Flow EventSources to EventPipe on Windows (#18217)
authorBrian Robbins <brianrob@microsoft.com>
Mon, 4 Jun 2018 17:26:53 +0000 (10:26 -0700)
committerGitHub <noreply@github.com>
Mon, 4 Jun 2018 17:26:53 +0000 (10:26 -0700)
17 files changed:
clr.coreclr.props
src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs
src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs
src/vm/eventpipe.cpp
src/vm/eventpipeconfiguration.cpp
src/vm/eventpipeeventsource.cpp
src/vm/eventpipeprovider.cpp
tests/issues.targets
tests/src/tracing/common/EtlFile.cs [new file with mode: 0644]
tests/src/tracing/common/common.csproj
tests/src/tracing/eventsource/eventpipeandetw/EventPipeAndEtw.cs [new file with mode: 0644]
tests/src/tracing/eventsource/eventpipeandetw/eventpipeandetw.csproj [new file with mode: 0644]
tests/src/tracing/eventsource/eventsourcetrace/EventSourceTrace.cs [new file with mode: 0644]
tests/src/tracing/eventsource/eventsourcetrace/eventsourcetrace.csproj [moved from tests/src/tracing/eventsourcetrace/eventsourcetrace.csproj with 95% similarity]
tests/src/tracing/eventsourcetrace/EventSourceTrace.cs [deleted file]
tests/testsUnsupportedOutsideWindows.txt

index 029ddca..8b546c6 100644 (file)
@@ -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'">
index d412e6b..7ad7f0c 100644 (file)
@@ -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
 }
 
index 6992dce..8376c49 100644 (file)
@@ -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;
index 1793a16..0bf6657 100644 (file)
@@ -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;
index cad3093..fb112db 100644 (file)
@@ -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)
index d787956..74d9f44 100644 (file)
@@ -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.
index 1a5cf2a..a115af7 100644 (file)
@@ -20,7 +20,7 @@ EventPipeEventSource::EventPipeEventSource()
     CONTRACTL
     {
         THROWS;
-        GC_NOTRIGGER;
+        GC_TRIGGERS;
         MODE_ANY;
     }
     CONTRACTL_END;
index 3e82706..c2a0169 100644 (file)
@@ -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());
     }
index 2b9b272..aed787d 100644 (file)
         <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 (file)
index 0000000..f476ce2
--- /dev/null
@@ -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);
+        }
+    }
+}
index 0fe8d0f..32a2108 100644 (file)
@@ -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 (file)
index 0000000..71ef013
--- /dev/null
@@ -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 (file)
index 0000000..31c9137
--- /dev/null
@@ -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 (file)
index 0000000..78d53ce
--- /dev/null
@@ -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;
+        }
+    }
+}
@@ -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 (file)
index 3c91359..0000000
+++ /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;
-        }
-    }
-}
index 6e770f7..e9a7c66 100644 (file)
@@ -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