summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosé Rivero <jorive@microsoft.com>2019-04-16 18:58:31 -0700
committerGitHub <noreply@github.com>2019-04-16 18:58:31 -0700
commitb388f6cd87d87f4a07fe966aaa1bc92f245165d9 (patch)
tree96d38fd71242691b4066ffe8977993b827bdb77a /src
parentf360bbc0cf893bcd612516563145729743d3af2b (diff)
downloadcoreclr-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.
Diffstat (limited to 'src')
-rw-r--r--src/debug/debug-pal/win/diagnosticsipc.cpp2
-rw-r--r--src/vm/diagnosticserver.cpp15
-rw-r--r--src/vm/diagnosticserver.h8
-rw-r--r--src/vm/eventpipe.cpp135
-rw-r--r--src/vm/eventpipe.h22
-rw-r--r--src/vm/eventpipeconfiguration.cpp3
-rw-r--r--src/vm/eventpipeinternal.cpp15
-rw-r--r--src/vm/eventpipeinternal.h4
-rw-r--r--src/vm/eventpipeprotocolhelper.cpp135
-rw-r--r--src/vm/eventpipeprotocolhelper.h6
-rw-r--r--src/vm/eventpipesession.cpp3
-rw-r--r--src/vm/eventpipesession.h6
-rw-r--r--src/vm/fastserializer.cpp15
-rw-r--r--src/vm/fastserializer.h4
14 files changed, 152 insertions, 221 deletions
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;
};
//!