summaryrefslogtreecommitdiff
path: root/src/vm/eventpipe.cpp
diff options
context:
space:
mode:
authorBrian Robbins <brianrob@microsoft.com>2018-07-02 15:08:32 -0700
committerGitHub <noreply@github.com>2018-07-02 15:08:32 -0700
commitb3b9d08529baaa7afdc38b3ede5dde1e456360b2 (patch)
treea203237496640223e56fb564e56d43d214fd6d54 /src/vm/eventpipe.cpp
parent834799c12ec0d459638d694b08bf536adee070b5 (diff)
downloadcoreclr-b3b9d08529baaa7afdc38b3ede5dde1e456360b2.tar.gz
coreclr-b3b9d08529baaa7afdc38b3ede5dde1e456360b2.tar.bz2
coreclr-b3b9d08529baaa7afdc38b3ede5dde1e456360b2.zip
Dispatch Runtime Events to EventListener (#18649)
Diffstat (limited to 'src/vm/eventpipe.cpp')
-rw-r--r--src/vm/eventpipe.cpp152
1 files changed, 121 insertions, 31 deletions
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp
index fb112db72b..00e740edee 100644
--- a/src/vm/eventpipe.cpp
+++ b/src/vm/eventpipe.cpp
@@ -221,6 +221,7 @@ void EventPipe::EnableOnStartup()
// Create a new session.
EventPipeSession *pSession = new EventPipeSession(
+ EventPipeSessionType::File,
1024 /* 1 GB circular buffer */,
NULL, /* pProviders */
0 /* numProviders */);
@@ -293,7 +294,11 @@ void EventPipe::Enable(
CONTRACTL_END;
// Create a new session.
- EventPipeSession *pSession = s_pConfig->CreateSession(circularBufferSizeInMB, pProviders, static_cast<unsigned int>(numProviders));
+ EventPipeSession *pSession = s_pConfig->CreateSession(
+ (strOutputPath != NULL) ? EventPipeSessionType::File : EventPipeSessionType::Streaming,
+ circularBufferSizeInMB,
+ pProviders,
+ static_cast<unsigned int>(numProviders));
// Enable the session.
Enable(strOutputPath, pSession);
@@ -329,8 +334,13 @@ void EventPipe::Enable(LPCWSTR strOutputPath, EventPipeSession *pSession)
CrstHolder _crst(GetLock());
// Create the event pipe file.
- SString eventPipeFileOutputPath(strOutputPath);
- s_pFile = new EventPipeFile(eventPipeFileOutputPath);
+ // A NULL output path means that we should not write the results to a file.
+ // This is used in the EventListener streaming case.
+ if (strOutputPath != NULL)
+ {
+ SString eventPipeFileOutputPath(strOutputPath);
+ s_pFile = new EventPipeFile(eventPipeFileOutputPath);
+ }
#ifdef _DEBUG
if((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EnableEventPipe) & 2) == 2)
@@ -395,39 +405,39 @@ void EventPipe::Disable()
FlushProcessWriteBuffers();
// Write to the file.
- LARGE_INTEGER disableTimeStamp;
- QueryPerformanceCounter(&disableTimeStamp);
- s_pBufferManager->WriteAllBuffersToFile(s_pFile, disableTimeStamp);
-
- if(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeRundown) > 0)
+ if(s_pFile != NULL)
{
- // Before closing the file, do rundown.
- const unsigned int numRundownProviders = 2;
- EventPipeProviderConfiguration rundownProviders[] =
- {
- { W("Microsoft-Windows-DotNETRuntime"), 0x80020138, static_cast<unsigned int>(EventPipeEventLevel::Verbose) }, // Public provider.
- { W("Microsoft-Windows-DotNETRuntimeRundown"), 0x80020138, static_cast<unsigned int>(EventPipeEventLevel::Verbose) } // Rundown provider.
- };
- // The circular buffer size doesn't matter because all events are written synchronously during rundown.
- s_pSession = s_pConfig->CreateSession(1 /* circularBufferSizeInMB */, rundownProviders, numRundownProviders);
- s_pConfig->EnableRundown(s_pSession);
-
- // Ask the runtime to emit rundown events.
- if(g_fEEStarted && !g_fEEShutDown)
+ LARGE_INTEGER disableTimeStamp;
+ QueryPerformanceCounter(&disableTimeStamp);
+ s_pBufferManager->WriteAllBuffersToFile(s_pFile, disableTimeStamp);
+
+ if(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeRundown) > 0)
{
- ETW::EnumerationLog::EndRundown();
- }
+ // Before closing the file, do rundown.
+ const unsigned int numRundownProviders = 2;
+ EventPipeProviderConfiguration rundownProviders[] =
+ {
+ { W("Microsoft-Windows-DotNETRuntime"), 0x80020138, static_cast<unsigned int>(EventPipeEventLevel::Verbose) }, // Public provider.
+ { W("Microsoft-Windows-DotNETRuntimeRundown"), 0x80020138, static_cast<unsigned int>(EventPipeEventLevel::Verbose) } // Rundown provider.
+ };
+ // The circular buffer size doesn't matter because all events are written synchronously during rundown.
+ s_pSession = s_pConfig->CreateSession(EventPipeSessionType::File, 1 /* circularBufferSizeInMB */, rundownProviders, numRundownProviders);
+ s_pConfig->EnableRundown(s_pSession);
+
+ // Ask the runtime to emit rundown events.
+ if(g_fEEStarted && !g_fEEShutDown)
+ {
+ ETW::EnumerationLog::EndRundown();
+ }
- // Disable the event pipe now that rundown is complete.
- s_pConfig->Disable(s_pSession);
+ // Disable the event pipe now that rundown is complete.
+ s_pConfig->Disable(s_pSession);
- // Delete the rundown session.
- s_pConfig->DeleteSession(s_pSession);
- s_pSession = NULL;
- }
+ // Delete the rundown session.
+ s_pConfig->DeleteSession(s_pSession);
+ s_pSession = NULL;
+ }
- if(s_pFile != NULL)
- {
delete(s_pFile);
s_pFile = NULL;
}
@@ -486,6 +496,25 @@ EventPipeProvider* EventPipe::CreateProvider(const SString &providerName, EventP
}
+EventPipeProvider* EventPipe::GetProvider(const SString &providerName)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ EventPipeProvider *pProvider = NULL;
+ if (s_pConfig != NULL)
+ {
+ pProvider = s_pConfig->GetProvider(providerName);
+ }
+
+ return pProvider;
+}
+
void EventPipe::DeleteProvider(EventPipeProvider *pProvider)
{
CONTRACTL
@@ -975,6 +1004,28 @@ void EventPipe::SaveCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv
#endif
}
+EventPipeEventInstance* EventPipe::GetNextEvent()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ }
+ CONTRACTL_END;
+
+ EventPipeEventInstance *pInstance = NULL;
+
+ // Only fetch the next event if a tracing session exists.
+ // The buffer manager is not disposed until the process is shutdown.
+ if (s_pSession != NULL)
+ {
+ pInstance = s_pBufferManager->GetNextEvent();
+ }
+
+ return pInstance;
+}
+
void QCALLTYPE EventPipeInternal::Enable(
__in_z LPCWSTR outputFile,
UINT32 circularBufferSizeInMB,
@@ -1041,6 +1092,22 @@ INT_PTR QCALLTYPE EventPipeInternal::DefineEvent(
return reinterpret_cast<INT_PTR>(pEvent);
}
+INT_PTR QCALLTYPE EventPipeInternal::GetProvider(
+ __in_z LPCWSTR providerName)
+{
+ QCALL_CONTRACT;
+
+ EventPipeProvider *pProvider = NULL;
+
+ BEGIN_QCALL;
+
+ pProvider = EventPipe::GetProvider(providerName);
+
+ END_QCALL;
+
+ return reinterpret_cast<INT_PTR>(pProvider);
+}
+
void QCALLTYPE EventPipeInternal::DeleteProvider(
INT_PTR provHandle)
{
@@ -1153,4 +1220,27 @@ void QCALLTYPE EventPipeInternal::WriteEventData(
END_QCALL;
}
+bool QCALLTYPE EventPipeInternal::GetNextEvent(
+ EventPipeEventInstanceData *pInstance)
+{
+ QCALL_CONTRACT;
+
+ EventPipeEventInstance *pNextInstance = NULL;
+ BEGIN_QCALL;
+
+ _ASSERTE(pInstance != NULL);
+
+ pNextInstance = EventPipe::GetNextEvent();
+ if (pNextInstance)
+ {
+ pInstance->ProviderID = pNextInstance->GetEvent()->GetProvider();
+ pInstance->EventID = pNextInstance->GetEvent()->GetEventID();
+ pInstance->Payload = pNextInstance->GetData();
+ pInstance->PayloadLength = pNextInstance->GetDataLength();
+ }
+
+ END_QCALL;
+ return pNextInstance != NULL;
+}
+
#endif // FEATURE_PERFTRACING