Skip to content

Commit

Permalink
Maanged to Native hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
LakshanF committed Jan 9, 2023
1 parent 179585e commit 8502406
Show file tree
Hide file tree
Showing 6 changed files with 374 additions and 0 deletions.
129 changes: 129 additions & 0 deletions src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "common.h"
#include "eventpipeadapter.h"

#ifdef FEATURE_PERFTRACING

struct EventPipeEventInstanceData
{
void *ProviderID;
unsigned int EventID;
unsigned int ThreadID;
LARGE_INTEGER TimeStamp;
GUID ActivityId;
GUID RelatedActivityId;
const uint8_t *Payload;
unsigned int PayloadLength;
};

struct EventPipeSessionInfo
{
FILETIME StartTimeAsUTCFileTime;
LARGE_INTEGER StartTimeStamp;
LARGE_INTEGER TimeStampFrequency;
};

EXTERN_C NATIVEAOT_API uint64_t __cdecl RhEventPipeInternal_Enable(
LPCWSTR outputFile,
EventPipeSerializationFormat format,
uint32_t circularBufferSizeInMB,
/* COR_PRF_EVENTPIPE_PROVIDER_CONFIG */ const void * pProviders,
uint32_t numProviders)
{
__debugbreak();
return 0;
}

EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_Disable(uint64_t sessionID)
{
__debugbreak();
}

EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_CreateProvider(
LPCWSTR providerName,
EventPipeCallback pCallbackFunc,
void* pCallbackContext)
{
EventPipeProvider* pProvider = EventPipeAdapter::CreateProvider(providerName, pCallbackFunc, pCallbackContext);
return reinterpret_cast<intptr_t>(pProvider);
}

EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_DefineEvent(
intptr_t provHandle,
uint32_t eventID,
int64_t keywords,
uint32_t eventVersion,
uint32_t level,
void *pMetadata,
uint32_t metadataLength)
{
EventPipeEvent *pEvent = NULL;

_ASSERTE(provHandle != 0);
EventPipeProvider *pProvider = reinterpret_cast<EventPipeProvider *>(provHandle);
pEvent = EventPipeAdapter::AddEvent(pProvider, eventID, keywords, eventVersion, (EventPipeEventLevel)level, /* needStack = */ true, (uint8_t *)pMetadata, metadataLength);
_ASSERTE(pEvent != NULL);

return reinterpret_cast<intptr_t>(pEvent);
}

EXTERN_C NATIVEAOT_API intptr_t __cdecl RhEventPipeInternal_GetProvider(LPCWSTR providerName)
{
__debugbreak();
return 0;
}

EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_DeleteProvider(intptr_t provHandle)
{
if (provHandle != 0)
{
EventPipeProvider *pProvider = reinterpret_cast<EventPipeProvider *>(provHandle);
EventPipeAdapter::DeleteProvider(pProvider);
}
}

EXTERN_C NATIVEAOT_API int __cdecl RhEventPipeInternal_EventActivityIdControl(uint32_t controlCode, GUID *pActivityId)
{
__debugbreak();
return 0;
}

EXTERN_C NATIVEAOT_API void __cdecl RhEventPipeInternal_WriteEventData(
intptr_t eventHandle,
EventData *pEventData,
uint32_t eventDataCount,
const GUID * pActivityId,
const GUID * pRelatedActivityId)
{
_ASSERTE(eventHandle != 0);
EventPipeEvent *pEvent = reinterpret_cast<EventPipeEvent *>(eventHandle);
EventPipeAdapter::WriteEvent(pEvent, pEventData, eventDataCount, pActivityId, pRelatedActivityId);
}

EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetSessionInfo(uint64_t sessionID, EventPipeSessionInfo *pSessionInfo)
{
__debugbreak();
return FALSE;
}

EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_GetNextEvent(uint64_t sessionID, EventPipeEventInstanceData *pInstance)
{
__debugbreak();
return FALSE;
}

EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_SignalSession(uint64_t sessionID)
{
__debugbreak();
return FALSE;
}

EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhEventPipeInternal_WaitForSessionSignal(uint64_t sessionID, int32_t timeoutMs)
{
__debugbreak();
return FALSE;
}

#endif // FEATURE_PERFTRACING
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
<Compile Include="System\Diagnostics\StackFrame.NativeAot.cs" />
<Compile Include="System\Diagnostics\StackFrameExtensions.cs" />
<Compile Include="System\Diagnostics\StackTrace.NativeAot.cs" />
<Compile Include="System\Diagnostics\Eventing\EventPipe.NativeAot.cs" />
<Compile Include="System\Enum.NativeAot.cs" />
<Compile Include="System\Environment.NativeAot.cs" />
<Compile Include="System\GC.NativeAot.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime;
using System.Runtime.InteropServices;

#if FEATURE_PERFTRACING

