Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
40d9308
Proof of concept synchronous profiler EventPipe events
davmason May 24, 2020
7e2bbd8
Add provider callback and ability to query provider name
davmason May 25, 2020
a6ecda8
add guids to API
davmason May 26, 2020
af29c79
stop creating a buffer manager for synchronous sessions
davmason May 26, 2020
7198ac5
Take lock before adding provider to session
davmason May 26, 2020
7f3642c
fix linux build error
davmason May 26, 2020
1eb39d7
refactoring
davmason May 28, 2020
ce70d00
Get rid of enablecpusampling argument
davmason Jun 19, 2020
d644cba
move EventPipeProviderCreated profiler callback outside of lock
davmason Jun 19, 2020
8d1b5bc
refactor SuspendWriteEvent so it covers the synchronous callback case…
davmason Jun 20, 2020
7cb9a1a
after EventPipe starts shutting down return an error for EventPipeSta…
davmason Jun 21, 2020
c132d07
switch to spinlock since we can't use crst in gc_notrigger/coop
davmason Jun 22, 2020
ee9aee8
Add assert and remove unused variable
davmason Jun 23, 2020
540d8e3
Move storing null to the session array before EventPipeSession::Suspe…
davmason Jun 23, 2020
5eca5ef
remove spurious assert
davmason Jun 23, 2020
619f4b8
Fix SampleProfiler refcount issue, double profiler callback, remove u…
davmason Jun 24, 2020
7905bcf
remove the concept of m_writeEventSuspending from the buffer manager …
davmason Jun 24, 2020
96d8cc4
Add test
davmason May 26, 2020
87ceca4
add description of filter data format
davmason Jun 25, 2020
0cc9a28
fix x86 test build issues
davmason Jun 25, 2020
008dabd
exlcude test from mono
davmason Jun 26, 2020
68e3479
move waiting on threads to finish writing outside of the lock
davmason Jun 26, 2020
2c3429e
allow call to GetProviderInfo to get the length of the name
davmason Jun 27, 2020
5ab6fd0
Fix formatting
davmason Jun 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactoring
  • Loading branch information
davmason committed Jun 25, 2020
commit 1eb39d7981b85e1ea0597bb79670e6cc92a06524
9 changes: 4 additions & 5 deletions src/coreclr/src/inc/corprof.idl
Original file line number Diff line number Diff line change
Expand Up @@ -4118,12 +4118,11 @@ interface ICorProfilerInfo11 : ICorProfilerInfo10
interface ICorProfilerInfo12 : ICorProfilerInfo11
{
HRESULT EventPipeStartSession(
[in] const WCHAR* szProviderName,
[in] UINT32 cProviderConfigs,
[in, size_is(cProviderConfigs)]
COR_PRF_EVENTPIPE_PROVIDER_CONFIG pProviderConfigs[],
[in] BOOL requestRundown,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requestMetadataDump?

[in] BOOL requestSamples,
[in] BOOL requestCPUSamples,
[out] EVENTPIPE_SESSION* pSession);

HRESULT EventPipeAddProviderToSession(
Expand All @@ -4134,19 +4133,19 @@ interface ICorProfilerInfo12 : ICorProfilerInfo11
[in] EVENTPIPE_SESSION session);

HRESULT EventPipeCreateProvider(
[in, string] const WCHAR *szName,
[in, string] const WCHAR *providerName,
[out] EVENTPIPE_PROVIDER *pProvider);

HRESULT EventPipeGetProviderInfo(
[in] EVENTPIPE_PROVIDER provider,
[in] ULONG cchName,
[out] ULONG *pcchName,
[out, annotation("_Out_writes_to_(cchName, *pcchName)")]
WCHAR szName[]);
WCHAR providerName[]);

HRESULT EventPipeDefineEvent(
[in] EVENTPIPE_PROVIDER provider,
[in, string] const WCHAR *szName,
[in, string] const WCHAR *eventName,
[in] UINT32 eventID,
[in] UINT64 keywords,
[in] UINT32 eventVersion,
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/src/vm/eventpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ EventPipeSessionID EventPipe::Enable(
circularBufferSizeInMB,
pProviders,
numProviders,
false, //TODO: what is the difference between rundownRequested above and this rundownEnabled?
callback);

const bool fSuccess = EnableInternal(pSession, pEventPipeProviderCallbackDataQueue, enableSampleProfiler);
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/src/vm/eventpipesession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ EventPipeSession::EventPipeSession(
uint32_t circularBufferSizeInMB,
const EventPipeProviderConfiguration *pProviders,
uint32_t numProviders,
bool rundownEnabled,
EventPipeSessionSynchronousCallback callback) : m_index(index),
m_pProviderList(new EventPipeSessionProviderList(pProviders, numProviders)),
m_pBufferManager(nullptr),
m_rundownEnabled(rundownEnabled),
m_rundownEnabled(false),
m_SessionType(sessionType),
m_format(format),
m_rundownRequested(rundownSwitch),
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/src/vm/eventpipesession.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ class EventPipeSession
uint32_t circularBufferSizeInMB,
const EventPipeProviderConfiguration *pProviders,
uint32_t numProviders,
bool rundownEnabled = false,
EventPipeSessionSynchronousCallback callback = nullptr);

