-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add More Process Information to EventPipe Traces #17080
Changes from all commits
780d492
ba7fb59
07a361c
d9c874c
ec44ada
58e6a98
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,10 +9,12 @@ | |
#include "eventpipebuffermanager.h" | ||
#include "eventpipeconfiguration.h" | ||
#include "eventpipeevent.h" | ||
#include "eventpipeeventsource.h" | ||
#include "eventpipefile.h" | ||
#include "eventpipeprovider.h" | ||
#include "eventpipesession.h" | ||
#include "eventpipejsonfile.h" | ||
#include "eventtracebase.h" | ||
#include "sampleprofiler.h" | ||
|
||
#ifdef FEATURE_PAL | ||
|
@@ -27,6 +29,8 @@ EventPipeConfiguration* EventPipe::s_pConfig = NULL; | |
EventPipeSession* EventPipe::s_pSession = NULL; | ||
EventPipeBufferManager* EventPipe::s_pBufferManager = NULL; | ||
EventPipeFile* EventPipe::s_pFile = NULL; | ||
EventPipeEventSource* EventPipe::s_pEventSource = NULL; | ||
LPCWSTR EventPipe::s_pCommandLine = NULL; | ||
#ifdef _DEBUG | ||
EventPipeFile* EventPipe::s_pSyncFile = NULL; | ||
EventPipeJsonFile* EventPipe::s_pJsonFile = NULL; | ||
|
@@ -57,7 +61,7 @@ EventPipeEventPayload::EventPipeEventPayload(BYTE *pData, unsigned int length) | |
m_size = length; | ||
} | ||
|
||
EventPipeEventPayload::EventPipeEventPayload(EventData **pEventData, unsigned int eventDataCount) | ||
EventPipeEventPayload::EventPipeEventPayload(EventData *pEventData, unsigned int eventDataCount) | ||
{ | ||
CONTRACTL | ||
{ | ||
|
@@ -75,7 +79,7 @@ EventPipeEventPayload::EventPipeEventPayload(EventData **pEventData, unsigned in | |
S_UINT32 tmp_size = S_UINT32(0); | ||
for (unsigned int i=0; i<m_eventDataCount; i++) | ||
{ | ||
tmp_size += S_UINT32((*m_pEventData)[i].Size); | ||
tmp_size += S_UINT32(m_pEventData[i].Size); | ||
} | ||
|
||
if (tmp_size.IsOverflow()) | ||
|
@@ -155,8 +159,8 @@ void EventPipeEventPayload::CopyData(BYTE *pDst) | |
unsigned int offset = 0; | ||
for(unsigned int i=0; i<m_eventDataCount; i++) | ||
{ | ||
memcpy(pDst + offset, (BYTE*)(*m_pEventData)[i].Ptr, (*m_pEventData)[i].Size); | ||
offset += (*m_pEventData)[i].Size; | ||
memcpy(pDst + offset, (BYTE*) m_pEventData[i].Ptr, m_pEventData[i].Size); | ||
offset += m_pEventData[i].Size; | ||
} | ||
} | ||
} | ||
|
@@ -192,6 +196,8 @@ void EventPipe::Initialize() | |
|
||
s_pBufferManager = new EventPipeBufferManager(); | ||
|
||
s_pEventSource = new EventPipeEventSource(); | ||
|
||
// 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(); | ||
|
@@ -258,9 +264,18 @@ void EventPipe::Shutdown() | |
s_pBufferManager = NULL; | ||
FlushProcessWriteBuffers(); | ||
|
||
// Free the configuration and buffer manager. | ||
// Free resources. | ||
delete(pConfig); | ||
delete(pBufferManager); | ||
delete(s_pEventSource); | ||
s_pEventSource = NULL; | ||
|
||
// On Windows, this is just a pointer to the return value from | ||
// GetCommandLineW(), so don't attempt to free it. | ||
#ifdef FEATURE_PAL | ||
delete[](s_pCommandLine); | ||
s_pCommandLine = NULL; | ||
#endif | ||
} | ||
|
||
void EventPipe::Enable( | ||
|
@@ -307,6 +322,9 @@ void EventPipe::Enable(LPCWSTR strOutputPath, EventPipeSession *pSession) | |
return; | ||
} | ||
|
||
// Enable the EventPipe EventSource. | ||
s_pEventSource->Enable(pSession); | ||
|
||
// Take the lock before enabling tracing. | ||
CrstHolder _crst(GetLock()); | ||
|
||
|
@@ -360,6 +378,12 @@ void EventPipe::Disable() | |
// Disable the profiler. | ||
SampleProfiler::Disable(); | ||
|
||
// Log the process information event. | ||
s_pEventSource->SendProcessInfo(s_pCommandLine); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why wait with this until I am not sure who is going to call ProcessName and when (after processing all events or maybe in the meantime?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am waiting until Disable in case the circular buffer wraps. This guarantees that this event doesn't get discarded. With respect to TraceEvent - TraceLog already does a pass over the data before you can use it, which means that users won't notice that this isn't part of the header. That's actually the point of TraceLog - to allow you to fill data structures with information that is only available after you need it. Thus, TraceLog does a single pass and then the user of the TraceLog does a second pass. |
||
|
||
// Log the runtime information event. | ||
ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Normal); | ||
|
||
// Disable tracing. | ||
s_pConfig->Disable(s_pSession); | ||
|
||
|
@@ -447,7 +471,7 @@ EventPipeProvider* EventPipe::CreateProvider(const SString &providerName, EventP | |
CONTRACTL | ||
{ | ||
THROWS; | ||
GC_TRIGGERS; | ||
GC_NOTRIGGER; | ||
MODE_ANY; | ||
} | ||
CONTRACTL_END; | ||
|
@@ -509,7 +533,7 @@ void EventPipe::WriteEvent(EventPipeEvent &event, BYTE *pData, unsigned int leng | |
EventPipe::WriteEventInternal(event, payload, pActivityId, pRelatedActivityId); | ||
} | ||
|
||
void EventPipe::WriteEvent(EventPipeEvent &event, EventData **pEventData, unsigned int eventDataCount, LPCGUID pActivityId, LPCGUID pRelatedActivityId) | ||
void EventPipe::WriteEvent(EventPipeEvent &event, EventData *pEventData, unsigned int eventDataCount, LPCGUID pActivityId, LPCGUID pRelatedActivityId) | ||
{ | ||
CONTRACTL | ||
{ | ||
|
@@ -901,6 +925,47 @@ void EventPipe::GetConfigurationFromEnvironment(SString &outputPath, EventPipeSe | |
} | ||
} | ||
|
||
void EventPipe::SaveCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv) | ||
{ | ||
CONTRACTL | ||
{ | ||
THROWS; | ||
GC_TRIGGERS; | ||
MODE_COOPERATIVE; | ||
PRECONDITION(pwzAssemblyPath != NULL); | ||
PRECONDITION(argc <= 0 || argv != NULL); | ||
} | ||
CONTRACTL_END; | ||
|
||
// Get the command line. | ||
LPCWSTR osCommandLine = GetCommandLineW(); | ||
|
||
#ifndef FEATURE_PAL | ||
// On Windows, osCommandLine contains the executable and all arguments. | ||
s_pCommandLine = osCommandLine; | ||
#else | ||
// On UNIX, the PAL doesn't have the command line arguments, so we must build the command line. | ||
// osCommandLine contains the full path to the executable. | ||
SString commandLine(osCommandLine); | ||
commandLine.Append((WCHAR)' '); | ||
commandLine.Append(pwzAssemblyPath); | ||
|
||
for(int i=0; i<argc; i++) | ||
{ | ||
commandLine.Append((WCHAR)' '); | ||
commandLine.Append(argv[i]); | ||
} | ||
|
||
// Allocate a new string for the command line. | ||
SIZE_T commandLineLen = commandLine.GetCount(); | ||
WCHAR *pCommandLine = new WCHAR[commandLineLen + 1]; | ||
wcsncpy(pCommandLine, commandLine.GetUnicode(), commandLineLen); | ||
pCommandLine[commandLineLen] = '\0'; | ||
|
||
s_pCommandLine = pCommandLine; | ||
#endif | ||
} | ||
|
||
void QCALLTYPE EventPipeInternal::Enable( | ||
__in_z LPCWSTR outputFile, | ||
UINT32 circularBufferSizeInMB, | ||
|
@@ -1065,7 +1130,7 @@ void QCALLTYPE EventPipeInternal::WriteEvent( | |
void QCALLTYPE EventPipeInternal::WriteEventData( | ||
INT_PTR eventHandle, | ||
UINT32 eventID, | ||
EventData **pEventData, | ||
EventData *pEventData, | ||
UINT32 eventDataCount, | ||
LPCGUID pActivityId, | ||
LPCGUID pRelatedActivityId) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for adding this comment! 👍