Skip to content

Commit d6d76cb

Browse files
Make ETW event registering AOT friendly.
1 parent 7d51af7 commit d6d76cb

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

mcs/class/corlib/corlib-net_4_x.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@
292292
<Compile Include="..\referencesource\mscorlib\system\diagnostics\conditionalattribute.cs" />
293293
<Compile Include="..\referencesource\mscorlib\system\diagnostics\contracts\contracts.cs" />
294294
<Compile Include="..\referencesource\mscorlib\system\diagnostics\contracts\contractsbcl.cs" />
295-
<Compile Include="..\referencesource\mscorlib\system\diagnostics\debuggerattributes.cs" /> <Compile Include="..\referencesource\mscorlib\system\diagnostics\eventing\activitytracker.cs" />
295+
<Compile Include="..\referencesource\mscorlib\system\diagnostics\debuggerattributes.cs" />
296+
<Compile Include="..\referencesource\mscorlib\system\diagnostics\eventing\activitytracker.cs" />
296297
<Compile Include="..\referencesource\mscorlib\system\diagnostics\eventing\eventactivityoptions.cs" />
297298
<Compile Include="..\referencesource\mscorlib\system\diagnostics\eventing\eventdescriptor.cs" />
298299
<Compile Include="..\referencesource\mscorlib\system\diagnostics\eventing\eventprovider.cs" />

mcs/class/referencesource/mscorlib/system/diagnostics/eventing/eventprovider.cs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ internal SessionInfo(int sessionIdBit_, int etwSessionId_)
7878

7979
[SecurityCritical]
8080
UnsafeNativeMethods.ManifestEtw.EtwEnableCallback m_etwCallback; // Trace Callback function
81+
GCHandle m_thisGCHandle;
8182
private long m_regHandle; // Trace Registration Handle
8283
private byte m_level; // Tracing Level
8384
private long m_anyKeywordMask; // Trace Enable Flags
@@ -149,13 +150,25 @@ internal EventProvider()
149150
internal unsafe void Register(Guid providerGuid)
150151
{
151152
m_providerId = providerGuid;
152-
uint status;
153153
m_etwCallback = new UnsafeNativeMethods.ManifestEtw.EtwEnableCallback(EtwEnableCallBack);
154154

155-
status = EventRegister(ref m_providerId, m_etwCallback);
156-
if (status != 0)
155+
if (m_thisGCHandle.IsAllocated)
156+
m_thisGCHandle.Free();
157+
158+
m_thisGCHandle = GCHandle.Alloc(this);
159+
160+
try
161+
{
162+
var status = UnsafeNativeMethods.ManifestEtw.EventRegister(ref providerGuid, m_etwCallback, GCHandle.ToIntPtr(m_thisGCHandle).ToPointer(), ref m_regHandle);
163+
if (status != 0)
164+
{
165+
throw new ArgumentException(Win32Native.GetMessage(unchecked((int)status)));
166+
}
167+
}
168+
catch
157169
{
158-
throw new ArgumentException(Win32Native.GetMessage(unchecked((int)status)));
170+
m_thisGCHandle.Free();
171+
throw;
159172
}
160173
}
161174

@@ -264,22 +277,44 @@ private unsafe void Deregister()
264277
{
265278
EventUnregister();
266279
m_regHandle = 0;
280+
m_thisGCHandle.Free();
267281
}
268282
}
269283

284+
[AttributeUsage(AttributeTargets.Method)]
285+
private sealed class MonoPInvokeCallbackAttribute : Attribute
286+
{
287+
public MonoPInvokeCallbackAttribute(Type t)
288+
{
289+
}
290+
}
291+
292+
[MonoPInvokeCallback(typeof(UnsafeNativeMethods.ManifestEtw.EtwEnableCallback))]
293+
unsafe static void EtwEnableCallBack(
294+
[In] ref System.Guid sourceId,
295+
[In] int controlCode,
296+
[In] byte setLevel,
297+
[In] long anyKeyword,
298+
[In] long allKeyword,
299+
[In] UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
300+
[In] void* callbackContext
301+
)
302+
{
303+
var _this = (EventProvider)GCHandle.FromIntPtr(new IntPtr(callbackContext)).Target;
304+
_this.EtwEnableCallBackImpl(controlCode, setLevel, anyKeyword, allKeyword, filterData);
305+
}
306+
270307
// <SecurityKernel Critical="True" Ring="0">
271308
// <UsesUnsafeCode Name="Parameter filterData of type: Void*" />
272309
// <UsesUnsafeCode Name="Parameter callbackContext of type: Void*" />
273310
// </SecurityKernel>
274311
[System.Security.SecurityCritical]
275-
unsafe void EtwEnableCallBack(
276-
[In] ref System.Guid sourceId,
312+
unsafe void EtwEnableCallBackImpl(
277313
[In] int controlCode,
278314
[In] byte setLevel,
279315
[In] long anyKeyword,
280316
[In] long allKeyword,
281-
[In] UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
282-
[In] void* callbackContext
317+
[In] UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData
283318
)
284319
{
285320
// This is an optional callback API. We will therefore ignore any failures that happen as a
@@ -539,7 +574,7 @@ private unsafe bool GetDataFromController(int etwSessionId,
539574
dataStart = 0;
540575
if (filterData == null)
541576
{
542-
#if !ES_BUILD_PCL
577+
#if !ES_BUILD_PCL && !MONO
543578
string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}";
544579
if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) == 8)
545580
regKey = @"HKEY_LOCAL_MACHINE\Software" + @"\Wow6432Node" + regKey;
@@ -1161,13 +1196,6 @@ internal unsafe bool WriteEventRaw(
11611196

11621197
// These are look-alikes to the Manifest based ETW OS APIs that have been shimmed to work
11631198
// either with Manifest ETW or Classic ETW (if Manifest based ETW is not available).
1164-
[SecurityCritical]
1165-
private unsafe uint EventRegister(ref Guid providerId, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback)
1166-
{
1167-
m_providerId = providerId;
1168-
m_etwCallback = enableCallback;
1169-
return UnsafeNativeMethods.ManifestEtw.EventRegister(ref providerId, enableCallback, null, ref m_regHandle);
1170-
}
11711199

11721200
[SecurityCritical]
11731201
private uint EventUnregister()

0 commit comments

Comments
 (0)