~EventPipeSession();
Expand Down Expand Up @@ -196,6 +195,10 @@ class EventPipeSession

bool WriteAllBuffersToFile(bool *pEventsWritten);

// If a session is non-synchronous (i.e. a file, pipe, etc) WriteEvent will
// put the event in a buffer and return as quick as possible. If a session is
// synchronous (callback to the profiler) then this method will block until the
// profiler is done parsing and reacting to it.
bool WriteEvent(
Thread *pThread,
EventPipeEvent &event,
Expand Down
90 changes: 49 additions & 41 deletions src/coreclr/src/vm/proftoeeinterfaceimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7031,11 +7031,10 @@ HRESULT ProfToEEInterfaceImpl::SetEnvironmentVariable(const WCHAR *szName, const
}

HRESULT ProfToEEInterfaceImpl::EventPipeStartSession(
const WCHAR* szProviderName,
UINT32 cProviderConfigs,
COR_PRF_EVENTPIPE_PROVIDER_CONFIG pProviderConfigs[],
BOOL requestRundown,
BOOL requestSamples,
BOOL requestCPUSamples,
EVENTPIPE_SESSION* pSession)
{
CONTRACTL
Expand All @@ -7061,8 +7060,7 @@ HRESULT ProfToEEInterfaceImpl::EventPipeStartSession(
&& sizeof(EventPipeProviderConfiguration) == sizeof(COR_PRF_EVENTPIPE_PROVIDER_CONFIG),
"Layouts of EventPipeProviderConfiguration type and COR_PRF_EVENTPIPE_PROVIDER_CONFIG type do not match!");

if (szProviderName == NULL
|| cProviderConfigs == 0
if (cProviderConfigs == 0
|| pProviderConfigs == NULL
|| pSession == NULL)
{
Expand All @@ -7072,35 +7070,6 @@ HRESULT ProfToEEInterfaceImpl::EventPipeStartSession(
HRESULT hr = S_OK;
EX_TRY
{
auto eventPipeFunc = [](EventPipeProvider *provider,
DWORD eventId,
DWORD eventVersion,
ULONG cbMetadataBlob,
LPCBYTE metadataBlob,
ULONG cbEventData,
LPCBYTE eventData,
LPCGUID pActivityId,
LPCGUID pRelatedActivityId,
Thread *pEventThread,
ULONG numStackFrames,
UINT_PTR stackFrames[])
{
BEGIN_PIN_PROFILER(CORProfilerIsMonitoringEventPipe());
g_profControlBlock.pProfInterface->EventPipeEventDelivered(provider,
eventId,
eventVersion,
cbMetadataBlob,
metadataBlob,
cbEventData,
eventData,
pActivityId,
pRelatedActivityId,
pEventThread,
numStackFrames,
stackFrames);
END_PIN_PROFILER();
};

EventPipeProviderConfiguration *pProviders = reinterpret_cast<EventPipeProviderConfiguration *>(pProviderConfigs);
UINT64 sessionID = EventPipe::Enable(NULL,
0, // We don't use a circular buffer since it's synchronous
Expand All @@ -7110,8 +7079,8 @@ HRESULT ProfToEEInterfaceImpl::EventPipeStartSession(
EventPipeSerializationFormat::NetTraceV4,
requestRundown,
NULL,
requestSamples,
eventPipeFunc);
requestCPUSamples,
&ProfToEEInterfaceImpl::EventPipeCallbackHelper);
EventPipe::StartStreaming(sessionID);

*pSession = sessionID;
Expand Down Expand Up @@ -7207,7 +7176,9 @@ HRESULT ProfToEEInterfaceImpl::EventPipeStopSession(
#endif // FEATURE_PERFTRACING
}

HRESULT ProfToEEInterfaceImpl::EventPipeCreateProvider(const WCHAR *szName, EVENTPIPE_PROVIDER *pProvider)
HRESULT ProfToEEInterfaceImpl::EventPipeCreateProvider(
const WCHAR *providerName,
EVENTPIPE_PROVIDER *pProvider)
{
CONTRACTL
{
Expand All @@ -7224,15 +7195,15 @@ HRESULT ProfToEEInterfaceImpl::EventPipeCreateProvider(const WCHAR *szName, EVEN
"**PROF: EventPipeCreateProvider.\n"));

#ifdef FEATURE_PERFTRACING
if (szName == NULL || pProvider == NULL)
if (providerName == NULL || pProvider == NULL)
{
return E_INVALIDARG;
}

HRESULT hr = S_OK;
EX_TRY
{
EventPipeProvider *pRealProvider = EventPipe::CreateProvider(szName, NULL, NULL);
EventPipeProvider *pRealProvider = EventPipe::CreateProvider(providerName, NULL, NULL);
if (pRealProvider == NULL)
{
hr = E_FAIL;
Expand Down Expand Up @@ -7321,7 +7292,7 @@ HRESULT ProfToEEInterfaceImpl::EventPipeGetProviderInfo(

HRESULT ProfToEEInterfaceImpl::EventPipeDefineEvent(
EVENTPIPE_PROVIDER provider,
const WCHAR *szName,
const WCHAR *eventName,
UINT32 eventID,
UINT64 keywords,
UINT32 eventVersion,
Expand All @@ -7348,7 +7319,7 @@ HRESULT ProfToEEInterfaceImpl::EventPipeDefineEvent(

#ifdef FEATURE_PERFTRACING
EventPipeProvider *pProvider = reinterpret_cast<EventPipeProvider *>(provider);
if (pProvider == NULL || szName == NULL || pEvent == NULL)
if (pProvider == NULL || eventName == NULL || pEvent == NULL)
{
return E_INVALIDARG;
}
Expand Down Expand Up @@ -7381,7 +7352,7 @@ HRESULT ProfToEEInterfaceImpl::EventPipeDefineEvent(
size_t metadataLength;
NewArrayHolder<BYTE> pMetadata = EventPipeMetadataGenerator::GenerateEventMetadata(
eventID,
szName,
eventName,
keywords,
eventVersion,
(EventPipeEventLevel)level,
Expand Down Expand Up @@ -7452,6 +7423,43 @@ HRESULT ProfToEEInterfaceImpl::EventPipeWriteEvent(
#endif // FEATURE_PERFTRACING
}

void ProfToEEInterfaceImpl::EventPipeCallbackHelper(EventPipeProvider *provider,
DWORD eventId,
DWORD eventVersion,
ULONG cbMetadataBlob,
LPCBYTE metadataBlob,
ULONG cbEventData,
LPCBYTE eventData,
LPCGUID pActivityId,
LPCGUID pRelatedActivityId,
Thread *pEventThread,
ULONG numStackFrames,
UINT_PTR stackFrames[])
{
// If we got here we know a profiler has started an EventPipe session
BEGIN_PIN_PROFILER(true);
// But, a profiler could always register for a session and then detach without
// closing the session. So check if we have an interface before proceeding.
if (g_profControlBlock.pProfInterface != nullptr)
{
g_profControlBlock.pProfInterface->EventPipeEventDelivered(provider,
eventId,
eventVersion,
cbMetadataBlob,
metadataBlob,
cbEventData,
eventData,
pActivityId,
pRelatedActivityId,
pEventThread,
numStackFrames,
stackFrames);
}
END_PIN_PROFILER();
};



/*
* GetStringLayout
*
Expand Down
22 changes: 17 additions & 5 deletions src/coreclr/src/vm/proftoeeinterfaceimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,11 +645,10 @@ class ProfToEEInterfaceImpl : public ICorProfilerInfo12
// begin ICorProfilerInfo12

COM_METHOD EventPipeStartSession(
const WCHAR* szProviderName,
UINT32 cProviderConfigs,
COR_PRF_EVENTPIPE_PROVIDER_CONFIG pProviderConfigs[],
BOOL requestRundown,
BOOL requestSamples,
BOOL requestCPUSamples,
EVENTPIPE_SESSION* pSession);

COM_METHOD EventPipeAddProviderToSession(
Expand All @@ -660,18 +659,18 @@ class ProfToEEInterfaceImpl : public ICorProfilerInfo12
EVENTPIPE_SESSION session);

COM_METHOD EventPipeCreateProvider(
const WCHAR *szName,
const WCHAR *providerName,
EVENTPIPE_PROVIDER *pProvider);

COM_METHOD EventPipeGetProviderInfo(
EVENTPIPE_PROVIDER provider,
ULONG cchName,
ULONG *pcchName,
WCHAR szName[]);
WCHAR providerName[]);

COM_METHOD EventPipeDefineEvent(
EVENTPIPE_PROVIDER provider,
const WCHAR *szName,
const WCHAR *eventName,
UINT32 eventID,
UINT64 keywords,
UINT32 eventVersion,
Expand All @@ -695,6 +694,19 @@ class ProfToEEInterfaceImpl : public ICorProfilerInfo12

// Internal Helper Functions

static void EventPipeCallbackHelper(EventPipeProvider *provider,
DWORD eventId,
DWORD eventVersion,
ULONG cbMetadataBlob,
LPCBYTE metadataBlob,
ULONG cbEventData,
LPCBYTE eventData,
LPCGUID pActivityId,
LPCGUID pRelatedActivityId,
Thread *pEventThread,
ULONG numStackFrames,
UINT_PTR stackFrames[]);

HRESULT GetCodeInfoHelper(FunctionID functionId,
ReJITID reJitId,
ULONG32 cCodeInfos,
Expand Down