Skip to content

Commit 8502406

Browse files
committedJan 9, 2023
Maanged to Native hooks
1 parent 179585e commit 8502406

File tree

6 files changed

+374
-0
lines changed

6 files changed

+374
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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+
#include "common.h"
5+
#include "eventpipeadapter.h"
6+
7+
#ifdef FEATURE_PERFTRACING
8+
9+
struct EventPipeEventInstanceData
10+
{
11+
void *ProviderID;
12+
unsigned int EventID;
13+
unsigned int ThreadID;
14+
LARGE_INTEGER TimeStamp;
15+
GUID ActivityId;
16+
GUID RelatedActivityId;
17+
const uint8_t *Payload;
18+
unsigned int PayloadLength;
19+
};
20+
21+
struct EventPipeSessionInfo
22+
{
23+
FILETIME StartTimeAsUTCFileTime;
24+
LARGE_INTEGER StartTimeStamp;
25+
LARGE_INTEGER TimeStampFrequency;
26+
};
27+
28+
EXTERN_C NATIVEAOT_API uint64_t __cdecl RhEventPipeInternal_Enable(
29+
LPCWSTR outputFile,
30+
EventPipeSerializationFormat format,
31+
uint32_t circularBufferSizeInMB,
32+
/* COR_PRF_EVENTPIPE_PROVIDER_CONFIG */ const void * pProviders,
33+
uint32_t numProviders)
34+
{
35+
__debugbreak();
36+
return 0;
37+
}
38+
39+
EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_Disable(uint64_t sessionID)
40+
{
41+
__debugbreak();
42+
}
43+
44+
EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_CreateProvider(
45+
LPCWSTR providerName,
46+
EventPipeCallback pCallbackFunc,
47+
void* pCallbackContext)
48+
{
49+
EventPipeProvider* pProvider = EventPipeAdapter::CreateProvider(providerName, pCallbackFunc, pCallbackContext);
50+
return reinterpret_cast<intptr_t>(pProvider);
51+
}
52+
53+
EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_DefineEvent(
54+
intptr_t provHandle,
55+
uint32_t eventID,
56+
int64_t keywords,
57+
uint32_t eventVersion,
58+
uint32_t level,
59+
void *pMetadata,
60+
uint32_t metadataLength)
61+
{
62+
EventPipeEvent *pEvent = NULL;
63+
64+
_ASSERTE(provHandle != 0);
65+
EventPipeProvider *pProvider = reinterpret_cast<EventPipeProvider *>(provHandle);
66+
pEvent = EventPipeAdapter::AddEvent(pProvider, eventID, keywords, eventVersion, (EventPipeEventLevel)level, /* needStack = */ true, (uint8_t *)pMetadata, metadataLength);
67+
_ASSERTE(pEvent != NULL);
68+
69+
return reinterpret_cast<intptr_t>(pEvent);
70+
}
71+
72+
EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_GetProvider(LPCWSTR providerName)
73+
{
74+
__debugbreak();
75+
return 0;
76+
}
77+
78+
EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_DeleteProvider(intptr_t provHandle)
79+
{
80+
if (provHandle != 0)
81+
{
82+
EventPipeProvider *pProvider = reinterpret_cast<EventPipeProvider *>(provHandle);
83+
EventPipeAdapter::DeleteProvider(pProvider);
84+
}
85+
}
86+
87+
EXTERN_C NATIVEAOT_API int __cdecl RhEventPipeInternal_EventActivityIdControl(uint32_t controlCode, GUID *pActivityId)
88+
{
89+
__debugbreak();
90+
return 0;
91+
}
92+
93+
EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_WriteEventData(
94+
intptr_t eventHandle,
95+
EventData *pEventData,
96+
uint32_t eventDataCount,
97+
const GUID * pActivityId,
98+
const GUID * pRelatedActivityId)
99+
{
100+
_ASSERTE(eventHandle != 0);
101+
EventPipeEvent *pEvent = reinterpret_cast<EventPipeEvent *>(eventHandle);
102+
EventPipeAdapter::WriteEvent(pEvent, pEventData, eventDataCount, pActivityId, pRelatedActivityId);
103+
}
104+
105+
EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetSessionInfo(uint64_t sessionID, EventPipeSessionInfo *pSessionInfo)
106+
{
107+
__debugbreak();
108+
return FALSE;
109+
}
110+
111+
EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetNextEvent(uint64_t sessionID, EventPipeEventInstanceData *pInstance)
112+
{
113+
__debugbreak();
114+
return FALSE;
115+
}
116+
117+
EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_SignalSession(uint64_t sessionID)
118+
{
119+
__debugbreak();
120+
return FALSE;
121+
}
122+
123+
EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_WaitForSessionSignal(uint64_t sessionID, int32_t timeoutMs)
124+
{
125+
__debugbreak();
126+
return FALSE;
127+
}
128+
129+
#endif // FEATURE_PERFTRACING

