diff options
Diffstat (limited to 'src/vm/eventpipe.cpp')
-rw-r--r-- | src/vm/eventpipe.cpp | 92 |
1 files changed, 59 insertions, 33 deletions
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp index 8f2e8ff937..37de4c3b36 100644 --- a/src/vm/eventpipe.cpp +++ b/src/vm/eventpipe.cpp @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#include "common.h" #include "clrtypes.h" #include "safemath.h" -#include "common.h" #include "eventpipe.h" #include "eventpipebuffermanager.h" #include "eventpipeconfiguration.h" @@ -33,11 +33,8 @@ EventPipeJsonFile* EventPipe::s_pJsonFile = NULL; #ifdef FEATURE_PAL // This function is auto-generated from /src/scripts/genEventPipe.py extern "C" void InitProvidersAndEvents(); -#endif - -#ifdef FEATURE_PAL -// This function is auto-generated from /src/scripts/genEventPipe.py -extern "C" void InitProvidersAndEvents(); +#else +void InitProvidersAndEvents(); #endif EventPipeEventPayload::EventPipeEventPayload(BYTE *pData, unsigned int length) @@ -97,7 +94,7 @@ EventPipeEventPayload::~EventPipeEventPayload() CONTRACTL { NOTHROW; - GC_TRIGGERS; + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -114,7 +111,7 @@ void EventPipeEventPayload::Flatten() CONTRACTL { NOTHROW; - GC_TRIGGERS; + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -168,7 +165,7 @@ BYTE* EventPipeEventPayload::GetFlatData() CONTRACTL { NOTHROW; - GC_TRIGGERS; + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -193,11 +190,9 @@ void EventPipe::Initialize() s_pBufferManager = new EventPipeBufferManager(); -#ifdef FEATURE_PAL // This calls into auto-generated code to initialize the runtime providers // and events so that the EventPipe configuration lock isn't taken at runtime InitProvidersAndEvents(); -#endif } void EventPipe::EnableOnStartup() @@ -227,13 +222,19 @@ void EventPipe::Shutdown() { CONTRACTL { - THROWS; + NOTHROW; GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; - Disable(); + // We are shutting down, so if diasabling EventPipe throws, we need to move along anyway + EX_TRY + { + Disable(); + } + EX_CATCH { } + EX_END_CATCH(SwallowAllExceptions); if(s_pConfig != NULL) { @@ -262,7 +263,13 @@ void EventPipe::Enable( CONTRACTL_END; // If tracing is not initialized or is already enabled, bail here. - if(!s_tracingInitialized || s_pConfig->Enabled()) + if(!s_tracingInitialized || s_pConfig == NULL || s_pConfig->Enabled()) + { + return; + } + + // If the state or aurguments are invalid, bail + if(pProviders == NULL || numProviders <= 0) { return; } @@ -312,7 +319,7 @@ void EventPipe::Disable() // Take the lock before disabling tracing. CrstHolder _crst(GetLock()); - if(s_pConfig->Enabled()) + if(s_pConfig != NULL && s_pConfig->Enabled()) { // Disable the profiler. SampleProfiler::Disable(); @@ -468,7 +475,6 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload NOTHROW; GC_NOTRIGGER; MODE_ANY; - PRECONDITION(s_pBufferManager != NULL); } CONTRACTL_END; @@ -486,6 +492,12 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload return; } + if(s_pConfig == NULL) + { + // We can't procede without a configuration + return; + } + if(!s_pConfig->RundownEnabled() && s_pBufferManager != NULL) { if(!s_pBufferManager->WriteEvent(pThread, event, payload, pActivityId, pRelatedActivityId)) @@ -501,6 +513,10 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload { // Write synchronously to the file. // We're under lock and blocking the disabling thread. + // This copy occurs here (rather than at file write) because + // A) The FastSerializer API would need to change if we waited + // B) It is unclear there is a benefit to multiple file write calls + // as opposed a a buffer copy here EventPipeEventInstance instance( event, pThread->GetOSThreadId(), @@ -511,12 +527,22 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload if(s_pFile != NULL) { - s_pFile->WriteEvent(instance); + // EventPipeFile::WriteEvent needs to allocate a metadata event + // and can therefore throw. In this context we will silently + // fail rather than disrupt the caller + EX_TRY + { + s_pFile->WriteEvent(instance); + } + EX_CATCH { } + EX_END_CATCH(SwallowAllExceptions); } } } -#ifdef _DEBUG +// This section requires a call to GCX_PREEMP which violates the GC_NOTRIGGER contract +// It should only be enabled when debugging this specific component and contracts are off +#ifdef DEBUG_JSON_EVENT_FILE { GCX_PREEMP(); @@ -537,7 +563,7 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload { s_pSyncFile->WriteEvent(instance); } - + // Write to the EventPipeJsonFile if it exists. if(s_pJsonFile != NULL) { @@ -545,7 +571,7 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload } } } -#endif // _DEBUG +#endif // DEBUG_JSON_EVENT_FILE } void EventPipe::WriteSampleProfileEvent(Thread *pSamplingThread, EventPipeEvent *pEvent, Thread *pTargetThread, StackContents &stackContents, BYTE *pData, unsigned int length) @@ -641,7 +667,7 @@ StackWalkAction EventPipe::StackWalkCallback(CrawlFrame *pCf, StackContents *pDa { NOTHROW; GC_NOTRIGGER; - MODE_PREEMPTIVE; + MODE_ANY; PRECONDITION(pCf != NULL); PRECONDITION(pData != NULL); } @@ -686,15 +712,15 @@ CrstStatic* EventPipe::GetLock() void QCALLTYPE EventPipeInternal::Enable( __in_z LPCWSTR outputFile, - unsigned int circularBufferSizeInMB, - long profilerSamplingRateInNanoseconds, + UINT32 circularBufferSizeInMB, + INT64 profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, - int numProviders) + INT32 numProviders) { QCALL_CONTRACT; BEGIN_QCALL; - SampleProfiler::SetSamplingRate(profilerSamplingRateInNanoseconds); + SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds); EventPipe::Enable(outputFile, circularBufferSizeInMB, pProviders, numProviders); END_QCALL; } @@ -727,12 +753,12 @@ INT_PTR QCALLTYPE EventPipeInternal::CreateProvider( INT_PTR QCALLTYPE EventPipeInternal::DefineEvent( INT_PTR provHandle, - unsigned int eventID, + UINT32 eventID, __int64 keywords, - unsigned int eventVersion, - unsigned int level, + UINT32 eventVersion, + UINT32 level, void *pMetadata, - unsigned int metadataLength) + UINT32 metadataLength) { QCALL_CONTRACT; @@ -768,9 +794,9 @@ void QCALLTYPE EventPipeInternal::DeleteProvider( void QCALLTYPE EventPipeInternal::WriteEvent( INT_PTR eventHandle, - unsigned int eventID, + UINT32 eventID, void *pData, - unsigned int length, + UINT32 length, LPCGUID pActivityId, LPCGUID pRelatedActivityId) { @@ -786,9 +812,9 @@ void QCALLTYPE EventPipeInternal::WriteEvent( void QCALLTYPE EventPipeInternal::WriteEventData( INT_PTR eventHandle, - unsigned int eventID, + UINT32 eventID, EventData **pEventData, - unsigned int eventDataCount, + UINT32 eventDataCount, LPCGUID pActivityId, LPCGUID pRelatedActivityId) { |