From: Brian Robbins Date: Sat, 17 Mar 2018 22:18:25 +0000 (-0700) Subject: Fix EventSource Test Failures in CoreFX (#16999) X-Git-Tag: accepted/tizen/unified/20190422.045933~2606 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8a5464f322a9f01e4da37c349359836af548b3c0;p=platform%2Fupstream%2Fcoreclr.git Fix EventSource Test Failures in CoreFX (#16999) --- diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs index 751b0fd..21e03e0 100644 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs @@ -623,6 +623,7 @@ namespace System.Diagnostics.Tracing continue; byte[] metadata = EventPipeMetadataGenerator.Instance.GenerateEventMetadata(m_eventData[i]); + uint metadataLength = (metadata != null) ? (uint)metadata.Length : 0; string eventName = m_eventData[i].Name; Int64 keywords = m_eventData[i].Descriptor.Keywords; @@ -638,7 +639,7 @@ namespace System.Diagnostics.Tracing eventVersion, level, pMetadata, - (uint)metadata.Length); + metadataLength); Debug.Assert(eventHandle != IntPtr.Zero); m_eventData[i].EventHandle = eventHandle; diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs index cf8379f..b1c7327 100644 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using Interlocked = System.Threading.Interlocked; #if ES_BUILD_STANDALONE @@ -42,7 +43,6 @@ namespace System.Diagnostics.Tracing internal readonly byte[] nameMetadata; #if FEATURE_PERFTRACING - private IntPtr eventHandle = IntPtr.Zero; private readonly object eventHandleCreationLock = new object(); #endif @@ -82,13 +82,14 @@ namespace System.Diagnostics.Tracing } #if FEATURE_PERFTRACING - public IntPtr GetOrCreateEventHandle(EventProvider provider, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes) + public IntPtr GetOrCreateEventHandle(EventProvider provider, ConcurrentDictionary eventHandleMap, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes) { - if (eventHandle == IntPtr.Zero) + IntPtr eventHandle = IntPtr.Zero; + if(!eventHandleMap.TryGetValue(descriptor.EventId, out eventHandle)) { lock (eventHandleCreationLock) { - if (eventHandle == IntPtr.Zero) + if (!eventHandleMap.TryGetValue(descriptor.EventId, out eventHandle)) { byte[] metadataBlob = EventPipeMetadataGenerator.Instance.GenerateEventMetadata( descriptor.EventId, @@ -97,6 +98,7 @@ namespace System.Diagnostics.Tracing (EventLevel)descriptor.Level, descriptor.Version, eventTypes); + uint metadataLength = (metadataBlob != null) ? (uint)metadataBlob.Length : 0; unsafe { @@ -110,7 +112,7 @@ namespace System.Diagnostics.Tracing descriptor.Version, descriptor.Level, pMetadataBlob, - (uint)metadataBlob.Length); + metadataLength); } } } diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs index 4ebe3a3..ccdc8bf 100644 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs +++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs @@ -24,6 +24,7 @@ using System.Resources; using System.Runtime.InteropServices; using System.Security; using System.Collections.ObjectModel; +using System.Collections.Concurrent; #if !ES_BUILD_AGAINST_DOTNET_V35 using Contract = System.Diagnostics.Contracts.Contract; @@ -47,6 +48,10 @@ namespace System.Diagnostics.Tracing private byte[] providerMetadata; #endif +#if FEATURE_PERFTRACING + private ConcurrentDictionary m_eventHandleMap = new ConcurrentDictionary(); +#endif + /// /// Construct an EventSource with a given name for non-contract based events (e.g. those using the Write() API). /// @@ -432,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, descriptor, eventTypes); + IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes); Debug.Assert(eventHandle != IntPtr.Zero); #else IntPtr eventHandle = IntPtr.Zero; @@ -547,7 +552,7 @@ namespace System.Diagnostics.Tracing } #if FEATURE_PERFTRACING - IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, descriptor, eventTypes); + IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes); Debug.Assert(eventHandle != IntPtr.Zero); #else IntPtr eventHandle = IntPtr.Zero; @@ -616,7 +621,7 @@ namespace System.Diagnostics.Tracing } #if FEATURE_PERFTRACING - IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, descriptor, eventTypes); + IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes); Debug.Assert(eventHandle != IntPtr.Zero); #else IntPtr eventHandle = IntPtr.Zero; diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventPipeMetadataGenerator.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventPipeMetadataGenerator.cs index a2b6095..d18610d 100644 --- a/src/mscorlib/src/System/Diagnostics/Eventing/EventPipeMetadataGenerator.cs +++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventPipeMetadataGenerator.cs @@ -65,48 +65,59 @@ namespace System.Diagnostics.Tracing uint version, EventParameterInfo[] parameters) { - // eventID : 4 bytes - // eventName : (eventName.Length + 1) * 2 bytes - // keywords : 8 bytes - // eventVersion : 4 bytes - // level : 4 bytes - // parameterCount : 4 bytes - uint metadataLength = 24 + ((uint)eventName.Length + 1) * 2; - - // Check for an empty payload. - // Write calls with no arguments by convention have a parameter of - // type NullTypeInfo which is serialized as nothing. - if((parameters.Length == 1) && (parameters[0].ParameterType == typeof(EmptyStruct))) + byte[] metadata = null; + try { - parameters = Array.Empty(); - } - - // Increase the metadataLength for parameters. - foreach (var parameter in parameters) - { - metadataLength = metadataLength + parameter.GetMetadataLength(); - } - - byte[] metadata = new byte[metadataLength]; - - // Write metadata: eventID, eventName, keywords, eventVersion, level, parameterCount, param1 type, param1 name... - fixed (byte *pMetadata = metadata) - { - uint offset = 0; - WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)eventId); - fixed(char *pEventName = eventName) + // eventID : 4 bytes + // eventName : (eventName.Length + 1) * 2 bytes + // keywords : 8 bytes + // eventVersion : 4 bytes + // level : 4 bytes + // parameterCount : 4 bytes + uint metadataLength = 24 + ((uint)eventName.Length + 1) * 2; + + // Check for an empty payload. + // Write calls with no arguments by convention have a parameter of + // type NullTypeInfo which is serialized as nothing. + if ((parameters.Length == 1) && (parameters[0].ParameterType == typeof(EmptyStruct))) { - WriteToBuffer(pMetadata, metadataLength, ref offset, (byte *)pEventName, ((uint)eventName.Length + 1) * 2); + parameters = Array.Empty(); } - WriteToBuffer(pMetadata, metadataLength, ref offset, keywords); - WriteToBuffer(pMetadata, metadataLength, ref offset, version); - WriteToBuffer(pMetadata, metadataLength, ref offset, level); - WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)parameters.Length); + + // Increase the metadataLength for parameters. foreach (var parameter in parameters) { - parameter.GenerateMetadata(pMetadata, ref offset, metadataLength); + metadataLength = metadataLength + parameter.GetMetadataLength(); + } + + metadata = new byte[metadataLength]; + + // Write metadata: eventID, eventName, keywords, eventVersion, level, parameterCount, param1 type, param1 name... + fixed (byte* pMetadata = metadata) + { + uint offset = 0; + WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)eventId); + fixed (char* pEventName = eventName) + { + WriteToBuffer(pMetadata, metadataLength, ref offset, (byte*)pEventName, ((uint)eventName.Length + 1) * 2); + } + WriteToBuffer(pMetadata, metadataLength, ref offset, keywords); + WriteToBuffer(pMetadata, metadataLength, ref offset, version); + WriteToBuffer(pMetadata, metadataLength, ref offset, level); + WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)parameters.Length); + foreach (var parameter in parameters) + { + parameter.GenerateMetadata(pMetadata, ref offset, metadataLength); + } + Debug.Assert(metadataLength == offset); } - Debug.Assert(metadataLength == offset); + } + catch + { + // If a failure occurs during metadata generation, make sure that we don't return + // malformed metadata. Instead, return a null metadata blob. + // Consumers can either build in knowledge of the event or skip it entirely. + metadata = null; } return metadata; @@ -262,7 +273,12 @@ namespace System.Diagnostics.Tracing // TypeCode : 4 bytes // PropertyName : NULL-terminated string TypeCode typeCode = GetTypeCodeExtended(property.typeInfo.DataType); - Debug.Assert(typeCode != TypeCode.Object); + + // EventPipe does not support this type. Throw, which will cause no metadata to be registered for this event. + if(typeCode == TypeCode.Object) + { + throw new NotSupportedException(); + } // Write the type code. EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)typeCode); diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp index ab13738..910dee5 100644 --- a/src/vm/eventpipe.cpp +++ b/src/vm/eventpipe.cpp @@ -958,7 +958,6 @@ INT_PTR QCALLTYPE EventPipeInternal::DefineEvent( BEGIN_QCALL; _ASSERTE(provHandle != NULL); - _ASSERTE(pMetadata != NULL); EventPipeProvider *pProvider = reinterpret_cast(provHandle); pEvent = pProvider->AddEvent(eventID, keywords, eventVersion, (EventPipeEventLevel)level, (BYTE *)pMetadata, metadataLength); _ASSERTE(pEvent != NULL);