‎src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
<Compile Include="System\Diagnostics\StackFrame.NativeAot.cs" />
183183
<Compile Include="System\Diagnostics\StackFrameExtensions.cs" />
184184
<Compile Include="System\Diagnostics\StackTrace.NativeAot.cs" />
185+
<Compile Include="System\Diagnostics\Eventing\EventPipe.NativeAot.cs" />
185186
<Compile Include="System\Enum.NativeAot.cs" />
186187
<Compile Include="System\Environment.NativeAot.cs" />
187188
<Compile Include="System\GC.NativeAot.cs" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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+
using System.Runtime;
4+
using System.Runtime.InteropServices;
5+
6+
#if FEATURE_PERFTRACING
7+
8+
namespace System.Diagnostics.Tracing
9+
{
10+
//
11+
// NOTE:
12+
//
13+
// The implementation below takes some manual marshaling actions to ensure arguments are in
14+
// primitive form before they are passed through to the underlying RuntimeImports.Rh*
15+
// function.
16+
//
17+
// These extra steps are necessary only if the RuntimeImports mechanism represents "raw"
18+
// calls into the native runtime (as has been the case at least in the distant past).
19+
//
20+
// If the RuntimeImports mechanism automatically applies rich p/invoke marshaling to all of
21+
// these calls, then all of the manual steps below are unnecessary and can be removed (by
22+
// making the RuntimeImports.Rh* function signatures generally match the corresponding
23+
// EventPipeInternal function signatures; in other words, by making the RuntimeImports.Rh*
24+
// functions look like the QCalls in EventPipe.CoreCLR.cs).
25+
//
26+
internal static partial class EventPipeInternal
27+
{
28+
//
29+
// These PInvokes are used by the configuration APIs to interact with EventPipe.
30+
//
31+
private static unsafe ulong Enable(
32+
char* outputFile,
33+
EventPipeSerializationFormat format,
34+
uint circularBufferSizeInMB,
35+
EventPipeProviderConfigurationNative* providers,
36+
uint numProviders)
37+
{
38+
return RuntimeImports.RhEventPipeInternal_Enable(
39+
outputFile,
40+
(int)format,
41+
circularBufferSizeInMB,
42+
providers,
43+
numProviders);
44+
}
45+
46+
internal static void Disable(ulong sessionID)
47+
{
48+
RuntimeImports.RhEventPipeInternal_Disable(sessionID);
49+
}
50+
51+
//
52+
// These PInvokes are used by EventSource to interact with the EventPipe.
53+
//
54+
55+
// private static extern unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext);
56+
57+
internal static unsafe IntPtr CreateProvider(string providerName,
58+
delegate* unmanaged<byte*, int, byte, long, long, Interop.Advapi32.EVENT_FILTER_DESCRIPTOR*, void*, void> callbackFunc,
59+
void* callbackContext)
60+
=> CreateProvider(providerName, (IntPtr)callbackFunc, (IntPtr)callbackContext);
61+
//internal static unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext);
62+
63+
internal static unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext)
64+
{
65+
fixed (char* pProviderName = providerName)
66+
{
67+
return RuntimeImports.RhEventPipeInternal_CreateProvider(
68+
pProviderName,
69+
callbackFunc,
70+
callbackContext);
71+
}
72+
}
73+
74+
internal static unsafe IntPtr DefineEvent(
75+
IntPtr provHandle,
76+
uint eventID,
77+
long keywords,
78+
uint eventVersion,
79+
uint level,
80+
void *pMetadata,
81+
uint metadataLength)
82+
{
83+
return RuntimeImports.RhEventPipeInternal_DefineEvent(
84+
provHandle,
85+
eventID,
86+
keywords,
87+
eventVersion,
88+
level,
89+
pMetadata,
90+
metadataLength);
91+
}
92+
93+
internal static unsafe IntPtr GetProvider(string providerName)
94+
{
95+
fixed (char* pProviderName = providerName)
96+
{
97+
return RuntimeImports.RhEventPipeInternal_GetProvider(pProviderName);
98+
}
99+
}
100+
101+
internal static void DeleteProvider(IntPtr provHandle)
102+
{
103+
RuntimeImports.RhEventPipeInternal_DeleteProvider(provHandle);
104+
}
105+
106+
internal static unsafe int EventActivityIdControl(uint controlCode, ref Guid activityId)
107+
{
108+
//
109+
// Ensure that the address passed to native code is never on the managed heap, while still
110+
// managing the supplied byref in an in/out manner.
111+
//
112+
Guid localActivityId = activityId;
113+
try { return RuntimeImports.RhEventPipeInternal_EventActivityIdControl(controlCode, &localActivityId); }
114+
finally { activityId = localActivityId; }
115+
}
116+
117+
internal static unsafe void WriteEventData(
118+
IntPtr eventHandle,
119+
EventProvider.EventData* pEventData,
120+
uint dataCount,
121+
Guid* activityId,
122+
Guid* relatedActivityId)
123+
{
124+
RuntimeImports.RhEventPipeInternal_WriteEventData(
125+
eventHandle,
126+
pEventData,
127+
dataCount,
128+
activityId,
129+
relatedActivityId);
130+
}
131+
132+
//
133+
// These PInvokes are used as part of the EventPipeEventDispatcher.
134+
//
135+
internal static unsafe bool GetSessionInfo(ulong sessionID, EventPipeSessionInfo* pSessionInfo)
136+
{
137+
uint rawBool = RuntimeImports.RhEventPipeInternal_GetSessionInfo(sessionID, pSessionInfo);
138+
return (rawBool != 0);
139+
}
140+
141+
internal static unsafe bool GetNextEvent(ulong sessionID, EventPipeEventInstanceData* pInstance)
142+
{
143+
uint rawBool = RuntimeImports.RhEventPipeInternal_GetNextEvent(sessionID, pInstance);
144+
return (rawBool != 0);
145+
}
146+
147+
internal static bool SignalSession(ulong sessionID)
148+
{
149+
uint rawBool = RuntimeImports.RhEventPipeInternal_SignalSession(sessionID);
150+
return (rawBool != 0);
151+
}
152+
153+
internal static bool WaitForSessionSignal(ulong sessionID, int timeoutMs)
154+
{
155+
uint rawBool = RuntimeImports.RhEventPipeInternal_WaitForSessionSignal(sessionID, timeoutMs);
156+
return (rawBool != 0);
157+
}
158+
}
159+
}
160+
161+
#endif // FEATURE_PERFTRACING
162+

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

