Skip to content

Commit 59c8d55

Browse files
Put LogExceptionThrown on the NativeRuntimeEventSource plan (#118729)
This unifies `LogExceptionThrown` with the other eventing that is implemented in the native runtime (threads/threadpool). Noticed this in #107418 (comment) where we run an awful lot of code in situations where event source is not even enabled.
1 parent 2516978 commit 59c8d55

11 files changed

+67
-31
lines changed

src/coreclr/nativeaot/Runtime/disabledruntimeeventinternal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogThreadPoolIOPack(void * Nati
8080
{
8181
}
8282

83-
EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult)
83+
EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult, uint16_t flags, uint16_t ClrInstanceID)
8484
{
8585
}
8686

src/coreclr/nativeaot/Runtime/runtimeeventinternal.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogThreadPoolIOPack(void * Nati
9090
FireEtwThreadPoolIOPack(NativeOverlapped, Overlapped, ClrInstanceID);
9191
}
9292

93-
EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult)
93+
EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult, uint16_t flags, uint16_t ClrInstanceID)
9494
{
9595
FireEtwExceptionThrown_V1(exceptionTypeName,
9696
exceptionMessage,
9797
faultingIP,
9898
hresult,
99-
0,
100-
GetClrInstanceId());
99+
flags,
100+
ClrInstanceID);
101101
}
102102

103103
EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogWaitHandleWaitStart(uint8_t WaitSource, intptr_t AssociatedObjectID, uint16_t ClrInstanceID)

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.NativeAot.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections;
55
using System.Diagnostics;
66
using System.Diagnostics.CodeAnalysis;
7+
using System.Diagnostics.Tracing;
78
using System.Runtime;
89
using System.Runtime.CompilerServices;
910
using System.Runtime.InteropServices;
@@ -136,17 +137,13 @@ private static void AppendExceptionStackFrame(object exceptionObj, IntPtr IP, in
136137
ex.AppendStackIP(IP, isFirstRethrowFrame);
137138

138139
#if FEATURE_PERFTRACING
139-
if (isFirstFrame)
140+
if (isFirstFrame && NativeRuntimeEventSource.Log.IsEnabled())
140141
{
141142
string typeName = !fatalOutOfMemory ? ex.GetType().ToString() : "System.OutOfMemoryException";
142143
string message = !fatalOutOfMemory ? ex.Message :
143144
"Insufficient memory to continue the execution of the program.";
144145

145-
unsafe
146-
{
147-
fixed (char* exceptionTypeName = typeName, exceptionMessage = message)
148-
RuntimeImports.NativeRuntimeEventSource_LogExceptionThrown(exceptionTypeName, exceptionMessage, IP, ex.HResult);
149-
}
146+
NativeRuntimeEventSource.Log.ExceptionThrown_V1(typeName, message, IP, (uint)ex.HResult, 0);
150147
}
151148
#endif
152149
}

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -673,11 +673,6 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe
673673
[RuntimeImport(RuntimeLibrary, "RhUnregisterForGCReporting")]
674674
internal static extern unsafe void RhUnregisterForGCReporting(GCFrameRegistration* pRegistration);
675675

676-
#if FEATURE_PERFTRACING
677-
[LibraryImport(RuntimeLibrary)]
678-
internal static unsafe partial void NativeRuntimeEventSource_LogExceptionThrown(char* exceptionTypeName, char* exceptionMessage, IntPtr faultingIP, int hresult);
679-
#endif // FEATURE_PERFTRACING
680-
681676
//
682677
// Interlocked helpers
683678
//

src/libraries/System.Private.CoreLib/gen/NativeRuntimeEventSourceGenerator.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,13 @@ private static bool IsEventManuallyHandled(string eventName)
415415

416416
private static readonly List<string> manuallyHandledEventSymbols =
417417
[
418-
// Some threading events are defined manually in NativeRuntimeEventSource.Threading.cs
418+
// Some threading events are defined manually in NativeRuntimeEventSource.Threading.[NativeSinks].cs
419419
"ThreadPool",
420420
"Contention",
421-
"WaitHandle"
421+
"WaitHandle",
422+
423+
// Exception event defined manually in NativeRuntimeEventSource.Exceptions.NativeSinks.cs
424+
"ExceptionThrown_V1",
422425
];
423426
}
424427
}

