summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Falk <noahfalk@users.noreply.github.com>2019-06-21 15:27:21 -0700
committerGitHub <noreply@github.com>2019-06-21 15:27:21 -0700
commit961e8d7bd1bdd058ee5f8f34937e9f3f9d80b65b (patch)
tree06c18fd142f826966f051c908252089e6e5ec55b
parent205e01fc5020f597ee69643c24fd56268cdf1b50 (diff)
downloadcoreclr-961e8d7bd1bdd058ee5f8f34937e9f3f9d80b65b.tar.gz
coreclr-961e8d7bd1bdd058ee5f8f34937e9f3f9d80b65b.tar.bz2
coreclr-961e8d7bd1bdd058ee5f8f34937e9f3f9d80b65b.zip
Add EventPipe Processor Number support and make NetTrace the default … (#25276)
* Add EventPipe Processor Number support and make NetTrace the default format The EventPipe header now has a Processor Number field. On windows we query the correct value, on other OSes we currently have a -1 placeholder, but the field is written to the format regardless. NetTrace is now the default format when using the environment variable, and the format must be explicitly configured when using the IPC channel or managed API. A parallel change in the diagnostics repo is changing dotnet-trace and dotnet-counter to specify nettrace format which means .NET devs should see nettrace almost exclusively from now on. If for whatever reason it is needed, NetPerf remains available if a scenario explicitly requests to use it. * PR feedback + attempting to fix broken tests
-rw-r--r--dependencies.props2
-rw-r--r--src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs16
-rw-r--r--src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs3
-rw-r--r--src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeEventDispatcher.cs2
-rw-r--r--src/inc/clrconfigvalues.h3
-rw-r--r--src/vm/eventpipe.cpp24
-rw-r--r--src/vm/eventpipe.h22
-rw-r--r--src/vm/eventpipeblock.cpp9
-rw-r--r--src/vm/eventpipeblock.h1
-rw-r--r--src/vm/eventpipebuffer.cpp2
-rw-r--r--src/vm/eventpipeconfiguration.cpp1
-rw-r--r--src/vm/eventpipeeventinstance.cpp3
-rw-r--r--src/vm/eventpipeeventinstance.h16
-rw-r--r--src/vm/eventpipeinternal.cpp13
-rw-r--r--src/vm/eventpipeinternal.h1
-rw-r--r--src/vm/eventpipeprotocolhelper.cpp17
-rw-r--r--src/vm/eventpipeprotocolhelper.h3
-rw-r--r--tests/src/tracing/common/TraceConfiguration.cs18
-rw-r--r--tests/src/tracing/regress/GitHub_22247/GitHub_22247.cs15
19 files changed, 141 insertions, 30 deletions
diff --git a/dependencies.props b/dependencies.props
index a661e93db8..b04a88545f 100644
--- a/dependencies.props
+++ b/dependencies.props
@@ -25,7 +25,7 @@
<MicrosoftNETCoreRuntimeCoreCLRPackageVersion>3.0.0-preview6.19280.1</MicrosoftNETCoreRuntimeCoreCLRPackageVersion>
<XunitPackageVersion>2.4.1-pre.build.4059</XunitPackageVersion>
<XunitPerformanceApiPackageVersion>1.0.0-beta-build0015</XunitPerformanceApiPackageVersion>
- <MicrosoftDiagnosticsTracingTraceEventPackageVersion>2.0.40</MicrosoftDiagnosticsTracingTraceEventPackageVersion>
+ <MicrosoftDiagnosticsTracingTraceEventPackageVersion>2.0.43</MicrosoftDiagnosticsTracingTraceEventPackageVersion>
<CommandLineParserVersion>2.2.0</CommandLineParserVersion>
<!-- Scenario tests install this version of Microsoft.NetCore.App, then patch coreclr binaries via xcopy. At the moment it is
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 a7fb7cc2cb..f3f48b4583 100644
--- a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs
+++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.cs
@@ -79,15 +79,23 @@ namespace System.Diagnostics.Tracing
internal string? FilterData => m_filterData;
}
+ internal enum EventPipeSerializationFormat
+ {
+ NetPerf,
+ NetTrace
+ }
+
internal sealed class EventPipeConfiguration
{
private string m_outputFile;
+ private EventPipeSerializationFormat m_format;
private uint m_circularBufferSizeInMB;
private List<EventPipeProviderConfiguration> m_providers;
private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1);
internal EventPipeConfiguration(
string outputFile,
+ EventPipeSerializationFormat format,
uint circularBufferSizeInMB)
{
if(string.IsNullOrEmpty(outputFile))
@@ -99,6 +107,7 @@ namespace System.Diagnostics.Tracing
throw new ArgumentOutOfRangeException(nameof(circularBufferSizeInMB));
}
m_outputFile = outputFile;
+ m_format = format;
m_circularBufferSizeInMB = circularBufferSizeInMB;
m_providers = new List<EventPipeProviderConfiguration>();
}
@@ -108,6 +117,11 @@ namespace System.Diagnostics.Tracing
get { return m_outputFile; }
}
+ internal EventPipeSerializationFormat Format
+ {
+ get { return m_format; }
+ }
+
internal uint CircularBufferSizeInMB
{
get { return m_circularBufferSizeInMB; }
@@ -176,6 +190,7 @@ namespace System.Diagnostics.Tracing
s_sessionID = EventPipeInternal.Enable(
configuration.OutputFile,
+ configuration.Format,
configuration.CircularBufferSizeInMB,
providers,
(uint)providers.Length);
@@ -195,6 +210,7 @@ namespace System.Diagnostics.Tracing
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
internal static extern UInt64 Enable(
string? outputFile,
+ EventPipeSerializationFormat format,
uint circularBufferSizeInMB,
EventPipeProviderConfiguration[] providers,
uint numProviders);
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 8409078bb3..af68aefc8f 100644
--- a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
+++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
@@ -68,6 +68,7 @@ namespace System.Diagnostics.Tracing
// Create a new configuration object.
EventPipeConfiguration config = new EventPipeConfiguration(
outputFilePath,
+ (Config_NetTraceFormat != 0) ? EventPipeSerializationFormat.NetTrace : EventPipeSerializationFormat.NetPerf,
Config_EventPipeCircularMB);
// Get the configuration.
@@ -89,7 +90,7 @@ namespace System.Diagnostics.Tracing
private static string BuildTraceFileName()
{
return GetAppName() + "." + Interop.GetCurrentProcessId().ToString() +
- ((Config_NetTraceFormat > 0) ? NetTraceFileExtension : NetPerfFileExtension);
+ ((Config_NetTraceFormat != 0) ? NetTraceFileExtension : NetPerfFileExtension);
}
private static string GetAppName()
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 4ef9c515e8..a58d4eb750 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, providerConfiguration, 1);
+ m_sessionID = EventPipeInternal.Enable(null, EventPipeSerializationFormat.NetTrace, 1024, providerConfiguration, 1);
Debug.Assert(m_sessionID != 0);
// Get the session information that is required to properly dispatch events.
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h
index 7713af5040..4343ef4942 100644
--- a/src/inc/clrconfigvalues.h
+++ b/src/inc/clrconfigvalues.h
@@ -719,11 +719,12 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_AllowDComReflection, W("AllowDComReflection"),
// EventPipe
//
RETAIL_CONFIG_DWORD_INFO(INTERNAL_EnableEventPipe, W("EnableEventPipe"), 0, "Enable/disable event pipe. Non-zero values enable tracing.")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeNetTraceFormat, W("EventPipeNetTraceFormat"), 0, "Enable/disable using the newer nettrace file format.")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeNetTraceFormat, W("EventPipeNetTraceFormat"), 1, "Enable/disable using the newer nettrace file format.")
RETAIL_CONFIG_STRING_INFO(INTERNAL_EventPipeOutputPath, W("EventPipeOutputPath"), "The full path excluding file name for the trace file that will be written when COMPlus_EnableEventPipe=1")
RETAIL_CONFIG_STRING_INFO(INTERNAL_EventPipeConfig, W("EventPipeConfig"), "Configuration for EventPipe.")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeRundown, W("EventPipeRundown"), 1, "Enable/disable eventpipe rundown.")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeCircularMB, W("EventPipeCircularMB"), 1024, "The EventPipe circular buffer size in megabytes.")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers"), 0, "Enable/disable capturing processor numbers in EventPipe event headers")
#ifdef FEATURE_GDBJIT
///
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp
index adec56bd16..81b588f485 100644
--- a/src/vm/eventpipe.cpp
+++ b/src/vm/eventpipe.cpp
@@ -33,6 +33,9 @@ Volatile<bool> EventPipe::s_tracingInitialized = false;
EventPipeConfiguration EventPipe::s_config;
EventPipeEventSource *EventPipe::s_pEventSource = nullptr;
VolatilePtr<EventPipeSession> EventPipe::s_pSessions[MaxNumberOfSessions];
+#ifndef FEATURE_PAL
+unsigned int * EventPipe::s_pProcGroupOffsets = nullptr;
+#endif
#ifdef FEATURE_PAL
// This function is auto-generated from /src/scripts/genEventPipe.py
@@ -71,6 +74,26 @@ void EventPipe::Initialize()
const unsigned long DefaultProfilerSamplingRateInNanoseconds = 1000000; // 1 msec.
SampleProfiler::SetSamplingRate(DefaultProfilerSamplingRateInNanoseconds);
+
+ if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeProcNumbers) != 0)
+ {
+#ifndef FEATURE_PAL
+ // setup the windows processor group offset table
+ WORD numGroups = ::GetActiveProcessorGroupCount();
+ s_pProcGroupOffsets = new (nothrow) unsigned int[numGroups];
+ if (s_pProcGroupOffsets)
+ {
+ unsigned int countProcs = 0;
+ for (WORD i = 0; i < numGroups; i++)
+ {
+ s_pProcGroupOffsets[i] = countProcs;
+ countProcs += GetActiveProcessorCount(i);
+ }
+ }
+#endif
+ }
+
+
{
CrstHolder _crst(GetLock());
s_tracingInitialized = tracingInitialized;
@@ -577,6 +600,7 @@ void EventPipe::WriteEventInternal(
// as opposed a a buffer copy here
EventPipeEventInstance instance(
event,
+ GetCurrentProcessorNumber(),
pEventPipeThread->GetOSThreadId(),
pData,
payload.GetSize(),
diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h
index 20f6c1fc7f..7a8df26343 100644
--- a/src/vm/eventpipe.h
+++ b/src/vm/eventpipe.h
@@ -114,6 +114,21 @@ public:
InvokeCallback(eventPipeProviderCallbackData);
}
+ // Returns the a number 0...N representing the processor number this thread is currently
+ // running on. If for any reason we can't tell then return 0xFFFFFFFF.
+ static unsigned int GetCurrentProcessorNumber()
+ {
+#ifndef FEATURE_PAL
+ if (s_pProcGroupOffsets)
+ {
+ PROCESSOR_NUMBER procNum;
+ GetCurrentProcessorNumberEx(&procNum);
+ return s_pProcGroupOffsets[procNum.Group] + procNum.Number;
+ }
+#endif
+ return 0xFFFFFFFF;
+ }
+
private:
static void InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData);
@@ -174,6 +189,13 @@ private:
static EventPipeConfiguration s_config;
static VolatilePtr<EventPipeSession> s_pSessions[MaxNumberOfSessions];
static EventPipeEventSource *s_pEventSource;
+
+ // A mapping from windows processor group index to the total number of processors
+ // in all groups preceding it. For example if there are three groups with sizes:
+ // 1, 7, 6 the table would be 0, 1, 8
+#ifndef FEATURE_PAL
+ static unsigned int * s_pProcGroupOffsets;
+#endif
};
static_assert(EventPipe::MaxNumberOfSessions == 64, "Maximum number of EventPipe sessions is not 64.");
diff --git a/src/vm/eventpipeblock.cpp b/src/vm/eventpipeblock.cpp
index a2d561e1cd..fb9d6c721e 100644
--- a/src/vm/eventpipeblock.cpp
+++ b/src/vm/eventpipeblock.cpp
@@ -179,6 +179,7 @@ bool EventPipeEventBlockBase::WriteEvent(EventPipeEventInstance &instance,
unsigned int dataLength = 0;
BYTE* alignedEnd = NULL;
+ unsigned int captureProcNumber = instance.GetProcNumber();
if (!m_fUseHeaderCompression)
{
@@ -217,6 +218,9 @@ bool EventPipeEventBlockBase::WriteEvent(EventPipeEventInstance &instance,
memcpy(m_pWritePointer, &captureThreadId, sizeof(captureThreadId));
m_pWritePointer += sizeof(captureThreadId);
+ memcpy(m_pWritePointer, &captureProcNumber, sizeof(captureProcNumber));
+ m_pWritePointer += sizeof(captureProcNumber);
+
memcpy(m_pWritePointer, &stackId, sizeof(stackId));
m_pWritePointer += sizeof(stackId);
}
@@ -253,10 +257,12 @@ bool EventPipeEventBlockBase::WriteEvent(EventPipeEventInstance &instance,
}
if (m_lastHeader.SequenceNumber + (instance.GetMetadataId() != 0 ? 1 : 0) != sequenceNumber ||
- m_lastHeader.CaptureThreadId != captureThreadId)
+ m_lastHeader.CaptureThreadId != captureThreadId ||
+ m_lastHeader.CaptureProcNumber != captureProcNumber)
{
WriteVarUInt32(pWritePointer, sequenceNumber - m_lastHeader.SequenceNumber - 1);
WriteVarUInt64(pWritePointer, captureThreadId);
+ WriteVarUInt32(pWritePointer, captureProcNumber);
flags |= (1 << 1);
}
@@ -307,6 +313,7 @@ bool EventPipeEventBlockBase::WriteEvent(EventPipeEventInstance &instance,
m_lastHeader.SequenceNumber = sequenceNumber;
m_lastHeader.ThreadId = instance.GetThreadId64();
m_lastHeader.CaptureThreadId = captureThreadId;
+ m_lastHeader.CaptureProcNumber = captureProcNumber;
m_lastHeader.StackId = stackId;
m_lastHeader.TimeStamp.QuadPart = timeStamp->QuadPart;
memcpy(&m_lastHeader.ActivityId, instance.GetActivityId(), sizeof(GUID));
diff --git a/src/vm/eventpipeblock.h b/src/vm/eventpipeblock.h
index e7e9516fe5..1ce54dedb3 100644
--- a/src/vm/eventpipeblock.h
+++ b/src/vm/eventpipeblock.h
@@ -96,6 +96,7 @@ struct EventPipeEventHeader
DWORD SequenceNumber;
ULONGLONG ThreadId;
ULONGLONG CaptureThreadId;
+ DWORD CaptureProcNumber;
DWORD StackId;
LARGE_INTEGER TimeStamp;
GUID ActivityId;
diff --git a/src/vm/eventpipebuffer.cpp b/src/vm/eventpipebuffer.cpp
index 913fc57fcb..69eec1e268 100644
--- a/src/vm/eventpipebuffer.cpp
+++ b/src/vm/eventpipebuffer.cpp
@@ -88,8 +88,10 @@ bool EventPipeBuffer::WriteEvent(Thread *pThread, EventPipeSession &session, Eve
pStack = &s;
}
+ unsigned int procNumber = EventPipe::GetCurrentProcessorNumber();
EventPipeEventInstance *pInstance = new (m_pCurrent) EventPipeEventInstance(
event,
+ procNumber,
(pThread == NULL) ?
#ifdef FEATURE_PAL
::PAL_GetCurrentOSThreadId()
diff --git a/src/vm/eventpipeconfiguration.cpp b/src/vm/eventpipeconfiguration.cpp
index 84512b50fd..b6c9f01df1 100644
--- a/src/vm/eventpipeconfiguration.cpp
+++ b/src/vm/eventpipeconfiguration.cpp
@@ -453,6 +453,7 @@ EventPipeEventInstance *EventPipeConfiguration::BuildEventMetadataEvent(EventPip
// Construct the event instance.
EventPipeEventInstance *pInstance = new EventPipeEventInstance(
*m_pMetadataEvent,
+ EventPipe::GetCurrentProcessorNumber(),
#ifdef FEATURE_PAL
PAL_GetCurrentOSThreadId(),
#else
diff --git a/src/vm/eventpipeeventinstance.cpp b/src/vm/eventpipeeventinstance.cpp
index 19ce26919b..5b214a13b3 100644
--- a/src/vm/eventpipeeventinstance.cpp
+++ b/src/vm/eventpipeeventinstance.cpp
@@ -13,6 +13,7 @@
EventPipeEventInstance::EventPipeEventInstance(
EventPipeEvent &event,
+ unsigned int procNumber,
ULONGLONG threadId,
BYTE *pData,
unsigned int length,
@@ -32,6 +33,7 @@ EventPipeEventInstance::EventPipeEventInstance(
m_debugEventEnd = 0xCAFEBABE;
#endif // _DEBUG
m_pEvent = &event;
+ m_procNumber = procNumber;
m_threadId = threadId;
if (pActivityId != NULL)
{
@@ -101,6 +103,7 @@ unsigned int EventPipeEventInstance::GetAlignedTotalSize(EventPipeSerializationF
sizeof(unsigned int) + // Sequence number (implied by the buffer containing the event instance)
sizeof(m_threadId) + // Thread ID
sizeof(ULONGLONG) + // Capture Thread ID (implied by the buffer containing the event instance)
+ sizeof(m_procNumber) + // ProcNumber
sizeof(unsigned int) + // Stack intern table id
sizeof(m_timeStamp) + // TimeStamp
sizeof(m_activityId) + // Activity ID
diff --git a/src/vm/eventpipeeventinstance.h b/src/vm/eventpipeeventinstance.h
index 2ecb1118b6..a7fd4975f8 100644
--- a/src/vm/eventpipeeventinstance.h
+++ b/src/vm/eventpipeeventinstance.h
@@ -24,7 +24,13 @@ class EventPipeEventInstance
public:
- EventPipeEventInstance(EventPipeEvent &event, ULONGLONG threadID, BYTE *pData, unsigned int length, LPCGUID pActivityId, LPCGUID pRelatedActivityId);
+ EventPipeEventInstance(EventPipeEvent &event,
+ unsigned int procNumber,
+ ULONGLONG threadID,
+ BYTE *pData,
+ unsigned int length,
+ LPCGUID pActivityId,
+ LPCGUID pRelatedActivityId);
void EnsureStack(const EventPipeSession &session);
@@ -63,6 +69,13 @@ public:
m_metadataId = metadataId;
}
+ unsigned int GetProcNumber() const
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return m_procNumber;
+ }
+
DWORD GetThreadId32() const
{
LIMITED_METHOD_CONTRACT;
@@ -129,6 +142,7 @@ protected:
EventPipeEvent *m_pEvent;
unsigned int m_metadataId;
+ unsigned int m_procNumber;
ULONGLONG m_threadId;
LARGE_INTEGER m_timeStamp;
GUID m_activityId;
diff --git a/src/vm/eventpipeinternal.cpp b/src/vm/eventpipeinternal.cpp
index 093d1620c8..90c51d46ab 100644
--- a/src/vm/eventpipeinternal.cpp
+++ b/src/vm/eventpipeinternal.cpp
@@ -19,6 +19,7 @@
UINT64 QCALLTYPE EventPipeInternal::Enable(
__in_z LPCWSTR outputFile,
+ EventPipeSerializationFormat format,
UINT32 circularBufferSizeInMB,
EventPipeProviderConfiguration *pProviders,
UINT32 numProviders)
@@ -29,6 +30,7 @@ UINT64 QCALLTYPE EventPipeInternal::Enable(
// Invalid input!
if (circularBufferSizeInMB == 0 ||
+ format >= EventPipeSerializationFormat::Count ||
numProviders == 0 ||
pProviders == nullptr)
{
@@ -37,17 +39,6 @@ UINT64 QCALLTYPE EventPipeInternal::Enable(
BEGIN_QCALL;
{
- // This was a quick and dirty mechanism for testing but it may not be the final
- // configuration scheme we want. This path handles both the AI profiler scenario
- // doing private reflection and the EnableEventPipe env var. If we want to flip
- // the default for one but not the other we'll have to hoist the configuration
- // check into managed code.
- EventPipeSerializationFormat format = EventPipeSerializationFormat::NetPerfV3;
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeNetTraceFormat) > 0)
- {
- format = EventPipeSerializationFormat::NetTraceV4;
- }
-
sessionID = EventPipe::Enable(
outputFile,
circularBufferSizeInMB,
diff --git a/src/vm/eventpipeinternal.h b/src/vm/eventpipeinternal.h
index 2e95657658..ab280c357d 100644
--- a/src/vm/eventpipeinternal.h
+++ b/src/vm/eventpipeinternal.h
@@ -46,6 +46,7 @@ public:
//!
static UINT64 QCALLTYPE Enable(
__in_z LPCWSTR outputFile,
+ EventPipeSerializationFormat format,
UINT32 circularBufferSizeInMB,
EventPipeProviderConfiguration *pProviders,
UINT32 numProviders);
diff --git a/src/vm/eventpipeprotocolhelper.cpp b/src/vm/eventpipeprotocolhelper.cpp
index 00de406dd4..de5d1df105 100644
--- a/src/vm/eventpipeprotocolhelper.cpp
+++ b/src/vm/eventpipeprotocolhelper.cpp
@@ -32,6 +32,12 @@ static bool TryParseCircularBufferSize(uint8_t*& bufferCursor, uint32_t& bufferL
return CanParse && (circularBufferSizeInMB > 0);
}
+static bool TryParseSerializationFormat(uint8_t*& bufferCursor, uint32_t& bufferLen, EventPipeSerializationFormat& serializationFormat)
+{
+ const bool CanParse = TryParse(bufferCursor, bufferLen, (uint32_t&)serializationFormat);
+ return CanParse && (0 <= (int)serializationFormat) && ((int)serializationFormat < (int)EventPipeSerializationFormat::Count);
+}
+
const EventPipeCollectTracingCommandPayload* EventPipeCollectTracingCommandPayload::TryParse(BYTE* lpBuffer, uint16_t& BufferSize)
{
CONTRACTL
@@ -54,6 +60,7 @@ const EventPipeCollectTracingCommandPayload* EventPipeCollectTracingCommandPaylo
uint8_t* pBufferCursor = payload->incomingBuffer;
uint32_t bufferLen = BufferSize;
if (!TryParseCircularBufferSize(pBufferCursor, bufferLen, payload->circularBufferSizeInMB) ||
+ !TryParseSerializationFormat(pBufferCursor, bufferLen, payload->serializationFormat) ||
!TryParseString(pBufferCursor, bufferLen, payload->outputPath) ||
!EventPipeProtocolHelper::TryParseProviderConfiguration(pBufferCursor, bufferLen, payload->providerConfigs))
{
@@ -187,21 +194,13 @@ void EventPipeProtocolHelper::CollectTracing(DiagnosticsIpc::IpcMessage& message
return;
}
- // IPC should produce nettrace by default or be selectable via protocol
- // but this is a simple starting point for testing
- EventPipeSerializationFormat format = EventPipeSerializationFormat::NetPerfV3;
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeNetTraceFormat) > 0)
- {
- format = EventPipeSerializationFormat::NetTraceV4;
- }
-
auto sessionId = EventPipe::Enable(
nullptr, // strOutputPath (ignored in this scenario)
payload->circularBufferSizeInMB, // circularBufferSizeInMB
payload->providerConfigs.Ptr(), // pConfigs
static_cast<uint32_t>(payload->providerConfigs.Size()), // numConfigs
EventPipeSessionType::IpcStream, // EventPipeSessionType
- format, // EventPipeSerializationFormat
+ payload->serializationFormat, // EventPipeSerializationFormat
pStream); // IpcStream
if (sessionId == 0)
diff --git a/src/vm/eventpipeprotocolhelper.h b/src/vm/eventpipeprotocolhelper.h
index 2961b41726..743df5e600 100644
--- a/src/vm/eventpipeprotocolhelper.h
+++ b/src/vm/eventpipeprotocolhelper.h
@@ -30,13 +30,14 @@ struct EventPipeCollectTracingCommandPayload
// 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
+ // message = uint circularBufferMB, uint format, 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
// string = (array<char> where the last char must = 0) or (length = 0)
// provider_config = ulong keywords, uint logLevel, string provider_name, string filter_data
uint32_t circularBufferSizeInMB;
+ EventPipeSerializationFormat serializationFormat;
LPCWSTR outputPath;
CQuickArray<EventPipeProviderConfiguration> providerConfigs;
static const EventPipeCollectTracingCommandPayload* TryParse(BYTE* lpBuffer, uint16_t& BufferSize);
diff --git a/tests/src/tracing/common/TraceConfiguration.cs b/tests/src/tracing/common/TraceConfiguration.cs
index ad986c3608..afb7db24fc 100644
--- a/tests/src/tracing/common/TraceConfiguration.cs
+++ b/tests/src/tracing/common/TraceConfiguration.cs
@@ -7,6 +7,12 @@ using System.Reflection;
namespace Tracing.Tests.Common
{
+ public enum EventPipeSerializationFormat
+ {
+ NetPerf,
+ NetTrace
+ }
+
public sealed class TraceConfiguration
{
private ConstructorInfo m_configurationCtor;
@@ -29,6 +35,7 @@ namespace Tracing.Tests.Common
new object[]
{
outputFile,
+ EventPipeSerializationFormat.NetTrace,
circularBufferMB
});
}
@@ -79,10 +86,17 @@ namespace Tracing.Tests.Common
return false;
}
- m_configurationCtor = configurationType.GetConstructor(
+ Type formatType = SPC.GetType("System.Diagnostics.Tracing.EventPipeSerializationFormat");
+ if (formatType == null)
+ {
+ Console.WriteLine("formatType == null");
+ return false;
+ }
+
+ m_configurationCtor = configurationType.GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
- new Type[] { typeof(string), typeof(uint) },
+ new Type[] { typeof(string), formatType, typeof(uint) },
null);
if(m_configurationCtor == null)
{
diff --git a/tests/src/tracing/regress/GitHub_22247/GitHub_22247.cs b/tests/src/tracing/regress/GitHub_22247/GitHub_22247.cs
index a35c2b7ced..2e555444ed 100644
--- a/tests/src/tracing/regress/GitHub_22247/GitHub_22247.cs
+++ b/tests/src/tracing/regress/GitHub_22247/GitHub_22247.cs
@@ -4,6 +4,12 @@ using System.Reflection;
namespace EventPipe.Issue22247
{
+ public enum EventPipeSerializationFormat
+ {
+ NetPerf,
+ NetTrace
+ }
+
public sealed class TraceConfiguration
{
private ConstructorInfo m_configurationCtor;
@@ -26,6 +32,7 @@ namespace EventPipe.Issue22247
new object[]
{
outputFile,
+ EventPipeSerializationFormat.NetTrace,
circularBufferMB
});
}
@@ -75,11 +82,17 @@ namespace EventPipe.Issue22247
Console.WriteLine("configurationType == null");
return false;
}
+ Type formatType = SPC.GetType("System.Diagnostics.Tracing.EventPipeSerializationFormat");
+ if (formatType == null)
+ {
+ Console.WriteLine("formatType == null");
+ return false;
+ }
m_configurationCtor = configurationType.GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
- new Type[] { typeof(string), typeof(uint) },
+ new Type[] { typeof(string), formatType, typeof(uint) },
null);
if (m_configurationCtor == null)
{