diff options
-rw-r--r-- | src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs | 17 | ||||
-rw-r--r-- | src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs | 14 | ||||
-rw-r--r-- | src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventDispatcher.cs | 2 | ||||
-rw-r--r-- | src/vm/eventpipe.cpp | 148 | ||||
-rw-r--r-- | src/vm/eventpipe.h | 24 | ||||
-rw-r--r-- | src/vm/eventpipeinternal.cpp | 6 | ||||
-rw-r--r-- | src/vm/eventpipeinternal.h | 3 | ||||
-rw-r--r-- | src/vm/eventpipeprotocolhelper.cpp | 19 | ||||
-rw-r--r-- | src/vm/eventpipeprotocolhelper.h | 1 |
9 files changed, 25 insertions, 209 deletions
diff --git a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs index 9f05540610..763e78cf4f 100644 --- a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs +++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs @@ -87,7 +87,6 @@ namespace System.Diagnostics.Tracing private uint m_circularBufferSizeInMB; private List<EventPipeProviderConfiguration> m_providers; private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1); - private ulong m_multiFileTraceLengthInSeconds = 0; internal EventPipeConfiguration( string outputFile, @@ -116,11 +115,6 @@ namespace System.Diagnostics.Tracing get { return m_circularBufferSizeInMB; } } - internal ulong MultiFileTraceLengthInSeconds - { - get { return m_multiFileTraceLengthInSeconds; } - } - internal EventPipeProviderConfiguration[] Providers { get { return m_providers.ToArray(); } @@ -168,11 +162,6 @@ namespace System.Diagnostics.Tracing m_minTimeBetweenSamples = minTimeBetweenSamples; } - - internal void SetMultiFileTraceLength(ulong traceLengthInSeconds) - { - m_multiFileTraceLengthInSeconds = traceLengthInSeconds; - } } internal static class EventPipe @@ -198,8 +187,7 @@ namespace System.Diagnostics.Tracing configuration.CircularBufferSizeInMB, (ulong)configuration.ProfilerSamplingRateInNanoseconds, providers, - (uint)providers.Length, - configuration.MultiFileTraceLengthInSeconds); + (uint)providers.Length); } internal static void Disable() @@ -219,8 +207,7 @@ namespace System.Diagnostics.Tracing uint circularBufferSizeInMB, ulong profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration[] providers, - uint numProviders, - ulong multiFileTraceLengthInSeconds); + uint numProviders); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] internal static extern void Disable(UInt64 sessionID); diff --git a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs index cac4ac1f5d..2711d5290a 100644 --- a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs +++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs @@ -46,7 +46,6 @@ namespace System.Diagnostics.Tracing private const string ConfigKey_CircularMB = "CircularMB"; private const string ConfigKey_OutputPath = "OutputPath"; private const string ConfigKey_ProcessID = "ProcessID"; - private const string ConfigKey_MultiFileSec = "MultiFileSec"; // The default set of providers/keywords/levels. Used if an alternative configuration is not specified. private static EventPipeProviderConfiguration[] DefaultProviderConfiguration => new EventPipeProviderConfiguration[] @@ -170,7 +169,6 @@ namespace System.Diagnostics.Tracing string strProviderConfig = null; string strCircularMB = null; string strProcessID = null; - string strMultiFileSec = null; // Split the configuration entries by line. string[] configEntries = strConfigContents.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); @@ -200,10 +198,6 @@ namespace System.Diagnostics.Tracing { strProcessID = entryComponents[1]; } - else if (key.Equals(ConfigKey_MultiFileSec)) - { - strMultiFileSec = entryComponents[1]; - } } } @@ -224,13 +218,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(outputPath)); } - // Check to see if MultiFileSec is specified. - ulong multiFileSec = 0; - if (!string.IsNullOrEmpty(strMultiFileSec)) - { - multiFileSec = Convert.ToUInt64(strMultiFileSec); - } - // Build the full path to the trace file. string traceFileName = BuildTraceFileName(); string outputFile = Path.Combine(outputPath, traceFileName); @@ -244,7 +231,6 @@ namespace System.Diagnostics.Tracing // Initialize a new configuration object. EventPipeConfiguration config = new EventPipeConfiguration(outputFile, circularMB); - config.SetMultiFileTraceLength(multiFileSec); // Set the provider configuration if specified. if (!string.IsNullOrEmpty(strProviderConfig)) diff --git a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventDispatcher.cs b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventDispatcher.cs index 9f459891a7..1e152bcfcd 100644 --- a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventDispatcher.cs +++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventDispatcher.cs @@ -110,7 +110,7 @@ namespace System.Diagnostics.Tracing new EventPipeProviderConfiguration(NativeRuntimeEventSource.EventSourceName, (ulong) aggregatedKeywords, (uint) highestLevel, null) }; - m_sessionID = EventPipeInternal.Enable(null, 1024, 1, providerConfiguration, 1, 0); + m_sessionID = EventPipeInternal.Enable(null, 1024, 1, providerConfiguration, 1); Debug.Assert(m_sessionID != 0); // Get the session information that is required to properly dispatch events. diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp index 92b4793f2e..b730bd8371 100644 --- a/src/vm/eventpipe.cpp +++ b/src/vm/eventpipe.cpp @@ -31,14 +31,11 @@ bool EventPipe::s_tracingInitialized = false; EventPipeConfiguration *EventPipe::s_pConfig = NULL; EventPipeSession *EventPipe::s_pSession = NULL; EventPipeBufferManager *EventPipe::s_pBufferManager = NULL; -LPCWSTR EventPipe::s_pOutputPath = NULL; EventPipeFile *EventPipe::s_pFile = NULL; EventPipeEventSource *EventPipe::s_pEventSource = NULL; LPCWSTR EventPipe::s_pCommandLine = NULL; -unsigned long EventPipe::s_nextFileIndex; HANDLE EventPipe::s_fileSwitchTimerHandle = NULL; ULONGLONG EventPipe::s_lastFlushSwitchTime = 0; -uint64_t EventPipe::s_multiFileTraceLengthInSeconds = 0; #ifdef FEATURE_PAL // This function is auto-generated from /src/scripts/genEventPipe.py @@ -225,8 +222,6 @@ void EventPipe::Shutdown() delete pBufferManager; delete s_pEventSource; s_pEventSource = NULL; - delete[] s_pOutputPath; - s_pOutputPath = NULL; // On Windows, this is just a pointer to the return value from // GetCommandLineW(), so don't attempt to free it. @@ -241,8 +236,7 @@ EventPipeSessionID EventPipe::Enable( uint32_t circularBufferSizeInMB, uint64_t profilerSamplingRateInNanoseconds, const EventPipeProviderConfiguration *pProviders, - uint32_t numProviders, - uint64_t multiFileTraceLengthInSeconds) + uint32_t numProviders) { CONTRACTL { @@ -256,8 +250,6 @@ EventPipeSessionID EventPipe::Enable( // Take the lock before enabling tracing. CrstHolder _crst(GetLock()); - s_multiFileTraceLengthInSeconds = multiFileTraceLengthInSeconds; - // Create a new session. SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds); EventPipeSession *pSession = s_pConfig->CreateSession( @@ -266,9 +258,6 @@ EventPipeSessionID EventPipe::Enable( pProviders, numProviders); - // Initialize the next file index. - s_nextFileIndex = 1; - // Initialize the last file switch time. s_lastFlushSwitchTime = CLRGetTickCount64(); @@ -276,24 +265,8 @@ EventPipeSessionID EventPipe::Enable( // 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) - { - - // Save the output file path. - SString outputPath(strOutputPath); - SIZE_T outputPathLen = outputPath.GetCount(); - WCHAR *pOutputPath = new WCHAR[outputPathLen + 1]; - wcsncpy(pOutputPath, outputPath.GetUnicode(), outputPathLen); - pOutputPath[outputPathLen] = '\0'; - s_pOutputPath = pOutputPath; - - SString nextTraceFilePath; - GetNextFilePath(nextTraceFilePath); - - s_pFile = new EventPipeFile(new FileStreamWriter(nextTraceFilePath)); - } - - const DWORD FileSwitchTimerPeriodMS = 1000; - return Enable(pSession, SwitchToNextFileTimerCallback, FileSwitchTimerPeriodMS, FileSwitchTimerPeriodMS); + s_pFile = new EventPipeFile(new FileStreamWriter(SString(strOutputPath))); + return Enable(pSession); } EventPipeSessionID EventPipe::Enable( @@ -327,6 +300,9 @@ EventPipeSessionID EventPipe::Enable( 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; @@ -359,9 +335,6 @@ EventPipeSessionID EventPipe::Enable( GC_TRIGGERS; MODE_ANY; PRECONDITION(pSession != nullptr); - PRECONDITION(callback != nullptr); - PRECONDITION(dueTime > 0); - PRECONDITION(period > 0); PRECONDITION(GetLock()->OwnedByCurrentThread()); } CONTRACTL_END; @@ -386,7 +359,8 @@ EventPipeSessionID EventPipe::Enable( // Enable the sample profiler SampleProfiler::Enable(); - CreateFlushTimerCallback(callback, dueTime, period); + if (callback != nullptr) + CreateFlushTimerCallback(callback, dueTime, period); // Return the session ID. return (EventPipeSessionID)s_pSession; @@ -427,8 +401,6 @@ void EventPipe::Disable(EventPipeSessionID id) // Disable tracing. s_pConfig->Disable(s_pSession); - s_multiFileTraceLengthInSeconds = 0; - // Delete the session. s_pConfig->DeleteSession(s_pSession); s_pSession = NULL; @@ -555,36 +527,6 @@ void EventPipe::DeleteFlushTimerCallback() s_fileSwitchTimerHandle = NULL; } -void WINAPI EventPipe::SwitchToNextFileTimerCallback(PVOID parameter, BOOLEAN timerFired) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(timerFired); - } - CONTRACTL_END; - - // Take the lock control lock to make sure that tracing isn't disabled during this operation. - CrstHolder _crst(GetLock()); - - if (s_pSession == nullptr || s_pFile == nullptr) - return; - - // Make sure that we should actually switch files. - if (!Enabled() || s_pSession->GetSessionType() != EventPipeSessionType::File || s_multiFileTraceLengthInSeconds == 0) - return; - - GCX_PREEMP(); - - if (CLRGetTickCount64() > (s_lastFlushSwitchTime + (s_multiFileTraceLengthInSeconds * 1000))) - { - SwitchToNextFile(); - s_lastFlushSwitchTime = CLRGetTickCount64(); - } -} - void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired) { CONTRACTL @@ -621,80 +563,6 @@ void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired) } } -void EventPipe::SwitchToNextFile() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - PRECONDITION(s_pFile != nullptr); - PRECONDITION(GetLock()->OwnedByCurrentThread()); - } - CONTRACTL_END - - // Get the current time stamp. - // WriteAllBuffersToFile will use this to ensure that no events after the current timestamp are written into the file. - LARGE_INTEGER stopTimeStamp; - QueryPerformanceCounter(&stopTimeStamp); - s_pBufferManager->WriteAllBuffersToFile(s_pFile, stopTimeStamp); - - // Open the new file. - SString nextTraceFilePath; - GetNextFilePath(nextTraceFilePath); - - StreamWriter *pStreamWriter = new (nothrow) FileStreamWriter(nextTraceFilePath); - if (pStreamWriter == nullptr) - { - // TODO: Add error handling. - return; - } - - EventPipeFile *pFile = new (nothrow) EventPipeFile(pStreamWriter); - if (pFile == NULL) - { - // TODO: Add error handling. - return; - } - - // Close the previous file. - delete s_pFile; - - // Swap in the new file. - s_pFile = pFile; -} - -void EventPipe::GetNextFilePath(SString &nextTraceFilePath) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(GetLock()->OwnedByCurrentThread()); - } - CONTRACTL_END; - - // Set the full path to the requested trace file as the next file path. - nextTraceFilePath.Set(s_pOutputPath); - - // If multiple files have been requested, then add a sequence number to the trace file name. - if (s_multiFileTraceLengthInSeconds > 0) - { - // Remove the ".netperf" file extension if it exists. - SString::Iterator netPerfExtension = nextTraceFilePath.End(); - if (nextTraceFilePath.FindBack(netPerfExtension, W(".netperf"))) - { - nextTraceFilePath.Truncate(netPerfExtension); - } - - // Add the sequence number and the ".netperf" file extension. - WCHAR strNextIndex[21]; - swprintf_s(strNextIndex, 21, W(".%u.netperf"), s_nextFileIndex++); - nextTraceFilePath.Append(strNextIndex); - } -} - EventPipeSession *EventPipe::GetSession(EventPipeSessionID id) { LIMITED_METHOD_CONTRACT; diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h index 5129baf9a9..e60c493585 100644 --- a/src/vm/eventpipe.h +++ b/src/vm/eventpipe.h @@ -255,8 +255,7 @@ public: uint32_t circularBufferSizeInMB, uint64_t profilerSamplingRateInNanoseconds, const EventPipeProviderConfiguration *pProviders, - uint32_t numProviders, - uint64_t multiFileTraceLengthInSeconds); + uint32_t numProviders); static EventPipeSessionID Enable( IpcStream *pStream, @@ -313,28 +312,16 @@ private: // Enable the specified EventPipe session. static EventPipeSessionID Enable( EventPipeSession *const pSession, - WAITORTIMERCALLBACK callback, - DWORD dueTime, - DWORD period); + WAITORTIMERCALLBACK callback = nullptr, + DWORD dueTime = 0, + DWORD period = 0); static void CreateFlushTimerCallback(WAITORTIMERCALLBACK Callback, DWORD DueTime, DWORD Period); static void DeleteFlushTimerCallback(); - // Performs one polling operation to determine if it is necessary to switch to a new file. - // If the polling operation decides it is time, it will perform the switch. - // Called directly from the timer when the timer is triggered. - static void WINAPI SwitchToNextFileTimerCallback(PVOID parameter, BOOLEAN timerFired); - static void WINAPI FlushTimer(PVOID parameter, BOOLEAN timerFired); - // If event pipe has been configured to write multiple files, switch to the next file. - static void SwitchToNextFile(); - - // Generate the file path for the next trace file. - // This is used when event pipe has been configured to create multiple trace files with a specified maximum length of time. - static void GetNextFilePath(SString &nextTraceFilePath); - // Callback function for the stack walker. For each frame walked, this callback is invoked. static StackWalkAction StackWalkCallback(CrawlFrame *pCf, StackContents *pData); @@ -358,14 +345,11 @@ private: static EventPipeConfiguration *s_pConfig; static EventPipeSession *s_pSession; static EventPipeBufferManager *s_pBufferManager; - static LPCWSTR s_pOutputPath; - static unsigned long s_nextFileIndex; static EventPipeFile *s_pFile; static EventPipeEventSource *s_pEventSource; static LPCWSTR s_pCommandLine; static HANDLE s_fileSwitchTimerHandle; static ULONGLONG s_lastFlushSwitchTime; - static uint64_t s_multiFileTraceLengthInSeconds; }; struct EventPipeProviderConfiguration diff --git a/src/vm/eventpipeinternal.cpp b/src/vm/eventpipeinternal.cpp index 30a14642c0..17efeb39e6 100644 --- a/src/vm/eventpipeinternal.cpp +++ b/src/vm/eventpipeinternal.cpp @@ -22,8 +22,7 @@ UINT64 QCALLTYPE EventPipeInternal::Enable( UINT32 circularBufferSizeInMB, INT64 profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, - UINT32 numProviders, - UINT64 multiFileTraceLengthInSeconds) + UINT32 numProviders) { QCALL_CONTRACT; @@ -36,8 +35,7 @@ UINT64 QCALLTYPE EventPipeInternal::Enable( circularBufferSizeInMB, profilerSamplingRateInNanoseconds, pProviders, - numProviders, - multiFileTraceLengthInSeconds); + numProviders); } END_QCALL; diff --git a/src/vm/eventpipeinternal.h b/src/vm/eventpipeinternal.h index bbd4ad633b..e4252c743a 100644 --- a/src/vm/eventpipeinternal.h +++ b/src/vm/eventpipeinternal.h @@ -49,8 +49,7 @@ public: UINT32 circularBufferSizeInMB, INT64 profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, - UINT32 numProviders, - UINT64 multiFileTraceLengthInSeconds); + UINT32 numProviders); //! TODO: Add a ListActiveSessions to get the live SessionID in order to Disable? diff --git a/src/vm/eventpipeprotocolhelper.cpp b/src/vm/eventpipeprotocolhelper.cpp index c1fe613c05..24eb2b0ef5 100644 --- a/src/vm/eventpipeprotocolhelper.cpp +++ b/src/vm/eventpipeprotocolhelper.cpp @@ -74,7 +74,7 @@ void EventPipeProtocolHelper::EnableFileTracingEventHandler(IpcStream *pStream) // 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, ulong multiFileTraceLength, string outputPath, array<provider_config> providers + // 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 @@ -84,13 +84,11 @@ void EventPipeProtocolHelper::EnableFileTracingEventHandler(IpcStream *pStream) LPCWSTR strOutputPath; uint32_t circularBufferSizeInMB = EventPipeProtocolHelper::DefaultCircularBufferMB; - uint64_t multiFileTraceLengthInSeconds = EventPipeProtocolHelper::DefaultMultiFileTraceLengthInSeconds; CQuickArray<EventPipeProviderConfiguration> providerConfigs; uint8_t *pBufferCursor = buffer; uint32_t bufferLen = nNumberOfBytesRead; if (!TryParse(pBufferCursor, bufferLen, circularBufferSizeInMB) || - !TryParse(pBufferCursor, bufferLen, multiFileTraceLengthInSeconds) || !TryParseString(pBufferCursor, bufferLen, strOutputPath) || !TryParseProviderConfiguration(pBufferCursor, bufferLen, providerConfigs)) { @@ -103,12 +101,11 @@ void EventPipeProtocolHelper::EnableFileTracingEventHandler(IpcStream *pStream) if (providerConfigs.Size() > 0) { sessionId = EventPipe::Enable( - strOutputPath, // outputFile - circularBufferSizeInMB, // circularBufferSizeInMB - DefaultProfilerSamplingRateInNanoseconds, // ProfilerSamplingRateInNanoseconds - providerConfigs.Ptr(), // pConfigs - static_cast<uint32_t>(providerConfigs.Size()), // numConfigs - multiFileTraceLengthInSeconds); // multiFileTraceLengthInSeconds + strOutputPath, // outputFile + circularBufferSizeInMB, // circularBufferSizeInMB + DefaultProfilerSamplingRateInNanoseconds, // ProfilerSamplingRateInNanoseconds + providerConfigs.Ptr(), // pConfigs + static_cast<uint32_t>(providerConfigs.Size())); // numConfigs } uint32_t nBytesWritten = 0; @@ -191,7 +188,7 @@ void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream) // 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, ulong multiFileTraceLength, string outputPath, array<provider_config> providers + // message = uint circularBufferMB, string outputPath, array<provider_config> providers // uint = 4 little endian bytes // wchar = 2 little endian bytes, UTF16 encoding // array<T> = uint length, length # of Ts @@ -200,13 +197,11 @@ void EventPipeProtocolHelper::AttachTracingEventHandler(IpcStream *pStream) LPCWSTR strOutputPath; uint32_t circularBufferSizeInMB = EventPipeProtocolHelper::DefaultCircularBufferMB; - uint64_t multiFileTraceLengthInSeconds = EventPipeProtocolHelper::DefaultMultiFileTraceLengthInSeconds; CQuickArray<EventPipeProviderConfiguration> providerConfigs; uint8_t *pBufferCursor = buffer; uint32_t bufferLen = nNumberOfBytesRead; if (!TryParse(pBufferCursor, bufferLen, circularBufferSizeInMB) || - !TryParse(pBufferCursor, bufferLen, multiFileTraceLengthInSeconds) || !TryParseString(pBufferCursor, bufferLen, strOutputPath) || !TryParseProviderConfiguration(pBufferCursor, bufferLen, providerConfigs)) { diff --git a/src/vm/eventpipeprotocolhelper.h b/src/vm/eventpipeprotocolhelper.h index 44192d724a..4fc8580b64 100644 --- a/src/vm/eventpipeprotocolhelper.h +++ b/src/vm/eventpipeprotocolhelper.h @@ -23,7 +23,6 @@ public: private: const static uint32_t DefaultCircularBufferMB = 1024; // 1 GB - const static uint64_t DefaultMultiFileTraceLengthInSeconds = 0; const static uint32_t DefaultProfilerSamplingRateInNanoseconds = 1000000; // 1 msec. const static uint32_t IpcStreamReadBufferSize = 8192; |