+72
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,78 @@ public GCFrameRegistration(void* allocation, uint elemCount, bool areByRefs = tr
691691
[RuntimeImport(RuntimeLibrary, "RhpEtwExceptionThrown")]
692692
internal static extern unsafe void RhpEtwExceptionThrown(char* exceptionTypeName, char* exceptionMessage, IntPtr faultingIP, long hresult);
693693

694+
#if FEATURE_PERFTRACING
695+
696+
//
697+
// EventPipeInternal helpers.
698+
//
699+
[LibraryImport(RuntimeLibrary)]
700+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
701+
internal static unsafe partial ulong RhEventPipeInternal_Enable(
702+
char* outputFile,
703+
int format,
704+
uint circularBufferSizeInMB,
705+
void* providers,
706+
uint numProviders);
707+
708+
[LibraryImport(RuntimeLibrary)]
709+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
710+
internal static partial void RhEventPipeInternal_Disable(ulong sessionID);
711+
712+
[LibraryImport(RuntimeLibrary)]
713+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
714+
internal static unsafe partial IntPtr RhEventPipeInternal_CreateProvider(char* providerName, IntPtr callbackFunc, IntPtr callbackContext);
715+
716+
[LibraryImport(RuntimeLibrary)]
717+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
718+
internal static unsafe partial IntPtr RhEventPipeInternal_DefineEvent(
719+
IntPtr provHandle,
720+
uint eventID,
721+
long keywords,
722+
uint eventVersion,
723+
uint level,
724+
void *pMetadata,
725+
uint metadataLength);
726+
727+
[LibraryImport(RuntimeLibrary)]
728+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
729+
internal static unsafe partial IntPtr RhEventPipeInternal_GetProvider(char* providerName);
730+
731+
[LibraryImport(RuntimeLibrary)]
732+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
733+
internal static partial void RhEventPipeInternal_DeleteProvider(IntPtr provHandle);
734+
735+
[LibraryImport(RuntimeLibrary)]
736+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
737+
internal static unsafe partial int RhEventPipeInternal_EventActivityIdControl(uint controlCode, Guid* activityId);
738+
739+
[LibraryImport(RuntimeLibrary)]
740+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
741+
internal static unsafe partial void RhEventPipeInternal_WriteEventData(
742+
IntPtr eventHandle,
743+
void* pEventData,
744+
uint dataCount,
745+
Guid* activityId,
746+
Guid* relatedActivityId);
747+
748+
[LibraryImport(RuntimeLibrary)]
749+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
750+
internal static unsafe partial uint RhEventPipeInternal_GetSessionInfo(ulong sessionID, void* pSessionInfo);
751+
752+
[LibraryImport(RuntimeLibrary)]
753+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
754+
internal static unsafe partial uint RhEventPipeInternal_GetNextEvent(ulong sessionID, void* pInstance);
755+
756+
[LibraryImport(RuntimeLibrary)]
757+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
758+
internal static partial uint RhEventPipeInternal_SignalSession(ulong sessionID);
759+
760+
[LibraryImport(RuntimeLibrary)]
761+
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
762+
internal static partial uint RhEventPipeInternal_WaitForSessionSignal(ulong sessionID, int timeoutMs);
763+
764+
#endif // FEATURE_PERFTRACING
765+
694766
//
695767
// Interlocked helpers
696768
//

0 commit comments

Comments
 (0)