summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Robbins <brianrob@microsoft.com>2018-06-04 10:26:53 -0700
committerGitHub <noreply@github.com>2018-06-04 10:26:53 -0700
commit6238c4fffd9c47c8b917af611c6609ef160d7bf8 (patch)
treed4d5761160cb3782814ca26020741a51d7b79dea
parentde586767f51432e5d89f6fcffee07c488fdeeb7b (diff)
downloadcoreclr-6238c4fffd9c47c8b917af611c6609ef160d7bf8.tar.gz
coreclr-6238c4fffd9c47c8b917af611c6609ef160d7bf8.tar.bz2
coreclr-6238c4fffd9c47c8b917af611c6609ef160d7bf8.zip
Flow EventSources to EventPipe on Windows (#18217)
-rw-r--r--clr.coreclr.props3
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs39
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs135
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs6
-rw-r--r--src/vm/eventpipe.cpp4
-rw-r--r--src/vm/eventpipeconfiguration.cpp12
-rw-r--r--src/vm/eventpipeeventsource.cpp2
-rw-r--r--src/vm/eventpipeprovider.cpp4
-rw-r--r--tests/issues.targets12
-rw-r--r--tests/src/tracing/common/EtlFile.cs33
-rw-r--r--tests/src/tracing/common/common.csproj1
-rw-r--r--tests/src/tracing/eventsource/eventpipeandetw/EventPipeAndEtw.cs293
-rw-r--r--tests/src/tracing/eventsource/eventpipeandetw/eventpipeandetw.csproj30
-rw-r--r--tests/src/tracing/eventsource/eventsourcetrace/EventSourceTrace.cs112
-rw-r--r--tests/src/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj (renamed from tests/src/tracing/eventsourcetrace/eventsourcetrace.csproj)2
-rw-r--r--tests/src/tracing/eventsourcetrace/EventSourceTrace.cs111
-rw-r--r--tests/testsUnsupportedOutsideWindows.txt1
17 files changed, 608 insertions, 192 deletions
diff --git a/clr.coreclr.props b/clr.coreclr.props
index 029ddca4f7..8b546c66b9 100644
--- a/clr.coreclr.props
+++ b/clr.coreclr.props
@@ -4,7 +4,7 @@
<FeatureICastable>true</FeatureICastable>
<FeatureManagedEtwChannels>true</FeatureManagedEtwChannels>
<FeatureManagedEtw>true</FeatureManagedEtw>
-
+ <FeaturePerfTracing>true</FeaturePerfTracing>
<ProfilingSupportedBuild>true</ProfilingSupportedBuild>
</PropertyGroup>
@@ -17,7 +17,6 @@
<FeatureStubsAsIL>true</FeatureStubsAsIL>
<FeatureCoreFxGlobalization>true</FeatureCoreFxGlobalization>
- <FeaturePerfTracing>true</FeaturePerfTracing>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetsWindows)' == 'true'">
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs
index d412e6bde0..7ad7f0ce96 100644
--- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs
+++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs
@@ -30,6 +30,13 @@ namespace Microsoft.Diagnostics.Tracing
namespace System.Diagnostics.Tracing
#endif
{
+ internal enum EventProviderType
+ {
+ None = 0,
+ ETW,
+ EventPipe
+ };
+
// New in CLR4.0
internal enum ControllerCommand
{
@@ -120,15 +127,28 @@ namespace System.Diagnostics.Tracing
// it registers a callback from native code you MUST dispose it BEFORE shutdown, otherwise
// you may get native callbacks during shutdown when we have destroyed the delegate.
// EventSource has special logic to do this, no one else should be calling EventProvider.
- internal EventProvider()
+ internal EventProvider(EventProviderType providerType)
{
+ switch (providerType)
+ {
+ case EventProviderType.ETW:
#if PLATFORM_WINDOWS
- m_eventProvider = new EtwEventProvider();
-#elif FEATURE_PERFTRACING
- m_eventProvider = new EventPipeEventProvider();
+ m_eventProvider = new EtwEventProvider();
#else
- m_eventProvider = new NoOpEventProvider();
+ m_eventProvider = new NoOpEventProvider();
#endif
+ break;
+ case EventProviderType.EventPipe:
+#if FEATURE_PERFTRACING
+ m_eventProvider = new EventPipeEventProvider();
+#else
+ m_eventProvider = new NoOpEventProvider();
+#endif
+ break;
+ default:
+ m_eventProvider = new NoOpEventProvider();
+ break;
+ };
}
/// <summary>
@@ -475,7 +495,7 @@ namespace System.Diagnostics.Tracing
var structBase = (byte*)providerInstance;
providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
}
-#else
+#else
#if !ES_BUILD_PCL && PLATFORM_WINDOWS // TODO command arguments don't work on PCL builds...
// This code is only used in the Nuget Package Version of EventSource. because
// the code above is using APIs baned from UWP apps.
@@ -1276,8 +1296,7 @@ namespace System.Diagnostics.Tracing
}
}
-#elif !FEATURE_PERFTRACING
-
+#endif
internal sealed class NoOpEventProvider : IEventProvider
{
unsafe uint IEventProvider.EventRegister(
@@ -1314,10 +1333,8 @@ namespace System.Diagnostics.Tracing
// Define an EventPipeEvent handle.
unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, Int64 keywords, uint eventVersion, uint level, byte *pMetadata, uint metadataLength)
{
- throw new System.NotSupportedException();
+ return IntPtr.Zero;
}
}
-
-#endif
}
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
index 6992dcea43..8376c49a3f 100644
--- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
+++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
@@ -434,7 +434,7 @@ namespace System.Diagnostics.Tracing
throw new ArgumentException(SR.EventSource_InvalidCommand, nameof(command));
}
- eventSource.SendCommand(null, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
+ eventSource.SendCommand(null, EventProviderType.ETW, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
}
#if !ES_BUILD_STANDALONE
@@ -614,7 +614,7 @@ namespace System.Diagnostics.Tracing
}
Debug.Assert(m_eventData != null);
- Debug.Assert(m_provider != null);
+ Debug.Assert(m_eventPipeProvider != null);
int cnt = m_eventData.Length;
for (int i = 0; i < cnt; i++)
{
@@ -632,7 +632,7 @@ namespace System.Diagnostics.Tracing
fixed (byte *pMetadata = metadata)
{
- IntPtr eventHandle = m_provider.m_eventProvider.DefineEventHandle(
+ IntPtr eventHandle = m_eventPipeProvider.m_eventProvider.DefineEventHandle(
eventID,
eventName,
keywords,
@@ -1165,12 +1165,16 @@ namespace System.Diagnostics.Tracing
}
#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
+ if (m_eventData[eventId].EnabledForETW || m_eventData[eventId].EnabledForEventPipe)
{
if (!SelfDescribingEvents)
{
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
+ if (!m_etwProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
ThrowEventSourceException(m_eventData[eventId].Name);
+#if FEATURE_PERFTRACING
+ if (!m_eventPipeProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+#endif // FEATURE_PERFTRACING
}
else
{
@@ -1261,7 +1265,6 @@ namespace System.Diagnostics.Tracing
if (disposing)
{
#if FEATURE_MANAGED_ETW
-#if !FEATURE_PERFTRACING
// Send the manifest one more time to ensure circular buffers have a chance to get to this information
// even in scenarios with a high volume of ETW events.
if (m_eventSourceEnabled)
@@ -1274,11 +1277,17 @@ namespace System.Diagnostics.Tracing
{ } // If it fails, simply give up.
m_eventSourceEnabled = false;
}
+ if (m_etwProvider != null)
+ {
+ m_etwProvider.Dispose();
+ m_etwProvider = null;
+ }
#endif
- if (m_provider != null)
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider != null)
{
- m_provider.Dispose();
- m_provider = null;
+ m_eventPipeProvider.Dispose();
+ m_eventPipeProvider = null;
}
#endif
}
@@ -1306,16 +1315,27 @@ namespace System.Diagnostics.Tracing
IntPtr data)
{
#if FEATURE_MANAGED_ETW
- if (m_provider == null)
+ if (m_etwProvider == null)
{
ThrowEventSourceException(eventName);
}
else
{
- if (!m_provider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
+ if (!m_etwProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
ThrowEventSourceException(eventName);
}
#endif // FEATURE_MANAGED_ETW
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider == null)
+ {
+ ThrowEventSourceException(eventName);
+ }
+ else
+ {
+ if (!m_eventPipeProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
+ ThrowEventSourceException(eventName);
+ }
+#endif // FEATURE_PERFTRACING
}
// FrameworkEventSource is on the startup path for the framework, so we have this internal overload that it can use
@@ -1364,14 +1384,20 @@ namespace System.Diagnostics.Tracing
//Enable Implicit Activity tracker
m_activityTracker = ActivityTracker.Instance;
-#if FEATURE_MANAGED_ETW
+#if FEATURE_MANAGED_ETW || FEATURE_PERFTRACING
// Create and register our provider traits. We do this early because it is needed to log errors
// In the self-describing event case.
this.InitializeProviderMetadata();
-
+#endif
+#if FEATURE_MANAGED_ETW
// Register the provider with ETW
- var provider = new OverideEventProvider(this);
- provider.Register(this);
+ var etwProvider = new OverideEventProvider(this, EventProviderType.ETW);
+ etwProvider.Register(this);
+#endif
+#if FEATURE_PERFTRACING
+ // Register the provider with EventPipe
+ var eventPipeProvider = new OverideEventProvider(this, EventProviderType.EventPipe);
+ eventPipeProvider.Register(this);
#endif
// Add the eventSource to the global (weak) list.
// This also sets m_id, which is the index in the list.
@@ -1380,7 +1406,7 @@ namespace System.Diagnostics.Tracing
#if FEATURE_MANAGED_ETW
// OK if we get this far without an exception, then we can at least write out error messages.
// Set m_provider, which allows this.
- m_provider = provider;
+ m_etwProvider = etwProvider;
#if PLATFORM_WINDOWS
#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
@@ -1394,7 +1420,7 @@ namespace System.Diagnostics.Tracing
System.Runtime.InteropServices.GCHandle.Alloc(this.providerMetadata, System.Runtime.InteropServices.GCHandleType.Pinned);
IntPtr providerMetadata = metadataHandle.AddrOfPinnedObject();
- setInformationResult = m_provider.SetInformation(
+ setInformationResult = m_etwProvider.SetInformation(
UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS.SetTraits,
providerMetadata,
(uint)this.providerMetadata.Length);
@@ -1403,6 +1429,10 @@ namespace System.Diagnostics.Tracing
}
#endif // PLATFORM_WINDOWS
#endif // FEATURE_MANAGED_ETW
+
+#if FEATURE_PERFTRACING
+ m_eventPipeProvider = eventPipeProvider;
+#endif
Debug.Assert(!m_eventSourceEnabled); // We can't be enabled until we are completely initted.
// We are logically completely initialized at this point.
m_completelyInited = true;
@@ -1835,12 +1865,16 @@ namespace System.Diagnostics.Tracing
}
#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
+ if (m_eventData[eventId].EnabledForETW || m_eventData[eventId].EnabledForEventPipe)
{
if (!SelfDescribingEvents)
{
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, childActivityID, args))
+ if (!m_etwProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, childActivityID, args))
ThrowEventSourceException(m_eventData[eventId].Name);
+#if FEATURE_PERFTRACING
+ if (!m_eventPipeProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, childActivityID, args))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+#endif // FEATURE_PERFTRACING
}
else
{
@@ -1865,7 +1899,7 @@ namespace System.Diagnostics.Tracing
}
}
#endif // FEATURE_MANAGED_ETW
- if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
+ if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
{
#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
// Maintain old behavior - object identity is preserved
@@ -2030,8 +2064,8 @@ namespace System.Diagnostics.Tracing
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
private unsafe void WriteEventString(EventLevel level, long keywords, string msgString)
{
-#if FEATURE_MANAGED_ETW && !FEATURE_PERFTRACING
- if (m_provider != null)
+#if FEATURE_MANAGED_ETW
+ if (m_etwProvider != null)
{
string eventName = "EventSourceMessage";
if (SelfDescribingEvents)
@@ -2066,7 +2100,7 @@ namespace System.Diagnostics.Tracing
data.Ptr = (ulong)msgStringPtr;
data.Size = (uint)(2 * (msgString.Length + 1));
data.Reserved = 0;
- m_provider.WriteEvent(ref descr, IntPtr.Zero, null, null, 1, (IntPtr)((void*)&data));
+ m_etwProvider.WriteEvent(ref descr, IntPtr.Zero, null, null, 1, (IntPtr)((void*)&data));
}
}
}
@@ -2260,19 +2294,22 @@ namespace System.Diagnostics.Tracing
/// </summary>
private class OverideEventProvider : EventProvider
{
- public OverideEventProvider(EventSource eventSource)
+ public OverideEventProvider(EventSource eventSource, EventProviderType providerType)
+ : base(providerType)
{
this.m_eventSource = eventSource;
+ this.m_eventProviderType = providerType;
}
protected override void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments,
int perEventSourceSessionId, int etwSessionId)
{
// We use null to represent the ETW EventListener.
EventListener listener = null;
- m_eventSource.SendCommand(listener, perEventSourceSessionId, etwSessionId,
+ m_eventSource.SendCommand(listener, m_eventProviderType, perEventSourceSessionId, etwSessionId,
(EventCommand)command, IsEnabled(), Level, MatchAnyKeyword, arguments);
}
private EventSource m_eventSource;
+ private EventProviderType m_eventProviderType;
}
#endif
@@ -2301,7 +2338,8 @@ namespace System.Diagnostics.Tracing
public IntPtr EventHandle; // EventPipeEvent handle.
public EventTags Tags;
public bool EnabledForAnyListener; // true if any dispatcher has this event turned on
- public bool EnabledForETW; // is this event on for the OS ETW data dispatcher?
+ public bool EnabledForETW; // is this event on for ETW?
+ public bool EnabledForEventPipe; // is this event on for EventPipe?
public bool HasRelatedActivityID; // Set if the event method's first parameter is a Guid named 'relatedActivityId'
#pragma warning disable 0649
@@ -2345,12 +2383,12 @@ namespace System.Diagnostics.Tracing
// * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0).
//
// dispatcher == null has special meaning. It is the 'ETW' dispatcher.
- internal void SendCommand(EventListener listener, int perEventSourceSessionId, int etwSessionId,
+ internal void SendCommand(EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId,
EventCommand command, bool enable,
EventLevel level, EventKeywords matchAnyKeyword,
IDictionary<string, string> commandArguments)
{
- var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword);
+ var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, eventProviderType, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword);
lock (EventListener.EventListenersLock)
{
if (m_completelyInited)
@@ -2390,9 +2428,13 @@ namespace System.Diagnostics.Tracing
Debug.Assert(m_completelyInited);
#if FEATURE_MANAGED_ETW
- if (m_provider == null) // If we failed to construct
+ if (m_etwProvider == null) // If we failed to construct
return;
#endif // FEATURE_MANAGED_ETW
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider == null)
+ return;
+#endif
m_outOfBandMessageCount = 0;
bool shouldReport = (commandArgs.perEventSourceSessionId > 0) && (commandArgs.perEventSourceSessionId <= SessionMask.MAX);
@@ -2415,7 +2457,7 @@ namespace System.Diagnostics.Tracing
{
// Set it up using the 'standard' filtering bitfields (use the "global" enable, not session specific one)
for (int i = 0; i < m_eventData.Length; i++)
- EnableEventForDispatcher(commandArgs.dispatcher, i, IsEnabledByDefault(i, commandArgs.enable, commandArgs.level, commandArgs.matchAnyKeyword));
+ EnableEventForDispatcher(commandArgs.dispatcher, commandArgs.eventProviderType, i, IsEnabledByDefault(i, commandArgs.enable, commandArgs.level, commandArgs.matchAnyKeyword));
if (commandArgs.enable)
{
@@ -2465,13 +2507,11 @@ namespace System.Diagnostics.Tracing
{
// eventSourceDispatcher == null means this is the ETW manifest
-#if !FEATURE_PERFTRACING
// Note that we unconditionally send the manifest whenever we are enabled, even if
// we were already enabled. This is because there may be multiple sessions active
// and we can't know that all the sessions have seen the manifest.
if (!SelfDescribingEvents)
SendManifest(m_rawManifest);
-#endif
}
// Turn on the enable bit before making the OnEventCommand callback This allows you to do useful
@@ -2553,16 +2593,20 @@ namespace System.Diagnostics.Tracing
/// of 'eventId. If value is 'false' disable the event for that dispatcher. If 'eventId' is out of
/// range return false, otherwise true.
/// </summary>
- internal bool EnableEventForDispatcher(EventDispatcher dispatcher, int eventId, bool value)
+ internal bool EnableEventForDispatcher(EventDispatcher dispatcher, EventProviderType eventProviderType, int eventId, bool value)
{
if (dispatcher == null)
{
if (eventId >= m_eventData.Length)
return false;
#if FEATURE_MANAGED_ETW
- if (m_provider != null)
+ if (m_etwProvider != null && eventProviderType == EventProviderType.ETW)
m_eventData[eventId].EnabledForETW = value;
#endif
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider != null && eventProviderType == EventProviderType.EventPipe)
+ m_eventData[eventId].EnabledForEventPipe = value;
+#endif
}
else
{
@@ -2581,7 +2625,7 @@ namespace System.Diagnostics.Tracing
private bool AnyEventEnabled()
{
for (int i = 0; i < m_eventData.Length; i++)
- if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForAnyListener)
+ if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForEventPipe || m_eventData[i].EnabledForAnyListener)
return true;
return false;
}
@@ -2701,9 +2745,9 @@ namespace System.Diagnostics.Tracing
while (dataLeft > 0)
{
dataDescrs[1].Size = (uint)Math.Min(dataLeft, chunkSize);
- if (m_provider != null)
+ if (m_etwProvider != null)
{
- if (!m_provider.WriteEvent(ref manifestDescr, IntPtr.Zero, null, null, 2, (IntPtr)dataDescrs))
+ if (!m_etwProvider.WriteEvent(ref manifestDescr, IntPtr.Zero, null, null, 2, (IntPtr)dataDescrs))
{
// Turns out that if users set the BufferSize to something less than 64K then WriteEvent
// can fail. If we get this failure on the first chunk try again with something smaller
@@ -3642,7 +3686,10 @@ namespace System.Diagnostics.Tracing
// Dispatching state
internal volatile EventDispatcher m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially)
#if FEATURE_MANAGED_ETW
- private volatile OverideEventProvider m_provider; // This hooks up ETW commands to our 'OnEventCommand' callback
+ private volatile OverideEventProvider m_etwProvider; // This hooks up ETW commands to our 'OnEventCommand' callback
+#endif
+#if FEATURE_PERFTRACING
+ private volatile OverideEventProvider m_eventPipeProvider;
#endif
private bool m_completelyInited; // The EventSource constructor has returned without exception.
private Exception m_constructionException; // If there was an exception construction, this is it
@@ -3886,7 +3933,7 @@ namespace System.Diagnostics.Tracing
throw new ArgumentNullException(nameof(eventSource));
}
- eventSource.SendCommand(this, 0, 0, EventCommand.Update, true, level, matchAnyKeyword, arguments);
+ eventSource.SendCommand(this, EventProviderType.None, 0, 0, EventCommand.Update, true, level, matchAnyKeyword, arguments);
}
/// <summary>
/// Disables all events coming from eventSource identified by 'eventSource'.
@@ -3900,7 +3947,7 @@ namespace System.Diagnostics.Tracing
throw new ArgumentNullException(nameof(eventSource));
}
- eventSource.SendCommand(this, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null);
+ eventSource.SendCommand(this, EventProviderType.None, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null);
}
/// <summary>
@@ -4245,7 +4292,7 @@ namespace System.Diagnostics.Tracing
{
if (Command != EventCommand.Enable && Command != EventCommand.Disable)
throw new InvalidOperationException();
- return eventSource.EnableEventForDispatcher(dispatcher, eventId, true);
+ return eventSource.EnableEventForDispatcher(dispatcher, eventProviderType, eventId, true);
}
/// <summary>
@@ -4257,18 +4304,19 @@ namespace System.Diagnostics.Tracing
{
if (Command != EventCommand.Enable && Command != EventCommand.Disable)
throw new InvalidOperationException();
- return eventSource.EnableEventForDispatcher(dispatcher, eventId, false);
+ return eventSource.EnableEventForDispatcher(dispatcher, eventProviderType, eventId, false);
}
#region private
internal EventCommandEventArgs(EventCommand command, IDictionary<string, string> arguments, EventSource eventSource,
- EventListener listener, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
+ EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
{
this.Command = command;
this.Arguments = arguments;
this.eventSource = eventSource;
this.listener = listener;
+ this.eventProviderType = eventProviderType;
this.perEventSourceSessionId = perEventSourceSessionId;
this.etwSessionId = etwSessionId;
this.enable = enable;
@@ -4278,6 +4326,7 @@ namespace System.Diagnostics.Tracing
internal EventSource eventSource;
internal EventDispatcher dispatcher;
+ internal EventProviderType eventProviderType;
// These are the arguments of sendCommand and are only used for deferring commands until after we are fully initialized.
internal EventListener listener;
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs
index 1793a16e0e..0bf6657ffa 100644
--- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs
+++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs
@@ -437,7 +437,7 @@ namespace System.Diagnostics.Tracing
EventDescriptor descriptor = new EventDescriptor(identity, level, opcode, (long)keywords);
#if FEATURE_PERFTRACING
- IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes);
+ IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
Debug.Assert(eventHandle != IntPtr.Zero);
#else
IntPtr eventHandle = IntPtr.Zero;
@@ -552,7 +552,7 @@ namespace System.Diagnostics.Tracing
}
#if FEATURE_PERFTRACING
- IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes);
+ IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
Debug.Assert(eventHandle != IntPtr.Zero);
#else
IntPtr eventHandle = IntPtr.Zero;
@@ -621,7 +621,7 @@ namespace System.Diagnostics.Tracing
}
#if FEATURE_PERFTRACING
- IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes);
+ IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
Debug.Assert(eventHandle != IntPtr.Zero);
#else
IntPtr eventHandle = IntPtr.Zero;
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp
index cad3093d46..fb112db72b 100644
--- a/src/vm/eventpipe.cpp
+++ b/src/vm/eventpipe.cpp
@@ -471,7 +471,7 @@ EventPipeProvider* EventPipe::CreateProvider(const SString &providerName, EventP
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
@@ -554,7 +554,6 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
- PRECONDITION(s_pSession != NULL);
}
CONTRACTL_END;
@@ -577,6 +576,7 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload
// We can't procede without a configuration
return;
}
+ _ASSERTE(s_pSession != NULL);
// If the activity id isn't specified, pull it from the current thread.
if(pActivityId == NULL)
diff --git a/src/vm/eventpipeconfiguration.cpp b/src/vm/eventpipeconfiguration.cpp
index d787956c7c..74d9f44abc 100644
--- a/src/vm/eventpipeconfiguration.cpp
+++ b/src/vm/eventpipeconfiguration.cpp
@@ -86,7 +86,7 @@ void EventPipeConfiguration::Initialize()
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
@@ -108,7 +108,7 @@ EventPipeProvider* EventPipeConfiguration::CreateProvider(const SString &provide
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
@@ -151,7 +151,7 @@ bool EventPipeConfiguration::RegisterProvider(EventPipeProvider &provider)
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
@@ -346,7 +346,7 @@ void EventPipeConfiguration::Enable(EventPipeSession *pSession)
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(pSession != NULL);
// Lock must be held by EventPipe::Enable.
@@ -385,7 +385,7 @@ void EventPipeConfiguration::Disable(EventPipeSession *pSession)
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
// TODO: Multiple session support will require that the session be specified.
PRECONDITION(pSession != NULL);
@@ -431,7 +431,7 @@ void EventPipeConfiguration::EnableRundown(EventPipeSession *pSession)
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(pSession != NULL);
// Lock must be held by EventPipe::Disable.
diff --git a/src/vm/eventpipeeventsource.cpp b/src/vm/eventpipeeventsource.cpp
index 1a5cf2a3f3..a115af7227 100644
--- a/src/vm/eventpipeeventsource.cpp
+++ b/src/vm/eventpipeeventsource.cpp
@@ -20,7 +20,7 @@ EventPipeEventSource::EventPipeEventSource()
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
diff --git a/src/vm/eventpipeprovider.cpp b/src/vm/eventpipeprovider.cpp
index 3e82706801..c2a0169e7b 100644
--- a/src/vm/eventpipeprovider.cpp
+++ b/src/vm/eventpipeprovider.cpp
@@ -116,7 +116,7 @@ void EventPipeProvider::SetConfiguration(bool providerEnabled, INT64 keywords, E
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
}
@@ -191,7 +191,7 @@ void EventPipeProvider::InvokeCallback()
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
}
diff --git a/tests/issues.targets b/tests/issues.targets
index 2b9b2729f2..aed787dd13 100644
--- a/tests/issues.targets
+++ b/tests/issues.targets
@@ -1728,16 +1728,8 @@
<ExcludeList Include="$(XunitTestBinBase)\managed\Compilation\Compilation\Compilation.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
- </ItemGroup>
-
- <!-- The following are tests that fail on Windows -->
-
- <ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(TargetsWindows)' == 'true'">
- <ExcludeList Include="$(XunitTestBinBase)\tracing\eventsourcetrace\eventsourcetrace\eventsourcetrace.cmd">
- <Issue>15494</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\tracing\tracevalidation\tracelogging\tracelogging\tracelogging.cmd">
- <Issue>15494</Issue>
+ <ExcludeList Include="$(XunitTestBinBase)\tracing\eventsource\eventpipeandetw\eventpipeandetw\eventpipeandetw.cmd">
+ <Issue>by design Windows only</Issue>
</ExcludeList>
</ItemGroup>
diff --git a/tests/src/tracing/common/EtlFile.cs b/tests/src/tracing/common/EtlFile.cs
new file mode 100644
index 0000000000..f476ce230c
--- /dev/null
+++ b/tests/src/tracing/common/EtlFile.cs
@@ -0,0 +1,33 @@
+using System;
+using System.IO;
+
+namespace Tracing.Tests.Common
+{
+ public class EtlFile : IDisposable
+ {
+ public string Path { get; }
+ private bool KeepOutput { get; }
+
+ private EtlFile(string fileName, bool keep)
+ {
+ Path = fileName;
+ KeepOutput = keep;
+ }
+
+ public void Dispose()
+ {
+ if (KeepOutput)
+ Console.WriteLine("\n\tOutput file: {0}", Path);
+ else
+ File.Delete(Path);
+ }
+
+ public static EtlFile Create(string[] args)
+ {
+ if (args.Length >= 1)
+ return new EtlFile(args[0], true);
+
+ return new EtlFile(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".etl", false);
+ }
+ }
+}
diff --git a/tests/src/tracing/common/common.csproj b/tests/src/tracing/common/common.csproj
index 0fe8d0fb4f..32a210882c 100644
--- a/tests/src/tracing/common/common.csproj
+++ b/tests/src/tracing/common/common.csproj
@@ -26,6 +26,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Assert.cs" />
+ <Compile Include="EtlFile.cs" />
<Compile Include="NetPerfFile.cs" />
<Compile Include="TraceControl.cs" />
<Compile Include="TraceConfiguration.cs" />
diff --git a/tests/src/tracing/eventsource/eventpipeandetw/EventPipeAndEtw.cs b/tests/src/tracing/eventsource/eventpipeandetw/EventPipeAndEtw.cs
new file mode 100644
index 0000000000..71ef01365d
--- /dev/null
+++ b/tests/src/tracing/eventsource/eventpipeandetw/EventPipeAndEtw.cs
@@ -0,0 +1,293 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Threading;
+using Tracing.Tests.Common;
+using System.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing.Etlx;
+using Microsoft.Diagnostics.Tracing.Parsers;
+using Microsoft.Diagnostics.Tracing.Parsers.Clr;
+using Microsoft.Diagnostics.Tracing.Session;
+
+namespace Tracing.Tests
+{
+ [EventSource(Name = "EventPipeAndEtwEventSource")]
+ class EventPipeAndEtwEventSource : EventSource
+ {
+ public class Keywords
+ {
+ public const EventKeywords EventPipeKeyword = (EventKeywords)0x1;
+ public const EventKeywords EtwKeyword = (EventKeywords)0x2;
+ }
+
+ public static EventPipeAndEtwEventSource Log = new EventPipeAndEtwEventSource();
+
+ private EventPipeAndEtwEventSource() : base(true) { }
+
+ [Event(1, Keywords = Keywords.EventPipeKeyword)]
+ public void Event1()
+ {
+ WriteEvent(1);
+ }
+
+ [Event(2, Keywords = Keywords.EtwKeyword)]
+ public void Event2()
+ {
+ WriteEvent(2);
+ }
+
+ [Event(3, Keywords = Keywords.EventPipeKeyword | Keywords.EtwKeyword)]
+ public void Event3()
+ {
+ WriteEvent(3);
+ }
+ }
+
+ class EventResults
+ {
+ public int Event1Count { get; private set; }
+ public int Event2Count { get; private set; }
+ public int Event3Count { get; private set; }
+
+ public void AddEvent(TraceEvent data)
+ {
+ if (data.ProviderName == EventPipeAndEtwEventSource.Log.Name)
+ {
+ if (data.EventName == "ManifestData")
+ {
+ return;
+ }
+
+ if (data.EventName == "Event1")
+ {
+ Event1Count++;
+ }
+ else if (data.EventName == "Event2")
+ {
+ Event2Count++;
+ }
+ else if (data.EventName == "Event3")
+ {
+ Event3Count++;
+ }
+ else
+ {
+ Console.WriteLine($"\tEncountered unexpected event with name '{data.EventName}'.");
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public void Print(string header)
+ {
+ Console.WriteLine("\n\t" + header);
+ Console.WriteLine($"\t\tEvent1Count: {Event1Count}");
+ Console.WriteLine($"\t\tEvent2Count: {Event2Count}");
+ Console.WriteLine($"\t\tEvent3Count: {Event3Count}\n\n");
+ }
+ }
+
+ class EventPipeAndEtw
+ {
+ private static TraceConfiguration EventPipeGetConfig(EventSource eventSource, EventKeywords keywords, string outputFile="default.netperf")
+ {
+ // Setup the configuration values.
+ uint circularBufferMB = 1024; // 1 GB
+ uint level = 5;
+
+ // Create a new instance of EventPipeConfiguration.
+ TraceConfiguration config = new TraceConfiguration(outputFile, circularBufferMB);
+
+ // Enable the provider.
+ config.EnableProvider(eventSource.Name, (ulong)keywords, level);
+
+ return config;
+ }
+
+ private static TraceEventSession EnableETW(EventSource eventSource, EventKeywords keywords, string outputFile="default.etl")
+ {
+ outputFile = Path.GetFullPath(outputFile);
+ TraceEventSession session = new TraceEventSession("EventSourceEventPipeSession", outputFile);
+ session.EnableProvider(eventSource.Name, TraceEventLevel.Verbose, (ulong)keywords, null);
+ Thread.Sleep(200); // Calls are async.
+ return session;
+ }
+
+ private static void DisableETW(TraceEventSession traceEventSession)
+ {
+ traceEventSession.Flush();
+ Thread.Sleep(1010); // Calls are async.
+ traceEventSession.Dispose();
+ }
+
+ private static void WriteAllEvents(EventPipeAndEtwEventSource eventSource)
+ {
+ Console.WriteLine("\tStart: Write events.");
+ eventSource.Event1();
+ eventSource.Event2();
+ eventSource.Event3();
+ Console.WriteLine("\tEnd: Writing events.\n");
+ }
+
+ private static void RoundOne(string[] args)
+ {
+ using (var netPerfFile = NetPerfFile.Create(args))
+ {
+ using (var etlFile = EtlFile.Create(args))
+ {
+ Console.WriteLine("\tStart: Enable EventPipe.");
+ TraceControl.Enable(EventPipeGetConfig(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EventPipeKeyword, netPerfFile.Path));
+ Console.WriteLine("\tEnd: Enable EventPipe.\n");
+
+ Console.WriteLine("\tStart: Enable ETW.");
+ TraceEventSession etwSession = EnableETW(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EtwKeyword, etlFile.Path);
+ Console.WriteLine("\tEnd: Enable ETW.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable ETW.");
+ DisableETW(etwSession);
+ Console.WriteLine("\tEnd: Disable ETW.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable EventPipe.");
+ TraceControl.Disable();
+ Console.WriteLine("\tEnd: Disable EventPipe.\n");
+
+ Console.WriteLine("\tStart: Processing events from EventPipe file.");
+
+ EventResults eventPipeResults = new EventResults();
+ EventResults etwResults = new EventResults();
+
+ using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ eventPipeResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate EventPipe results.
+ eventPipeResults.Print("EventPipe Results:");
+ Assert.Equal("EventPipeEvent1Count", eventPipeResults.Event1Count, 2);
+ Assert.Equal("EventPipeEvent2Count", eventPipeResults.Event2Count, 0);
+ Assert.Equal("EventPipeEvent3Count", eventPipeResults.Event3Count, 2);
+
+ Console.WriteLine("\tEnd: Processing events from EventPipe file.\n");
+
+ Console.WriteLine("\tStart: Processing events from ETW file.");
+
+ using (var trace = new ETWTraceEventSource(etlFile.Path))
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ etwResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate ETW results.
+ etwResults.Print("ETW Results:");
+ Assert.Equal("EventPipeEvent1Count", etwResults.Event1Count, 0);
+ Assert.Equal("EventPipeEvent2Count", etwResults.Event2Count, 1);
+ Assert.Equal("EventPipeEvent3Count", etwResults.Event3Count, 1);
+
+ Console.WriteLine("\tEnd: Processing events from ETW file.");
+ }
+ }
+ }
+
+ private static void RoundTwo(string[] args)
+ {
+ using (var netPerfFile = NetPerfFile.Create(args))
+ {
+ using (var etlFile = EtlFile.Create(args))
+ {
+ Console.WriteLine("\tStart: Enable EventPipe.");
+ TraceControl.Enable(EventPipeGetConfig(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EventPipeKeyword, netPerfFile.Path));
+ Console.WriteLine("\tEnd: Enable EventPipe.\n");
+
+ Console.WriteLine("\tStart: Enable ETW.");
+ TraceEventSession etwSession = EnableETW(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EtwKeyword, etlFile.Path);
+ Console.WriteLine("\tEnd: Enable ETW.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable EventPipe.");
+ TraceControl.Disable();
+ Console.WriteLine("\tEnd: Disable EventPipe.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable ETW.");
+ DisableETW(etwSession);
+ Console.WriteLine("\tEnd: Disable ETW.\n");
+
+ Console.WriteLine("\tStart: Processing events from EventPipe file.");
+
+ EventResults eventPipeResults = new EventResults();
+ EventResults etwResults = new EventResults();
+
+ using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ eventPipeResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate EventPipe results.
+ eventPipeResults.Print("EventPipe Results:");
+ Assert.Equal("EventPipeEvent1Count", eventPipeResults.Event1Count, 1);
+ Assert.Equal("EventPipeEvent2Count", eventPipeResults.Event2Count, 0);
+ Assert.Equal("EventPipeEvent3Count", eventPipeResults.Event3Count, 1);
+
+ Console.WriteLine("\tEnd: Processing events from EventPipe file.\n");
+
+ Console.WriteLine("\tStart: Processing events from ETW file.");
+
+ using (var trace = new ETWTraceEventSource(etlFile.Path))
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ etwResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate ETW results.
+ etwResults.Print("ETW Results:");
+ Assert.Equal("EventPipeEvent1Count", etwResults.Event1Count, 0);
+ Assert.Equal("EventPipeEvent2Count", etwResults.Event2Count, 2);
+ Assert.Equal("EventPipeEvent3Count", etwResults.Event3Count, 2);
+
+ Console.WriteLine("\tEnd: Processing events from ETW file.");
+ }
+ }
+ }
+
+ static int Main(string[] args)
+ {
+ // This test can only run with elevation.
+ if (TraceEventSession.IsElevated() != true)
+ {
+ Console.WriteLine("Test skipped because the shell is not elevated.");
+ return 100;
+ }
+
+ RoundOne(args);
+ RoundTwo(args);
+
+
+ return 100;
+ }
+ }
+}
diff --git a/tests/src/tracing/eventsource/eventpipeandetw/eventpipeandetw.csproj b/tests/src/tracing/eventsource/eventpipeandetw/eventpipeandetw.csproj
new file mode 100644
index 0000000000..31c9137ca3
--- /dev/null
+++ b/tests/src/tracing/eventsource/eventpipeandetw/eventpipeandetw.csproj
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{8E3244CB-407F-4142-BAAB-E7A55901A5FA}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="EventPipeAndEtw.cs" />
+ <ProjectReference Include="../../common/common.csproj" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project> \ No newline at end of file
diff --git a/tests/src/tracing/eventsource/eventsourcetrace/EventSourceTrace.cs b/tests/src/tracing/eventsource/eventsourcetrace/EventSourceTrace.cs
new file mode 100644
index 0000000000..78d53ceb49
--- /dev/null
+++ b/tests/src/tracing/eventsource/eventsourcetrace/EventSourceTrace.cs
@@ -0,0 +1,112 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using Tracing.Tests.Common;
+using System.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing.Etlx;
+using Microsoft.Diagnostics.Tracing.Parsers;
+using Microsoft.Diagnostics.Tracing.Parsers.Clr;
+
+namespace Tracing.Tests
+{
+ [EventSource(Name = "SimpleEventSource")]
+ class SimpleEventSource : EventSource
+ {
+ public SimpleEventSource() : base(true) { }
+
+ [Event(1)]
+ internal void MathResult(int x, int y, int z, string formula) { this.WriteEvent(1, x, y, z, formula); }
+ }
+
+ class EventSourceTrace
+ {
+ private static int messageIterations = 10000;
+
+ public static TraceConfiguration GetConfig(EventSource eventSource, string outputFile="default.netperf")
+ {
+ // Setup the configuration values.
+ uint circularBufferMB = 1024; // 1 GB
+ uint level = 5;//(uint)EventLevel.Informational;
+ TimeSpan profSampleDelay = TimeSpan.FromMilliseconds(1);
+
+ // Create a new instance of EventPipeConfiguration.
+ TraceConfiguration config = new TraceConfiguration(outputFile, circularBufferMB);
+ // Setup the provider values.
+ // Public provider.
+ string providerName = eventSource.Name;
+ UInt64 keywords = 0xffffffffffffffff;
+
+ // Enable the provider.
+ config.EnableProvider(providerName, keywords, level);
+
+ // Set the sampling rate.
+ config.SetSamplingRate(profSampleDelay);
+
+ return config;
+ }
+
+ static int Main(string[] args)
+ {
+ bool pass = true;
+
+ using (SimpleEventSource eventSource = new SimpleEventSource())
+ {
+ using (var netPerfFile = NetPerfFile.Create(args))
+ {
+ Console.WriteLine("\tStart: Enable tracing.");
+ TraceControl.Enable(GetConfig(eventSource, netPerfFile.Path));
+ Console.WriteLine("\tEnd: Enable tracing.\n");
+
+ Console.WriteLine("\tStart: Messaging.");
+ // Send messages
+ // Use random numbers and addition as a simple, human readble checksum
+ Random generator = new Random();
+ for (int i = 0; i < messageIterations; i++)
+ {
+ int x = generator.Next(1, 1000);
+ int y = generator.Next(1, 1000);
+ string formula = String.Format("{0} + {1} = {2}", x, y, x + y);
+
+ eventSource.MathResult(x, y, x + y, formula);
+ }
+ Console.WriteLine("\tEnd: Messaging.\n");
+
+ Console.WriteLine("\tStart: Disable tracing.");
+ TraceControl.Disable();
+ Console.WriteLine("\tEnd: Disable tracing.\n");
+
+ Console.WriteLine("\tStart: Processing events from file.");
+ int msgCount = 0;
+ using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
+ {
+ var names = new HashSet<string>();
+
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ if (!names.Contains(data.ProviderName))
+ {
+ Console.WriteLine("\t{0}", data.ProviderName);
+ names.Add(data.ProviderName);
+ }
+
+ if (data.ProviderName == "SimpleEventSource")
+ {
+ msgCount += 1;
+ }
+ };
+
+ trace.Process();
+ }
+ Console.WriteLine("\tEnd: Processing events from file.\n");
+
+ Console.WriteLine("\tProcessed {0} events from EventSource", msgCount);
+
+ pass &= msgCount == messageIterations;
+ }
+ }
+
+ return pass ? 100 : 0;
+ }
+ }
+}
diff --git a/tests/src/tracing/eventsourcetrace/eventsourcetrace.csproj b/tests/src/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj
index 0bf6d8fd39..83415240c4 100644
--- a/tests/src/tracing/eventsourcetrace/eventsourcetrace.csproj
+++ b/tests/src/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj
@@ -24,7 +24,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="EventSourceTrace.cs" />
- <ProjectReference Include="../common/common.csproj" />
+ <ProjectReference Include="../../common/common.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project> \ No newline at end of file
diff --git a/tests/src/tracing/eventsourcetrace/EventSourceTrace.cs b/tests/src/tracing/eventsourcetrace/EventSourceTrace.cs
deleted file mode 100644
index 3c9135927c..0000000000
--- a/tests/src/tracing/eventsourcetrace/EventSourceTrace.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using Tracing.Tests.Common;
-using System.Diagnostics.Tracing;
-using Microsoft.Diagnostics.Tracing;
-using Microsoft.Diagnostics.Tracing.Etlx;
-using Microsoft.Diagnostics.Tracing.Parsers;
-using Microsoft.Diagnostics.Tracing.Parsers.Clr;
-
-namespace Tracing.Tests
-{
- [EventSource(Name = "SimpleEventSource")]
- class SimpleEventSource : EventSource
- {
- public SimpleEventSource() : base(true) { }
-
- [Event(1)]
- internal void MathResult(int x, int y, int z, string formula) { this.WriteEvent(1, x, y, z, formula); }
- }
-
- class EventSourceTrace
- {
- private static int messageIterations = 10000;
-
- public static TraceConfiguration GetConfig(EventSource eventSource, string outputFile="default.netperf")
- {
- // Setup the configuration values.
- uint circularBufferMB = 1024; // 1 GB
- uint level = 5;//(uint)EventLevel.Informational;
- TimeSpan profSampleDelay = TimeSpan.FromMilliseconds(1);
-
- // Create a new instance of EventPipeConfiguration.
- TraceConfiguration config = new TraceConfiguration(outputFile, circularBufferMB);
- // Setup the provider values.
- // Public provider.
- string providerName = eventSource.Name;
- UInt64 keywords = 0xffffffffffffffff;
-
- // Enable the provider.
- config.EnableProvider(providerName, keywords, level);
-
- // Set the sampling rate.
- config.SetSamplingRate(profSampleDelay);
-
- return config;
- }
-
- static int Main(string[] args)
- {
- bool pass = true;
-
- SimpleEventSource eventSource = new SimpleEventSource();
-
- using (var netPerfFile = NetPerfFile.Create(args))
- {
- Console.WriteLine("\tStart: Enable tracing.");
- TraceControl.Enable(GetConfig(eventSource, netPerfFile.Path));
- Console.WriteLine("\tEnd: Enable tracing.\n");
-
- Console.WriteLine("\tStart: Messaging.");
- // Send messages
- // Use random numbers and addition as a simple, human readble checksum
- Random generator = new Random();
- for(int i=0; i<messageIterations; i++)
- {
- int x = generator.Next(1,1000);
- int y = generator.Next(1,1000);
- string formula = String.Format("{0} + {1} = {2}", x, y, x+y);
-
- eventSource.MathResult(x, y, x+y, formula);
- }
- Console.WriteLine("\tEnd: Messaging.\n");
-
- Console.WriteLine("\tStart: Disable tracing.");
- TraceControl.Disable();
- Console.WriteLine("\tEnd: Disable tracing.\n");
-
- Console.WriteLine("\tStart: Processing events from file.");
- int msgCount = 0;
- using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
- {
- var names = new HashSet<string>();
-
- trace.Dynamic.All += delegate(TraceEvent data)
- {
- if (!names.Contains(data.ProviderName))
- {
- Console.WriteLine("\t{0}", data.ProviderName);
- names.Add(data.ProviderName);
- }
-
- if (data.ProviderName == "SimpleEventSource")
- {
- msgCount += 1;
- }
- };
-
- trace.Process();
- }
- Console.WriteLine("\tEnd: Processing events from file.\n");
-
- Console.WriteLine("\tProcessed {0} events from EventSource", msgCount);
-
- pass &= msgCount == messageIterations;
- }
-
- return pass ? 100 : 0;
- }
- }
-}
diff --git a/tests/testsUnsupportedOutsideWindows.txt b/tests/testsUnsupportedOutsideWindows.txt
index 6e770f733b..e9a7c6632b 100644
--- a/tests/testsUnsupportedOutsideWindows.txt
+++ b/tests/testsUnsupportedOutsideWindows.txt
@@ -340,3 +340,4 @@ JIT/Regression/VS-ia64-JIT/V2.0-RTM/b286991/b286991/b286991.sh
managed/Compilation/Compilation/Compilation.sh
Regressions/coreclr/0584/Test584/Test584.sh
Interop/SizeConst/SizeConstTest/SizeConstTest.sh
+tracing/eventsource/eventpipeandetw/eventpipeandetw/eventpipeandetw.sh