diff options
author | José Rivero <jorive@microsoft.com> | 2019-04-16 18:58:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-16 18:58:31 -0700 |
commit | b388f6cd87d87f4a07fe966aaa1bc92f245165d9 (patch) | |
tree | 96d38fd71242691b4066ffe8977993b827bdb77a | |
parent | f360bbc0cf893bcd612516563145729743d3af2b (diff) | |
download | coreclr-b388f6cd87d87f4a07fe966aaa1bc92f245165d9.tar.gz coreclr-b388f6cd87d87f4a07fe966aaa1bc92f245165d9.tar.bz2 coreclr-b388f6cd87d87f4a07fe966aaa1bc92f245165d9.zip |
[EventPipe] Minor bug fixes, and remove redundant/unused code. (#23956)
- Update MicrosoftDiagnosticsTracingTraceEventPackageVersion
- Delete connection if the request is unknown/unhandled
- Adding missing error handling.
- Provider names must be defined.
- Some renaming, error handling, and build warnings.
- Removing test code, and merge EventPipe::Enable functions.
- Remove commented/non-used lines.
-rw-r--r-- | dependencies.props | 2 | ||||
-rw-r--r-- | src/debug/debug-pal/win/diagnosticsipc.cpp | 2 | ||||
-rw-r--r-- | src/vm/diagnosticserver.cpp | 15 | ||||
-rw-r--r-- | src/vm/diagnosticserver.h | 8 | ||||
-rw-r--r-- | src/vm/eventpipe.cpp | 135 | ||||
-rw-r--r-- | src/vm/eventpipe.h | 22 | ||||
-rw-r--r-- | src/vm/eventpipeconfiguration.cpp | 3 | ||||
-rw-r--r-- | src/vm/eventpipeinternal.cpp | 15 | ||||
-rw-r--r-- | src/vm/eventpipeinternal.h | 4 | ||||
-rw-r--r-- | src/vm/eventpipeprotocolhelper.cpp | 135 | ||||
-rw-r--r-- | src/vm/eventpipeprotocolhelper.h | 6 | ||||
-rw-r--r-- | src/vm/eventpipesession.cpp | 3 | ||||
-rw-r--r-- | src/vm/eventpipesession.h | 6 | ||||
-rw-r--r-- | src/vm/fastserializer.cpp | 15 | ||||
-rw-r--r-- | src/vm/fastserializer.h | 4 |
15 files changed, 153 insertions, 222 deletions
diff --git a/dependencies.props b/dependencies.props index 351914f9fe..f8f4a92817 100644 --- a/dependencies.props +++ b/dependencies.props @@ -35,7 +35,7 @@ <MicrosoftNETCoreRuntimeCoreCLRPackageVersion>3.0.0-preview5-27615-71</MicrosoftNETCoreRuntimeCoreCLRPackageVersion> <XunitPackageVersion>2.4.1-pre.build.4059</XunitPackageVersion> <XunitPerformanceApiPackageVersion>1.0.0-beta-build0015</XunitPerformanceApiPackageVersion> - <MicrosoftDiagnosticsTracingTraceEventPackageVersion>2.0.36</MicrosoftDiagnosticsTracingTraceEventPackageVersion> + <MicrosoftDiagnosticsTracingTraceEventPackageVersion>2.0.40</MicrosoftDiagnosticsTracingTraceEventPackageVersion> <IbcMergePackageVersion>4.6.0-alpha-00001</IbcMergePackageVersion> <CommandLineParserVersion>2.2.0</CommandLineParserVersion> diff --git a/src/debug/debug-pal/win/diagnosticsipc.cpp b/src/debug/debug-pal/win/diagnosticsipc.cpp index 5467581f4a..ef65f232a6 100644 --- a/src/debug/debug-pal/win/diagnosticsipc.cpp +++ b/src/debug/debug-pal/win/diagnosticsipc.cpp @@ -73,7 +73,7 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const return new IpcStream(hPipe); } -void IpcStream::DiagnosticsIpc::Unlink(ErrorCallback callback) +void IpcStream::DiagnosticsIpc::Unlink(ErrorCallback) { } diff --git a/src/vm/diagnosticserver.cpp b/src/vm/diagnosticserver.cpp index 81cdc25d5b..4ce0131397 100644 --- a/src/vm/diagnosticserver.cpp +++ b/src/vm/diagnosticserver.cpp @@ -57,20 +57,17 @@ static DWORD WINAPI DiagnosticsServerThread(LPVOID lpThreadParameter) switch (header.RequestType) { - case DiagnosticMessageType::EnableEventPipe: - EventPipeProtocolHelper::EnableFileTracingEventHandler(pStream); + case DiagnosticMessageType::StopEventPipeTracing: + EventPipeProtocolHelper::StopTracing(pStream); break; - case DiagnosticMessageType::DisableEventPipe: - EventPipeProtocolHelper::DisableFileTracingEventHandler(pStream); - break; - - case DiagnosticMessageType::StreamEventPipe: - EventPipeProtocolHelper::AttachTracingEventHandler(pStream); + case DiagnosticMessageType::CollectEventPipeTracing: + EventPipeProtocolHelper::CollectTracing(pStream); break; default: - LOG((LF_DIAGNOSTICS_PORT, LL_WARNING, "Received unknow request type (%d)\n", header.RequestType)); + STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_WARNING, "Received unknown request type (%d)\n", header.RequestType); + delete pStream; break; } } diff --git a/src/vm/diagnosticserver.h b/src/vm/diagnosticserver.h index 76ad3eff23..c3c2ca477d 100644 --- a/src/vm/diagnosticserver.h +++ b/src/vm/diagnosticserver.h @@ -18,11 +18,9 @@ enum class DiagnosticMessageType : uint32_t /////////////////////////////////////////////////////////////////////////// // EventPipe - EnableEventPipe = 1024, - DisableEventPipe, - StreamEventPipe, - AttachEventPipe, - DetachEventPipe, + StartEventPipeTracing = 1024, // To file + StopEventPipeTracing, + CollectEventPipeTracing, // To IPC /////////////////////////////////////////////////////////////////////////// // Profiler = 2048 diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp index b730bd8371..dc94c2b451 100644 --- a/src/vm/eventpipe.cpp +++ b/src/vm/eventpipe.cpp @@ -236,14 +236,18 @@ EventPipeSessionID EventPipe::Enable( uint32_t circularBufferSizeInMB, uint64_t profilerSamplingRateInNanoseconds, const EventPipeProviderConfiguration *pProviders, - uint32_t numProviders) + uint32_t numProviders, + EventPipeSessionType sessionType, + IpcStream *const pStream) { CONTRACTL { THROWS; GC_TRIGGERS; MODE_ANY; - PRECONDITION((numProviders == 0) || (numProviders > 0 && pProviders != nullptr)); + PRECONDITION(circularBufferSizeInMB > 0); + PRECONDITION(profilerSamplingRateInNanoseconds > 0); + PRECONDITION(numProviders > 0 && pProviders != nullptr); } CONTRACTL_END; @@ -251,83 +255,22 @@ EventPipeSessionID EventPipe::Enable( CrstHolder _crst(GetLock()); // Create a new session. - SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds); + SampleProfiler::SetSamplingRate(static_cast<unsigned long>(profilerSamplingRateInNanoseconds)); EventPipeSession *pSession = s_pConfig->CreateSession( - (strOutputPath != nullptr) ? EventPipeSessionType::File : EventPipeSessionType::Streaming, + sessionType, circularBufferSizeInMB, pProviders, numProviders); - // Initialize the last file switch time. - s_lastFlushSwitchTime = CLRGetTickCount64(); - - // Create the event pipe file. - // 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) - s_pFile = new EventPipeFile(new FileStreamWriter(SString(strOutputPath))); - return Enable(pSession); -} - -EventPipeSessionID EventPipe::Enable( - IpcStream *pStream, - uint32_t circularBufferSizeInMB, - uint64_t profilerSamplingRateInNanoseconds, - const EventPipeProviderConfiguration *pProviders, - uint32_t numProviders) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(pStream != nullptr); - PRECONDITION((numProviders == 0) || (numProviders > 0 && pProviders != nullptr)); - } - CONTRACTL_END; - - if (numProviders == 0 || pProviders == nullptr) - return (EventPipeSessionID) nullptr; - - // Take the lock before enabling tracing. - CrstHolder _crst(GetLock()); - - // Create a new session. - SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds); - EventPipeSession *pSession = s_pConfig->CreateSession( - EventPipeSessionType::IpcStream, - circularBufferSizeInMB, - pProviders, - numProviders); - - // Initialize the last file switch time. - s_lastFlushSwitchTime = CLRGetTickCount64(); - - // Reply back to client with the SessionId - uint32_t nBytesWritten = 0; - EventPipeSessionID sessionId = (EventPipeSessionID) pSession; - bool fSuccess = pStream->Write(&sessionId, sizeof(sessionId), nBytesWritten); - if (!fSuccess) - { - // TODO: Add error handling. - s_pConfig->DeleteSession(pSession); - - delete pStream; - return (EventPipeSessionID) nullptr; - } - - s_pFile = new EventPipeFile(new IpcStreamWriter(pStream)); - - // Enable the session. - const DWORD FlushTimerPeriodMS = 100; // TODO: Define a good number here for streaming. - return Enable(pSession, FlushTimer, FlushTimerPeriodMS, FlushTimerPeriodMS); + EventPipeSessionID sessionId = Enable(strOutputPath, pSession, sessionType, pStream); + return sessionId; } EventPipeSessionID EventPipe::Enable( + LPCWSTR strOutputPath, EventPipeSession *const pSession, - WAITORTIMERCALLBACK callback, - DWORD dueTime, - DWORD period) + EventPipeSessionType sessionType, + IpcStream *const pStream) { CONTRACTL { @@ -339,12 +282,16 @@ EventPipeSessionID EventPipe::Enable( } CONTRACTL_END; - // If tracing is not initialized or is already enabled, bail here. - if (!s_tracingInitialized || s_pConfig == nullptr || s_pConfig->Enabled()) + // If the state or arguments are invalid, bail here. + if (pSession == nullptr || !pSession->IsValid()) + return 0; + if (sessionType == EventPipeSessionType::File && strOutputPath == nullptr) + return 0; + if (sessionType == EventPipeSessionType::IpcStream && pStream == nullptr) return 0; - // If the state or arguments are invalid, bail here. - if (pSession == NULL || !pSession->IsValid()) + // If tracing is not initialized or is already enabled, bail here. + if (!s_tracingInitialized || s_pConfig == nullptr || s_pConfig->Enabled()) return 0; // Enable the EventPipe EventSource. @@ -352,6 +299,27 @@ EventPipeSessionID EventPipe::Enable( // Save the session. s_pSession = pSession; + EventPipeSessionID sessionId = reinterpret_cast<EventPipeSessionID>(s_pSession); + + // Create the event pipe file. + // A NULL output path means that we should not write the results to a file. + // This is used in the EventListener streaming case. + switch (sessionType) + { + case EventPipeSessionType::File: + if (strOutputPath != nullptr) + s_pFile = new EventPipeFile(new FileStreamWriter(SString(strOutputPath))); + break; + + case EventPipeSessionType::IpcStream: + s_pFile = new EventPipeFile(new IpcStreamWriter(sessionId, pStream)); + CreateFlushTimerCallback(); + break; + + default: + s_pFile = nullptr; + break; + } // Enable tracing. s_pConfig->Enable(s_pSession); @@ -359,11 +327,8 @@ EventPipeSessionID EventPipe::Enable( // Enable the sample profiler SampleProfiler::Enable(); - if (callback != nullptr) - CreateFlushTimerCallback(callback, dueTime, period); - // Return the session ID. - return (EventPipeSessionID)s_pSession; + return sessionId; } void EventPipe::Disable(EventPipeSessionID id) @@ -459,16 +424,13 @@ void EventPipe::Disable(EventPipeSessionID id) } } -void EventPipe::CreateFlushTimerCallback(WAITORTIMERCALLBACK callback, DWORD dueTime, DWORD period) +void EventPipe::CreateFlushTimerCallback() { CONTRACTL { THROWS; GC_TRIGGERS; MODE_ANY; - PRECONDITION(callback != nullptr); - PRECONDITION(dueTime > 0); - PRECONDITION(period > 0); PRECONDITION(GetLock()->OwnedByCurrentThread()); } CONTRACTL_END @@ -482,16 +444,19 @@ void EventPipe::CreateFlushTimerCallback(WAITORTIMERCALLBACK callback, DWORD due timerContextHolder->TimerId = 0; + // Initialize the last file switch time. + s_lastFlushSwitchTime = CLRGetTickCount64(); + bool success = false; _ASSERTE(s_fileSwitchTimerHandle == NULL); EX_TRY { if (ThreadpoolMgr::CreateTimerQueueTimer( &s_fileSwitchTimerHandle, - callback, + FlushTimer, timerContextHolder, - dueTime, - period, + 100, // DueTime (msec) + 100, // Period (msec) 0 /* flags */)) { _ASSERTE(s_fileSwitchTimerHandle != NULL); diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h index e60c493585..e3704d7763 100644 --- a/src/vm/eventpipe.h +++ b/src/vm/eventpipe.h @@ -21,6 +21,7 @@ class MethodDesc; struct EventPipeProviderConfiguration; class EventPipeSession; class IpcStream; +enum class EventPipeSessionType; // EVENT_FILTER_DESCRIPTOR (This type does not exist on non-Windows platforms.) // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/ns-evntprov-_event_filter_descriptor @@ -28,6 +29,7 @@ class IpcStream; // determines which events are reported and traced. The structure gives the // event provider greater control over the selection of events for reporting // and tracing. +// TODO: EventFilterDescriptor and EventData (defined below) are the same. struct EventFilterDescriptor { // A pointer to the filter data. @@ -231,7 +233,6 @@ public: }; typedef UINT64 EventPipeSessionID; -typedef void (*FlushTimerCallback)(); class EventPipe { @@ -255,14 +256,9 @@ public: uint32_t circularBufferSizeInMB, uint64_t profilerSamplingRateInNanoseconds, const EventPipeProviderConfiguration *pProviders, - uint32_t numProviders); - - static EventPipeSessionID Enable( - IpcStream *pStream, - uint32_t circularBufferSizeInMB, - uint64_t profilerSamplingRateInNanoseconds, - const EventPipeProviderConfiguration *pProviders, - uint32_t numProviders); + uint32_t numProviders, + EventPipeSessionType sessionType, + IpcStream *const pStream); // Disable tracing via the event pipe. static void Disable(EventPipeSessionID id); @@ -311,12 +307,12 @@ private: // Enable the specified EventPipe session. static EventPipeSessionID Enable( + LPCWSTR strOutputPath, EventPipeSession *const pSession, - WAITORTIMERCALLBACK callback = nullptr, - DWORD dueTime = 0, - DWORD period = 0); + EventPipeSessionType sessionType, + IpcStream *const pStream); - static void CreateFlushTimerCallback(WAITORTIMERCALLBACK Callback, DWORD DueTime, DWORD Period); + static void CreateFlushTimerCallback(); static void DeleteFlushTimerCallback(); diff --git a/src/vm/eventpipeconfiguration.cpp b/src/vm/eventpipeconfiguration.cpp index 48899df16c..9c7d396af1 100644 --- a/src/vm/eventpipeconfiguration.cpp +++ b/src/vm/eventpipeconfiguration.cpp @@ -319,7 +319,8 @@ EventPipeSession *EventPipeConfiguration::CreateSession( THROWS; GC_NOTRIGGER; MODE_ANY; - PRECONDITION((numProviders == 0) || (numProviders > 0 && pProviders != nullptr)); + PRECONDITION(circularBufferSizeInMB > 0); + PRECONDITION(numProviders > 0 && pProviders != nullptr); } CONTRACTL_END; diff --git a/src/vm/eventpipeinternal.cpp b/src/vm/eventpipeinternal.cpp index 17efeb39e6..9291d6b228 100644 --- a/src/vm/eventpipeinternal.cpp +++ b/src/vm/eventpipeinternal.cpp @@ -20,7 +20,7 @@ UINT64 QCALLTYPE EventPipeInternal::Enable( __in_z LPCWSTR outputFile, UINT32 circularBufferSizeInMB, - INT64 profilerSamplingRateInNanoseconds, + UINT64 profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, UINT32 numProviders) { @@ -28,6 +28,15 @@ UINT64 QCALLTYPE EventPipeInternal::Enable( UINT64 sessionID = 0; + // Invalid input! + if (circularBufferSizeInMB == 0 || + profilerSamplingRateInNanoseconds == 0 || + numProviders == 0 || + pProviders == nullptr) + { + return 0; + } + BEGIN_QCALL; { sessionID = EventPipe::Enable( @@ -35,7 +44,9 @@ UINT64 QCALLTYPE EventPipeInternal::Enable( circularBufferSizeInMB, profilerSamplingRateInNanoseconds, pProviders, - numProviders); + numProviders, + outputFile != NULL ? EventPipeSessionType::File : EventPipeSessionType::Streaming, + nullptr); } END_QCALL; diff --git a/src/vm/eventpipeinternal.h b/src/vm/eventpipeinternal.h index e4252c743a..97178c067d 100644 --- a/src/vm/eventpipeinternal.h +++ b/src/vm/eventpipeinternal.h @@ -47,12 +47,10 @@ public: static UINT64 QCALLTYPE Enable( __in_z LPCWSTR outputFile, UINT32 circularBufferSizeInMB, - INT64 profilerSamplingRateInNanoseconds, + UINT64 profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, UINT32 numProviders); - //! TODO: Add a ListActiveSessions to get the live SessionID in order to Disable? - //! //! Disables the specified session Id. //! diff --git a/src/vm/eventpipeprotocolhelper.cpp b/src/vm/eventpipeprotocolhelper.cpp index 24eb2b0ef5..8217dae22c 100644 --- a/src/vm/eventpipeprotocolhelper.cpp +++ b/src/vm/eventpipeprotocolhelper.cpp @@ -3,12 +3,29 @@ // See the LICENSE file in the project root for more information. #include "common.h" +#include "fastserializer.h" +#include "eventpipefile.h" #include "eventpipeprotocolhelper.h" +#include "eventpipesession.h" #include "diagnosticsipc.h" #include "diagnosticsprotocol.h" #ifdef FEATURE_PERFTRACING +static bool IsNullOrWhiteSpace(LPCWSTR value) +{ + if (value == nullptr) + return true; + + while (*value) + { + if (!iswspace(*value)) + return false; + ++value; + } + return true; +} + bool EventPipeProtocolHelper::TryParseProviderConfiguration(uint8_t *&bufferCursor, uint32_t &bufferLen, CQuickArray<EventPipeProviderConfiguration> &result) { // Picking an arbitrary upper bound, @@ -39,93 +56,18 @@ bool EventPipeProtocolHelper::TryParseProviderConfiguration(uint8_t *&bufferCurs LPCWSTR pProviderName = nullptr; if (!TryParseString(bufferCursor, bufferLen, pProviderName)) return false; - if (wcslen(pProviderName) == 0) - return false; // TODO: Should we ignore these input? + if (IsNullOrWhiteSpace(pProviderName)) + return false; LPCWSTR pFilterData = nullptr; // This parameter is optional. TryParseString(bufferCursor, bufferLen, pFilterData); pConfigs[i] = EventPipeProviderConfiguration(pProviderName, keywords, logLevel, pFilterData); } - return true; + return (countConfigs > 0); } -void EventPipeProtocolHelper::EnableFileTracingEventHandler(IpcStream *pStream) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(pStream != nullptr); - } - CONTRACTL_END; - - // TODO: Read within a loop. - uint8_t buffer[IpcStreamReadBufferSize]{}; - uint32_t nNumberOfBytesRead = 0; - bool fSuccess = pStream->Read(buffer, sizeof(buffer), nNumberOfBytesRead); - if (!fSuccess) - { - // TODO: Add error handling. - delete pStream; - return; - } - - // The protocol buffer is defined as: - // X, Y, Z means encode bytes for X followed by bytes for Y followed by bytes for Z - // message = uint circularBufferMB, string outputPath, array<provider_config> providers - // uint = 4 little endian bytes - // ulong = 8 little endian bytes - // wchar = 2 little endian bytes, UTF16 encoding - // array<T> = uint length, length # of Ts - // string = (array<char> where the last char must = 0) or (length = 0) - // provider_config = ulong keywords, uint logLevel, string provider_name, string filter_data - - LPCWSTR strOutputPath; - uint32_t circularBufferSizeInMB = EventPipeProtocolHelper::DefaultCircularBufferMB; - CQuickArray<EventPipeProviderConfiguration> providerConfigs; - - uint8_t *pBufferCursor = buffer; - uint32_t bufferLen = nNumberOfBytesRead; - if (!TryParse(pBufferCursor, bufferLen, circularBufferSizeInMB) || - !TryParseString(pBufferCursor, bufferLen, strOutputPath) || - !TryParseProviderConfiguration(pBufferCursor, bufferLen, providerConfigs)) - { - // TODO: error handling - delete pStream; - return; - } - - EventPipeSessionID sessionId = (EventPipeSessionID) nullptr; - if (providerConfigs.Size() > 0) - { - sessionId = EventPipe::Enable( - strOutputPath, // outputFile - circularBufferSizeInMB, // circularBufferSizeInMB - DefaultProfilerSamplingRateInNanoseconds, // ProfilerSamplingRateInNanoseconds - providerConfigs.Ptr(), // pConfigs - static_cast<uint32_t>(providerConfigs.Size())); // numConfigs - } - - uint32_t nBytesWritten = 0; - fSuccess = pStream->Write(&sessionId, sizeof(sessionId), nBytesWritten); - if (!fSuccess) - { - // TODO: Add error handling. - delete pStream; - return; - } - - fSuccess = pStream->Flush(); - if (!fSuccess) - { - // TODO: Add error handling. - } - delete pStream; -} - -void EventPipeProtocolHelper::DisableFileTracingEventHandler(IpcStream *pStream) +void EventPipeProtocolHelper::StopTracing(IpcStream *pStream) { CONTRACTL { @@ -164,7 +106,13 @@ void EventPipeProtocolHelper::DisableFileTracingEventHandler(IpcStream *pStream) delete pStream; } -void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream) +static bool TryParseCircularBufferSize(uint8_t *&bufferCursor, uint32_t &bufferLen, uint32_t &circularBufferSizeInMB) +{ + const bool CanParse = TryParse(bufferCursor, bufferLen, circularBufferSizeInMB); + return CanParse && (circularBufferSizeInMB > 0); +} + +void EventPipeProtocolHelper::CollectTracing(IpcStream *pStream) { CONTRACTL { @@ -175,6 +123,9 @@ void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream) } CONTRACTL_END; + if (pStream == nullptr) + return; + // TODO: Read within a loop. uint8_t buffer[IpcStreamReadBufferSize]{}; uint32_t nNumberOfBytesRead = 0; @@ -201,8 +152,8 @@ void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream) uint8_t *pBufferCursor = buffer; uint32_t bufferLen = nNumberOfBytesRead; - if (!TryParse(pBufferCursor, bufferLen, circularBufferSizeInMB) || - !TryParseString(pBufferCursor, bufferLen, strOutputPath) || + if (!TryParseCircularBufferSize(pBufferCursor, bufferLen, circularBufferSizeInMB) || + !TryParseString(pBufferCursor, bufferLen, strOutputPath) || // TODO: Remove. Currently ignored in this scenario. !TryParseProviderConfiguration(pBufferCursor, bufferLen, providerConfigs)) { // TODO: error handling @@ -210,15 +161,17 @@ void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream) return; } - if (providerConfigs.Size() > 0) - { - EventPipe::Enable( - pStream, // IPC stream - circularBufferSizeInMB, // circularBufferSizeInMB - DefaultProfilerSamplingRateInNanoseconds, // ProfilerSamplingRateInNanoseconds - providerConfigs.Ptr(), // pConfigs - static_cast<uint32_t>(providerConfigs.Size())); // numConfigs - } + auto sessionId = EventPipe::Enable( + nullptr, // strOutputPath (ignored in this scenario) + circularBufferSizeInMB, // circularBufferSizeInMB + DefaultProfilerSamplingRateInNanoseconds, // ProfilerSamplingRateInNanoseconds + providerConfigs.Ptr(), // pConfigs + static_cast<uint32_t>(providerConfigs.Size()), // numConfigs + EventPipeSessionType::IpcStream, // EventPipeSessionType + pStream); // IpcStream + + if (sessionId == 0) + delete pStream; } #endif // FEATURE_PERFTRACING diff --git a/src/vm/eventpipeprotocolhelper.h b/src/vm/eventpipeprotocolhelper.h index 4fc8580b64..8832521165 100644 --- a/src/vm/eventpipeprotocolhelper.h +++ b/src/vm/eventpipeprotocolhelper.h @@ -16,10 +16,8 @@ class EventPipeProtocolHelper { public: // IPC event handlers. - static void EnableFileTracingEventHandler(IpcStream *pStream); - static void DisableFileTracingEventHandler(IpcStream *pStream); - - static void AttachTracingEventHandler(IpcStream *pStream); + static void StopTracing(IpcStream *pStream); + static void CollectTracing(IpcStream *pStream); // `dotnet-trace collect` private: const static uint32_t DefaultCircularBufferMB = 1024; // 1 GB diff --git a/src/vm/eventpipesession.cpp b/src/vm/eventpipesession.cpp index 30c88fb807..ef7181861f 100644 --- a/src/vm/eventpipesession.cpp +++ b/src/vm/eventpipesession.cpp @@ -21,7 +21,8 @@ EventPipeSession::EventPipeSession( THROWS; GC_NOTRIGGER; MODE_ANY; - PRECONDITION((numProviders == 0) || (numProviders > 0 && pProviders != nullptr)); + PRECONDITION(circularBufferSizeInMB > 0); + PRECONDITION(numProviders > 0 && pProviders != nullptr); } CONTRACTL_END; diff --git a/src/vm/eventpipesession.h b/src/vm/eventpipesession.h index 128ba77012..829e18b8a7 100644 --- a/src/vm/eventpipesession.h +++ b/src/vm/eventpipesession.h @@ -12,9 +12,9 @@ class EventPipeSessionProvider; enum class EventPipeSessionType { - File, - Streaming, - IpcStream + File, // EventToFile + Streaming, // EventToEventListener + IpcStream // EventToIpc }; class EventPipeSession diff --git a/src/vm/fastserializer.cpp b/src/vm/fastserializer.cpp index 0b2c0f6f84..620b51077d 100644 --- a/src/vm/fastserializer.cpp +++ b/src/vm/fastserializer.cpp @@ -12,7 +12,7 @@ // As a result of work on V3 of Event Pipe (https://github.com/Microsoft/perfview/pull/532) it got removed // if you need it, please use git to restore it -IpcStreamWriter::IpcStreamWriter(IpcStream *pStream) : _pStream(pStream) +IpcStreamWriter::IpcStreamWriter(uint64_t id, IpcStream *pStream) : _pStream(pStream) { CONTRACTL { @@ -22,6 +22,17 @@ IpcStreamWriter::IpcStreamWriter(IpcStream *pStream) : _pStream(pStream) PRECONDITION(_pStream != nullptr); } CONTRACTL_END; + + if (_pStream == nullptr) + return; + + uint32_t nBytesWritten = 0; + bool fSuccess = _pStream->Write(&id, sizeof(id), nBytesWritten); + if (!fSuccess) + { + delete _pStream; + _pStream = nullptr; + } } IpcStreamWriter::~IpcStreamWriter() @@ -51,6 +62,8 @@ bool IpcStreamWriter::Write(const void *lpBuffer, const uint32_t nBytesToWrite, if (_pStream == nullptr) return false; + if (lpBuffer == nullptr || nBytesToWrite == 0) + return false; return _pStream->Write(lpBuffer, nBytesToWrite, nBytesWritten); } diff --git a/src/vm/fastserializer.h b/src/vm/fastserializer.h index d5db786549..2c669f0a25 100644 --- a/src/vm/fastserializer.h +++ b/src/vm/fastserializer.h @@ -53,12 +53,12 @@ public: class IpcStreamWriter final : public StreamWriter { public: - IpcStreamWriter(IpcStream *pStream); + IpcStreamWriter(uint64_t id, IpcStream *pStream); ~IpcStreamWriter(); bool Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten) const; private: - IpcStream *const _pStream; + IpcStream *_pStream; }; //! |