namespace System.Diagnostics.Tracing
{
//
// NOTE:
//
// The implementation below takes some manual marshaling actions to ensure arguments are in
// primitive form before they are passed through to the underlying RuntimeImports.Rh*
// function.
//
// These extra steps are necessary only if the RuntimeImports mechanism represents "raw"
// calls into the native runtime (as has been the case at least in the distant past).
//
// If the RuntimeImports mechanism automatically applies rich p/invoke marshaling to all of
// these calls, then all of the manual steps below are unnecessary and can be removed (by
// making the RuntimeImports.Rh* function signatures generally match the corresponding
// EventPipeInternal function signatures; in other words, by making the RuntimeImports.Rh*
// functions look like the QCalls in EventPipe.CoreCLR.cs).
//
internal static partial class EventPipeInternal
{
//
// These PInvokes are used by the configuration APIs to interact with EventPipe.
//
private static unsafe ulong Enable(
char* outputFile,
EventPipeSerializationFormat format,
uint circularBufferSizeInMB,
EventPipeProviderConfigurationNative* providers,
uint numProviders)
{
return RuntimeImports.RhEventPipeInternal_Enable(
outputFile,
(int)format,
circularBufferSizeInMB,
providers,
numProviders);
}

internal static void Disable(ulong sessionID)
{
RuntimeImports.RhEventPipeInternal_Disable(sessionID);
}

//
// These PInvokes are used by EventSource to interact with the EventPipe.
//

// private static extern unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext);

internal static unsafe IntPtr CreateProvider(string providerName,
delegate* unmanaged<byte*, int, byte, long, long, Interop.Advapi32.EVENT_FILTER_DESCRIPTOR*, void*, void> callbackFunc,
void* callbackContext)
=> CreateProvider(providerName, (IntPtr)callbackFunc, (IntPtr)callbackContext);
//internal static unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext);

internal static unsafe IntPtr CreateProvider(string providerName, IntPtr callbackFunc, IntPtr callbackContext)
{
fixed (char* pProviderName = providerName)
{
return RuntimeImports.RhEventPipeInternal_CreateProvider(
pProviderName,
callbackFunc,
callbackContext);
}
}

internal static unsafe IntPtr DefineEvent(
IntPtr provHandle,
uint eventID,
long keywords,
uint eventVersion,
uint level,
void *pMetadata,
uint metadataLength)
{
return RuntimeImports.RhEventPipeInternal_DefineEvent(
provHandle,
eventID,
keywords,
eventVersion,
level,
pMetadata,
metadataLength);
}

internal static unsafe IntPtr GetProvider(string providerName)
{
fixed (char* pProviderName = providerName)
{
return RuntimeImports.RhEventPipeInternal_GetProvider(pProviderName);
}
}

internal static void DeleteProvider(IntPtr provHandle)
{
RuntimeImports.RhEventPipeInternal_DeleteProvider(provHandle);
}

internal static unsafe int EventActivityIdControl(uint controlCode, ref Guid activityId)
{
//
// Ensure that the address passed to native code is never on the managed heap, while still
// managing the supplied byref in an in/out manner.
//
Guid localActivityId = activityId;
try { return RuntimeImports.RhEventPipeInternal_EventActivityIdControl(controlCode, &localActivityId); }
finally { activityId = localActivityId; }
}

internal static unsafe void WriteEventData(
IntPtr eventHandle,
EventProvider.EventData* pEventData,
uint dataCount,
Guid* activityId,
Guid* relatedActivityId)
{
RuntimeImports.RhEventPipeInternal_WriteEventData(
eventHandle,
pEventData,
dataCount,
activityId,
relatedActivityId);
}

//
// These PInvokes are used as part of the EventPipeEventDispatcher.
//
internal static unsafe bool GetSessionInfo(ulong sessionID, EventPipeSessionInfo* pSessionInfo)
{
uint rawBool = RuntimeImports.RhEventPipeInternal_GetSessionInfo(sessionID, pSessionInfo);
return (rawBool != 0);
}

internal static unsafe bool GetNextEvent(ulong sessionID, EventPipeEventInstanceData* pInstance)
{
uint rawBool = RuntimeImports.RhEventPipeInternal_GetNextEvent(sessionID, pInstance);
return (rawBool != 0);
}

internal static bool SignalSession(ulong sessionID)
{
uint rawBool = RuntimeImports.RhEventPipeInternal_SignalSession(sessionID);
return (rawBool != 0);
}

internal static bool WaitForSessionSignal(ulong sessionID, int timeoutMs)
{
uint rawBool = RuntimeImports.RhEventPipeInternal_WaitForSessionSignal(sessionID, timeoutMs);
return (rawBool != 0);
}
}
}

#endif // FEATURE_PERFTRACING

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

#if FEATURE_PERFTRACING

//
// EventPipeInternal helpers.
//
[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial ulong RhEventPipeInternal_Enable(
char* outputFile,
int format,
uint circularBufferSizeInMB,
void* providers,
uint numProviders);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial void RhEventPipeInternal_Disable(ulong sessionID);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial IntPtr RhEventPipeInternal_CreateProvider(char* providerName, IntPtr callbackFunc, IntPtr callbackContext);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial IntPtr RhEventPipeInternal_DefineEvent(
IntPtr provHandle,
uint eventID,
long keywords,
uint eventVersion,
uint level,
void *pMetadata,
uint metadataLength);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial IntPtr RhEventPipeInternal_GetProvider(char* providerName);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial void RhEventPipeInternal_DeleteProvider(IntPtr provHandle);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial int RhEventPipeInternal_EventActivityIdControl(uint controlCode, Guid* activityId);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial void RhEventPipeInternal_WriteEventData(
IntPtr eventHandle,
void* pEventData,
uint dataCount,
Guid* activityId,
Guid* relatedActivityId);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial uint RhEventPipeInternal_GetSessionInfo(ulong sessionID, void* pSessionInfo);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static unsafe partial uint RhEventPipeInternal_GetNextEvent(ulong sessionID, void* pInstance);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial uint RhEventPipeInternal_SignalSession(ulong sessionID);

[LibraryImport(RuntimeLibrary)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static partial uint RhEventPipeInternal_WaitForSessionSignal(ulong sessionID, int timeoutMs);

#endif // FEATURE_PERFTRACING

//
// Interlocked helpers
//
Expand Down
Loading

0 comments on commit 8502406

Please sign in to comment.