diff options
author | Brian Robbins <brianrob@microsoft.com> | 2018-06-04 10:26:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-04 10:26:53 -0700 |
commit | 6238c4fffd9c47c8b917af611c6609ef160d7bf8 (patch) | |
tree | d4d5761160cb3782814ca26020741a51d7b79dea | |
parent | de586767f51432e5d89f6fcffee07c488fdeeb7b (diff) | |
download | coreclr-6238c4fffd9c47c8b917af611c6609ef160d7bf8.tar.gz coreclr-6238c4fffd9c47c8b917af611c6609ef160d7bf8.tar.bz2 coreclr-6238c4fffd9c47c8b917af611c6609ef160d7bf8.zip |
Flow EventSources to EventPipe on Windows (#18217)
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 |