src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,8 @@
15851585
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\IncrementingEventCounter.cs" />
15861586
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\IncrementingPollingCounter.cs" />
15871587
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\NativeRuntimeEventSource.cs" />
1588+
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\NativeRuntimeEventSource.Exceptions.NativeSinks.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
1589+
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\NativeRuntimeEventSource.Exceptions.NativeSinks.Internal.cs" Condition="'$(FeaturePerfTracing)' == 'true' and '$(FeatureNativeAot)' == 'true'" />
15881590
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\NativeRuntimeEventSource.Threading.cs" Condition="'$(FeaturePerfTracing)' != 'true'" />
15891591
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\NativeRuntimeEventSource.Threading.NativeSinks.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
15901592
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\NativeRuntimeEventSource.Threading.NativeSinks.Internal.cs" Condition="'$(FeaturePerfTracing)' == 'true' and '$(FeatureMono)' != 'true'" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.CompilerServices;
5+
using System.Runtime.InteropServices;
6+
7+
namespace System.Diagnostics.Tracing
8+
{
9+
internal sealed partial class NativeRuntimeEventSource : EventSource
10+
{
11+
[NonEvent]
12+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "NativeRuntimeEventSource_LogExceptionThrown", StringMarshalling = StringMarshalling.Utf16)]
13+
private static unsafe partial void LogExceptionThrown(string exceptionTypeName, string exceptionMessage, IntPtr faultingIP, uint hresult, ushort flags, ushort ClrInstanceID);
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Diagnostics.CodeAnalysis;
5+
using System.Runtime.CompilerServices;
6+
using System.Threading;
7+
8+
namespace System.Diagnostics.Tracing
9+
{
10+
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "NativeRuntimeEventSource is a special case where event methods don't use WriteEvent/WriteEventCore but still need to be instance methods.")]
11+
internal sealed partial class NativeRuntimeEventSource : EventSource
12+
{
13+
[Event(80, Version = 1, Level = EventLevel.Error, Keywords = Keywords.ExceptionKeyword | Keywords.MonitoringKeyword)]
14+
public void ExceptionThrown_V1(string ExceptionType, string ExceptionMessage, IntPtr ExceptionEIP, uint ExceptionHRESULT, ushort ExceptionFlags, ushort ClrInstanceID = DefaultClrInstanceId)
15+
{
16+
#if NATIVEAOT
17+
if (!IsEnabled(EventLevel.Error, Keywords.ExceptionKeyword | Keywords.MonitoringKeyword))
18+
{
19+
return;
20+
}
21+
LogExceptionThrown(ExceptionType, ExceptionMessage, ExceptionEIP, ExceptionHRESULT, ExceptionFlags, ClrInstanceID);
22+
#else
23+
// QCall not implemented elsewhere
24+
throw new NotImplementedException();
25+
#endif
26+
}
27+
}
28+
}

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.Internal.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
namespace System.Diagnostics.Tracing
88
{
9-
// This is part of the NativeRuntimeEventsource, which is the managed version of the Microsoft-Windows-DotNETRuntime provider.
10-
// It contains the runtime specific interop to native event sinks.
119
internal sealed partial class NativeRuntimeEventSource : EventSource
1210
{
1311
[NonEvent]

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@
77

88
namespace System.Diagnostics.Tracing
99
{
10-
// This is part of the NativeRuntimeEventsource, which is the managed version of the Microsoft-Windows-DotNETRuntime provider.
11-
// It contains the handwritten implementation of threading events.
12-
// The events here do not call into the typical WriteEvent* APIs unlike most EventSources because that results in the
13-
// events to be forwarded to EventListeners twice, once directly from the managed WriteEvent API, and another time
14-
// from the mechanism in NativeRuntimeEventSource.ProcessEvents that forwards native runtime events to EventListeners.
15-
// To prevent this, these events call directly into QCalls provided by the runtime (refer to NativeRuntimeEventSource.cs) which call
16-
// FireEtw* methods auto-generated from ClrEtwAll.man. This ensures that corresponding event sinks are being used
17-
// for the native platform.
18-
// For implementation of these events not supporting native sinks, refer to NativeRuntimeEventSource.Threading.cs.
1910
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "NativeRuntimeEventSource is a special case where event methods don't use WriteEvent/WriteEventCore but still need to be instance methods.")]
2011
internal sealed partial class NativeRuntimeEventSource : EventSource
2112
{

0 commit comments

Comments
 (0)