2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 // File: eventtracebase.h
7 // Abstract: This module implements base Event Tracing support (excluding some of the
8 // CLR VM-specific ETW helpers).
17 // ETW (Event Tracing for Windows) is a high-performance, low overhead and highly scalable
18 // tracing facility provided by the Windows Operating System. ETW is available on Win2K and above. There are
19 // four main types of components in ETW: event providers, controllers, consumers, and event trace sessions.
20 // An event provider is a logical entity that writes events to ETW sessions. The event provider must register
21 // a provider ID with ETW through the registration API. A provider first registers with ETW and writes events
22 // from various points in the code by invoking the ETW logging API. When a provider is enabled dynamically by
23 // the ETW controller application, calls to the logging API sends events to a specific trace session
24 // designated by the controller. Each event sent by the event provider to the trace session consists of a
25 // fixed header that includes event metadata and additional variable user-context data. CLR is an event
27 // ============================================================================
29 #ifndef _ETWTRACER_HXX_
30 #define _ETWTRACER_HXX_
32 struct EventStructTypeData;
33 void InitializeEventTracing();
35 // !!!!!!! NOTE !!!!!!!!
36 // The flags must match those in the ETW manifest exactly
37 // !!!!!!! NOTE !!!!!!!!
39 // These flags need to be defined either when FEATURE_EVENT_TRACE is enabled or the
40 // PROFILING_SUPPORTED is set, since they are used both by event tracing and profiling.
44 kEtwGCRootFlagsPinning = 0x1,
45 kEtwGCRootFlagsWeakRef = 0x2,
46 kEtwGCRootFlagsInterior = 0x4,
47 kEtwGCRootFlagsRefCounted = 0x8,
52 kEtwGCRootKindStack = 0,
53 kEtwGCRootKindFinalizer = 1,
54 kEtwGCRootKindHandle = 2,
55 kEtwGCRootKindOther = 3,
60 kEtwTypeFlagsDelegate = 0x1,
61 kEtwTypeFlagsFinalizable = 0x2,
62 kEtwTypeFlagsExternallyImplementedCOMObject = 0x4,
63 kEtwTypeFlagsArray = 0x8,
68 kEtwThreadFlagGCSpecial = 0x00000001,
69 kEtwThreadFlagFinalizer = 0x00000002,
70 kEtwThreadFlagThreadPoolWorker = 0x00000004,
73 #ifdef FEATURE_EVENT_TRACE
75 // During a heap walk, this is the storage for keeping track of all the nodes and edges
76 // being batched up by ETW, and for remembering whether we're also supposed to call into
77 // a profapi profiler. This is allocated toward the end of a GC and passed to us by the
79 struct ProfilerWalkHeapContext
82 ProfilerWalkHeapContext(BOOL fProfilerPinnedParam, LPVOID pvEtwContextParam)
84 fProfilerPinned = fProfilerPinnedParam;
85 pvEtwContext = pvEtwContextParam;
94 /******************************/
95 /* CLR ETW supported versions */
96 /******************************/
97 #define ETW_SUPPORTED_MAJORVER 5 // ETW is supported on win2k and above
98 #define ETW_ENABLED_MAJORVER 6 // OS versions >= to this we enable ETW registration by default, since on XP and Windows 2003, registration is too slow.
100 /***************************************/
101 /* Tracing levels supported by CLR ETW */
102 /***************************************/
103 #define ETWMAX_TRACE_LEVEL 6 // Maximum Number of Trace Levels supported
104 #define TRACE_LEVEL_NONE 0 // Tracing is not on
105 #define TRACE_LEVEL_FATAL 1 // Abnormal exit or termination
106 #define TRACE_LEVEL_ERROR 2 // Severe errors that need logging
107 #define TRACE_LEVEL_WARNING 3 // Warnings such as allocation failure
108 #define TRACE_LEVEL_INFORMATION 4 // Includes non-error cases such as Entry-Exit
109 #define TRACE_LEVEL_VERBOSE 5 // Detailed traces from intermediate steps
111 struct ProfilingScanContext;
114 // Use this macro to check if ETW is initialized and the event is enabled
116 #define ETW_TRACING_ENABLED(Context, EventDescriptor) \
117 (Context.IsEnabled && ETW_TRACING_INITIALIZED(Context.RegistrationHandle) && ETW_EVENT_ENABLED(Context, EventDescriptor))
120 // Using KEYWORDZERO means when checking the events category ignore the keyword
122 #define KEYWORDZERO 0x0
125 // Use this macro to check if ETW is initialized and the category is enabled
127 #define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) \
128 (ETW_TRACING_INITIALIZED(Context.RegistrationHandle) && ETW_CATEGORY_ENABLED(Context, Level, Keyword))
130 #define ETWOnStartup(StartEventName, EndEventName) \
131 ETWTraceStartup trace##StartEventName##(Microsoft_Windows_DotNETRuntimePrivateHandle, &StartEventName, &StartupId, &EndEventName, &StartupId);
132 #define ETWFireEvent(EventName) \
133 ETWTraceStartup::StartupTraceEvent(Microsoft_Windows_DotNETRuntimePrivateHandle, &EventName, &StartupId);
135 #ifndef FEATURE_REDHAWK
138 #include <initguid.h>
140 #include <evntrace.h>
141 #include <evntprov.h>
142 #if !defined(DONOT_DEFINE_ETW_CALLBACK) && !defined(DACCESS_COMPILE)
143 #define GetVersionEx(Version) (GetOSVersion((LPOSVERSIONINFOW)Version))
145 #define GetVersionEx(Version) (WszGetVersionEx((LPOSVERSIONINFOW)Version))
146 #endif // !DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE
148 #endif //!FEATURE_REDHAWK
151 #else // FEATURE_EVENT_TRACE
153 #include "etmdummy.h"
154 #endif // FEATURE_EVENT_TRACE
156 #ifndef FEATURE_REDHAWK
160 // g_nClrInstanceId is defined in Utilcode\Util.cpp. The definition goes into Utilcode.lib.
161 // This enables both the VM and Utilcode to raise ETW events.
162 extern UINT32 g_nClrInstanceId;
163 extern BOOL g_fEEManagedEXEStartup;
164 extern BOOL g_fEEIJWStartup;
166 #define GetClrInstanceId() (static_cast<UINT16>(g_nClrInstanceId))
168 #if defined(FEATURE_EVENT_TRACE)
169 // Callback and stack support
170 #if !defined(DONOT_DEFINE_ETW_CALLBACK) && !defined(DACCESS_COMPILE)
172 /* ETW control callback
173 * Desc: This function handles the ETW control
175 * Ret: success or failure
176 ***********************************************/
178 _In_ LPCGUID SourceId,
179 _In_ ULONG ControlCode,
181 _In_ ULONGLONG MatchAnyKeyword,
182 _In_ ULONGLONG MatchAllKeyword,
183 _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
184 _Inout_opt_ PVOID CallbackContext);
188 // User defined callback
190 #define MCGEN_PRIVATE_ENABLE_CALLBACK(RequestCode, Context, InOutBufferSize, Buffer) \
191 EtwCallback(NULL /* SourceId */, (RequestCode==WMI_ENABLE_EVENTS) ? EVENT_CONTROL_CODE_ENABLE_PROVIDER : EVENT_CONTROL_CODE_DISABLE_PROVIDER, 0 /* Level */, 0 /* MatchAnyKeyword */, 0 /* MatchAllKeyword */, NULL /* FilterData */, Context)
194 // User defined callback2
196 #define MCGEN_PRIVATE_ENABLE_CALLBACK_V2(SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeyword, FilterData, CallbackContext) \
197 EtwCallback(SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeyword, FilterData, CallbackContext)
201 * Desc: This function handles the ETW callout
202 * Ret: success or failure
203 ***********************************************/
206 PCEVENT_DESCRIPTOR Descriptor,
208 PEVENT_DATA_DESCRIPTOR EventData);
212 // Call user defined callout
214 #define MCGEN_CALLOUT(RegHandle, Descriptor, NumberOfArguments, EventData) \
215 EtwCallout(RegHandle, Descriptor, NumberOfArguments, EventData)
216 #endif //!DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE
218 #include <clretwallmain.h>
219 // The bulk type event is too complex for MC.exe to auto-generate proper code.
220 // Use code:BulkTypeEventLogger instead.
221 #ifdef FireEtwBulkType
222 #undef FireEtwBulkType
223 #endif // FireEtwBulkType
224 #endif // FEATURE_EVENT_TRACE
226 /**************************/
227 /* CLR ETW infrastructure */
228 /**************************/
230 // On Windows Vista, ETW has gone through a major upgrade, and one of the most significant changes is the
231 // introduction of the unified event provider model and APIs. The older architecture used the classic ETW
232 // events. The new ETW architecture uses the manifest based events. To support both types of events at the
233 // same time, we use the manpp tool for generating event macros that can be directly used to fire ETW events
234 // from various components within the CLR.
235 // (http://diagnostics/sites/etw/Lists/Announcements/DispForm.aspx?ID=10&Source=http%3A%2F%2Fdiagnostics%2Fsites%2Fetw%2Fdefault%2Easpx)
236 // Every ETW provider has to Register itself to the system, so that when enabled, it is capable of firing
237 // ETW events. file:../VM/eventtrace.cpp#Registration is where the actual Provider Registration takes place.
238 // At process shutdown, a registered provider need to be unregistered.
239 // file:../VM/eventtrace.cpp#Unregistration. Since ETW can also be enabled at any instant after the process
240 // has started, one may want to do something useful when that happens (e.g enumerate all the loaded modules
241 // in the system). To enable this, we have to implement a callback routine.
242 // file:../VM/eventtrace.cpp#EtwCallback is CLR's implementation of the callback.
254 class LoaderAllocator;
255 class AssemblyLoaderAllocator;
256 struct AllLoggedTypes;
258 class BulkTypeEventLogger;
263 // All ETW helpers must be a part of this namespace
264 // We have auto-generated macros to directly fire the events
265 // but in some cases, gathering the event payload information involves some work
266 // and it can be done in a relevant helper class like the one's in this namespace
269 // Class to wrap the ETW infrastructure logic
272 #if defined(FEATURE_EVENT_TRACE)
273 ULONG RegGuids(LPCGUID ProviderId, PENABLECALLBACK EnableCallback, PVOID CallbackContext, PREGHANDLE RegHandle);
277 #ifdef FEATURE_EVENT_TRACE
278 // Registers all the Event Tracing providers
281 // Unregisters all the Event Tracing providers
282 HRESULT UnRegister();
292 #endif // FEATURE_EVENT_TRACE
297 // Class to wrap all the enumeration logic for ETW
300 friend class ETW::LoaderLog;
301 friend class ETW::MethodLog;
302 #ifdef FEATURE_EVENT_TRACE
303 static VOID SendThreadRundownEvent();
304 static VOID IterateDomain(BaseDomain *pDomain, DWORD enumerationOptions);
305 static VOID IterateAppDomain(AppDomain * pAppDomain, DWORD enumerationOptions);
306 static VOID IterateCollectibleLoaderAllocator(AssemblyLoaderAllocator *pLoaderAllocator, DWORD enumerationOptions);
307 static VOID IterateAssembly(Assembly *pAssembly, DWORD enumerationOptions);
308 static VOID IterateModule(Module *pModule, DWORD enumerationOptions);
309 static VOID EnumerationHelper(Module *moduleFilter, BaseDomain *domainFilter, DWORD enumerationOptions);
310 static DWORD GetEnumerationOptionsFromRuntimeKeywords();
312 typedef union _EnumerationStructs
314 typedef enum _EnumerationOptions
317 DomainAssemblyModuleLoad= 0x00000001,
318 DomainAssemblyModuleUnload= 0x00000002,
319 DomainAssemblyModuleDCStart= 0x00000004,
320 DomainAssemblyModuleDCEnd= 0x00000008,
321 JitMethodLoad= 0x00000010,
322 JitMethodUnload= 0x00000020,
323 JitMethodDCStart= 0x00000040,
324 JitMethodDCEnd= 0x00000080,
325 NgenMethodLoad= 0x00000100,
326 NgenMethodUnload= 0x00000200,
327 NgenMethodDCStart= 0x00000400,
328 NgenMethodDCEnd= 0x00000800,
329 ModuleRangeLoad= 0x00001000,
330 ModuleRangeDCStart= 0x00002000,
331 ModuleRangeDCEnd= 0x00004000,
332 ModuleRangeLoadPrivate= 0x00008000,
333 MethodDCStartILToNativeMap= 0x00010000,
334 MethodDCEndILToNativeMap= 0x00020000,
335 JitMethodILToNativeMap= 0x00040000,
336 TypeUnload= 0x00080000,
339 ModuleRangeEnabledAny = ModuleRangeLoad | ModuleRangeDCStart | ModuleRangeDCEnd | ModuleRangeLoadPrivate,
340 JitMethodLoadOrDCStartAny = JitMethodLoad | JitMethodDCStart | MethodDCStartILToNativeMap,
341 JitMethodUnloadOrDCEndAny = JitMethodUnload | JitMethodDCEnd | MethodDCEndILToNativeMap,
345 static VOID ProcessShutdown();
346 static VOID ModuleRangeRundown();
347 static VOID StartRundown();
348 static VOID EndRundown();
349 static VOID EnumerateForCaptureState();
352 static VOID ProcessShutdown() {};
353 static VOID StartRundown() {};
354 static VOID EndRundown() {};
355 #endif // FEATURE_EVENT_TRACE
359 // Class to wrap all the sampling logic for ETW
362 #if defined(FEATURE_EVENT_TRACE)
364 typedef enum _EtwStackWalkStatus
369 } EtwStackWalkStatus;
371 static const UINT8 s_MaxStackSize=100;
373 SIZE_T m_EBPStack[SamplingLog::s_MaxStackSize];
374 VOID Append(SIZE_T currentFrame);
375 EtwStackWalkStatus SaveCurrentStack(int skipTopNFrames=1);
377 static ULONG SendStackTrace(MCGEN_TRACE_CONTEXT TraceContext, PCEVENT_DESCRIPTOR Descriptor, LPCGUID EventGuid);
378 EtwStackWalkStatus GetCurrentThreadsCallStack(UINT32 *frameCount, PVOID **Stack);
379 #endif // FEATURE_EVENT_TRACE
382 // Class to wrap all Loader logic for ETW
385 friend class ETW::EnumerationLog;
386 #ifdef FEATURE_EVENT_TRACE
387 static VOID SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL bFireDomainModuleEvents=FALSE);
388 static ULONG SendModuleRange(Module *pModule, DWORD dwEventOptions);
389 static VOID SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions);
390 static VOID SendDomainEvent(BaseDomain *pBaseDomain, DWORD dwEventOptions, LPCWSTR wszFriendlyName=NULL);
392 typedef union _LoaderStructs
394 typedef enum _AppDomainFlags
397 ExecutableDomain=0x2,
401 typedef enum _AssemblyFlags
403 DomainNeutralAssembly=0x1,
406 CollectibleAssembly=0x8,
409 typedef enum _ModuleFlags
411 DomainNeutralModule=0x1,
418 typedef enum _RangeFlags
425 static VOID DomainLoadReal(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName=NULL);
427 static VOID DomainLoad(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName = NULL)
429 if (MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context.IsEnabled)
431 DomainLoadReal(pDomain, wszFriendlyName);
435 static VOID DomainUnload(AppDomain *pDomain);
436 static VOID CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator);
437 static VOID ModuleLoad(Module *pModule, LONG liReportedSharedModule);
440 static VOID DomainLoad(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName=NULL) {};
441 static VOID DomainUnload(AppDomain *pDomain) {};
442 static VOID CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator) {};
443 static VOID ModuleLoad(Module *pModule, LONG liReportedSharedModule) {};
444 #endif // FEATURE_EVENT_TRACE
447 // Class to wrap all Method logic for ETW
450 friend class ETW::EnumerationLog;
451 #ifdef FEATURE_EVENT_TRACE
452 static VOID SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAllocator *pLoaderAllocatorFilter, DWORD dwEventOptions);
453 static VOID SendEventsForJitMethodsHelper(BaseDomain *pDomainFilter,
454 LoaderAllocator *pLoaderAllocatorFilter,
455 DWORD dwEventOptions,
458 BOOL fSendMethodEvent,
459 BOOL fSendILToNativeMapEvent,
461 static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions);
462 static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
463 static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, ReJITID rejitID);
464 static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0);
465 static VOID SendHelperEvent(ULONGLONG ullHelperStartAddress, ULONG ulHelperSize, LPCWSTR pHelperName);
467 typedef union _MethodStructs
469 typedef enum _MethodFlags
473 SharedGenericCode=0x4,
478 typedef enum _MethodExtent
480 HotSection=0x00000000,
481 ColdSection=0x10000000
486 static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
487 static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0);
488 static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName);
489 static VOID StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG ulNoOfHelpers);
490 static VOID MethodRestored(MethodDesc * pMethodDesc);
491 static VOID MethodTableRestored(MethodTable * pMethodTable);
492 static VOID DynamicMethodDestroyed(MethodDesc *pMethodDesc);
493 #else // FEATURE_EVENT_TRACE
495 static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL) {};
496 static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0) {};
497 static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {};
498 static VOID StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG ulNoOfHelpers) {};
499 static VOID MethodRestored(MethodDesc * pMethodDesc) {};
500 static VOID MethodTableRestored(MethodTable * pMethodTable) {};
501 static VOID DynamicMethodDestroyed(MethodDesc *pMethodDesc) {};
502 #endif // FEATURE_EVENT_TRACE
505 // Class to wrap all Security logic for ETW
508 #ifdef FEATURE_EVENT_TRACE
510 static VOID StrongNameVerificationStart(DWORD dwInFlags, __in LPWSTR strFullyQualifiedAssemblyName);
511 static VOID StrongNameVerificationStop(DWORD dwInFlags,ULONG result, __in LPWSTR strFullyQualifiedAssemblyName);
513 static void FireFieldTransparencyComputationStart(LPCWSTR wszFieldName,
514 LPCWSTR wszModuleName,
516 static void FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
517 LPCWSTR wszModuleName,
520 BOOL fIsTreatAsSafe);
522 static void FireMethodTransparencyComputationStart(LPCWSTR wszMethodName,
523 LPCWSTR wszModuleName,
525 static void FireMethodTransparencyComputationEnd(LPCWSTR wszMethodName,
526 LPCWSTR wszModuleName,
529 BOOL fIsTreatAsSafe);
531 static void FireModuleTransparencyComputationStart(LPCWSTR wszModuleName, DWORD dwAppDomain);
532 static void FireModuleTransparencyComputationEnd(LPCWSTR wszModuleName,
535 BOOL fIsAllTransparent,
537 BOOL fIsOpportunisticallyCritical,
538 DWORD dwSecurityRuleSet);
540 static void FireTokenTransparencyComputationStart(DWORD dwToken,
541 LPCWSTR wszModuleName,
543 static void FireTokenTransparencyComputationEnd(DWORD dwToken,
544 LPCWSTR wszModuleName,
547 BOOL fIsTreatAsSafe);
549 static void FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
550 LPCWSTR wszModuleName,
552 static void FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
553 LPCWSTR wszModuleName,
556 BOOL fIsAllTransparent,
558 BOOL fIsTreatAsSafe);
561 static VOID StrongNameVerificationStart(DWORD dwInFlags,LPWSTR strFullyQualifiedAssemblyName) {};
562 static VOID StrongNameVerificationStop(DWORD dwInFlags,ULONG result, LPWSTR strFullyQualifiedAssemblyName) {};
564 static void FireFieldTransparencyComputationStart(LPCWSTR wszFieldName,
565 LPCWSTR wszModuleName,
566 DWORD dwAppDomain) {};
567 static void FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
568 LPCWSTR wszModuleName,
571 BOOL fIsTreatAsSafe) {};
573 static void FireMethodTransparencyComputationStart(LPCWSTR wszMethodName,
574 LPCWSTR wszModuleName,
575 DWORD dwAppDomain) {};
576 static void FireMethodTransparencyComputationEnd(LPCWSTR wszMethodName,
577 LPCWSTR wszModuleName,
580 BOOL fIsTreatAsSafe) {};
582 static void FireModuleTransparencyComputationStart(LPCWSTR wszModuleName, DWORD dwAppDomain) {};
583 static void FireModuleTransparencyComputationEnd(LPCWSTR wszModuleName,
586 BOOL fIsAllTransparent,
588 BOOL fIsOpportunisticallyCritical,
589 DWORD dwSecurityRuleSet) {};
591 static void FireTokenTransparencyComputationStart(DWORD dwToken,
592 LPCWSTR wszModuleName,
593 DWORD dwAppDomain) {};
594 static void FireTokenTransparencyComputationEnd(DWORD dwToken,
595 LPCWSTR wszModuleName,
598 BOOL fIsTreatAsSafe) {};
600 static void FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
601 LPCWSTR wszModuleName,
602 DWORD dwAppDomain) {};
603 static void FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
604 LPCWSTR wszModuleName,
607 BOOL fIsAllTransparent,
609 BOOL fIsTreatAsSafe) {};
610 #endif // FEATURE_EVENT_TRACE
613 // Class to wrap all Binder logic for ETW
617 typedef union _BinderStructs {
618 typedef enum _NGENBINDREJECT_REASON {
619 NGEN_BIND_START_BIND = 0,
620 NGEN_BIND_NO_INDEX = 1,
621 NGEN_BIND_SYSTEM_ASSEMBLY_NOT_AVAILABLE = 2,
622 NGEN_BIND_NO_NATIVE_IMAGE = 3,
623 NGEN_BIND_REJECT_CONFIG_MASK = 4,
625 NGEN_BIND_INDEX_CORRUPTION = 6,
626 NGEN_BIND_REJECT_TIMESTAMP = 7,
627 NGEN_BIND_REJECT_NATIVEIMAGE_NOT_FOUND = 8,
628 NGEN_BIND_REJECT_IL_SIG = 9,
629 NGEN_BIND_REJECT_LOADER_EVAL_FAIL = 10,
630 NGEN_BIND_MISSING_FOUND = 11,
631 NGEN_BIND_REJECT_HOSTASM = 12,
632 NGEN_BIND_REJECT_IL_NOT_FOUND = 13,
633 NGEN_BIND_REJECT_APPBASE_NOT_FILE = 14,
634 NGEN_BIND_BIND_DEPEND_REJECT_REF_DEF_MISMATCH = 15,
635 NGEN_BIND_BIND_DEPEND_REJECT_NGEN_SIG = 16,
636 NGEN_BIND_APPLY_EXTERNAL_RELOCS_FAILED = 17,
637 NGEN_BIND_SYSTEM_ASSEMBLY_NATIVEIMAGE_NOT_AVAILABLE = 18,
638 NGEN_BIND_ASSEMBLY_HAS_DIFFERENT_GRANT = 19,
639 NGEN_BIND_ASSEMBLY_NOT_DOMAIN_NEUTRAL = 20,
640 NGEN_BIND_NATIVEIMAGE_VERSION_MISMATCH = 21,
641 NGEN_BIND_LOADFROM_NOT_ALLOWED = 22,
642 NGEN_BIND_DEPENDENCY_HAS_DIFFERENT_IDENTITY = 23
643 } NGENBINDREJECT_REASON;
647 // Class to wrap all Exception logic for ETW
651 #ifdef FEATURE_EVENT_TRACE
652 static VOID ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownException, BOOL bIsNewException);
653 static VOID ExceptionThrownEnd();
654 static VOID ExceptionCatchBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP);
655 static VOID ExceptionCatchEnd();
656 static VOID ExceptionFinallyBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP);
657 static VOID ExceptionFinallyEnd();
658 static VOID ExceptionFilterBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP);
659 static VOID ExceptionFilterEnd();
662 static VOID ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownException, BOOL bIsNewException) {};
663 static VOID ExceptionThrownEnd() {};
664 static VOID ExceptionCatchBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {};
665 static VOID ExceptionCatchEnd() {};
666 static VOID ExceptionFinallyBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {};
667 static VOID ExceptionFinallyEnd() {};
668 static VOID ExceptionFilterBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {};
669 static VOID ExceptionFilterEnd() {};
670 #endif // FEATURE_EVENT_TRACE
671 typedef union _ExceptionStructs
673 typedef enum _ExceptionThrownFlags
675 HasInnerException=0x1,
676 IsNestedException=0x2,
677 IsReThrownException=0x4,
680 }ExceptionThrownFlags;
683 // Class to wrap all Contention logic for ETW
687 typedef union _ContentionStructs
689 typedef enum _ContentionFlags {
695 // Class to wrap all Interop logic for ETW
701 // Class to wrap all Information logic for ETW
705 typedef union _InfoStructs
707 typedef enum _StartupMode
722 typedef enum _EtwMode
729 #ifdef FEATURE_EVENT_TRACE
730 static VOID RuntimeInformation(INT32 type);
732 static VOID RuntimeInformation(INT32 type) {};
733 #endif // FEATURE_EVENT_TRACE
739 // The ONE and only ONE global instantiation of this class
741 extern ETW::CEtwTracer * g_pEtwTracer;
742 #define ETW_IS_TRACE_ON(level) ( FALSE ) // for fusion which is eventually going to get removed
743 #define ETW_IS_FLAG_ON(flag) ( FALSE ) // for fusion which is eventually going to get removed
745 // Commonly used constats for ETW Assembly Loader and Assembly Binder events.
746 #define ETWLoadContextNotAvailable (LOADCTX_TYPE_HOSTED + 1)
747 #define ETWAppDomainIdNotAvailable 0 // Valid AppDomain IDs start from 1
749 #define ETWFieldUnused 0 // Indicates that a particular field in the ETW event payload template is currently unused.
751 #define ETWLoaderLoadTypeNotAvailable 0 // Static or Dynamic Load is only valid at LoaderPhaseStart and LoaderPhaseEnd events - for other events, 0 indicates "not available"
752 #define ETWLoaderStaticLoad 0 // Static reference load
753 #define ETWLoaderDynamicLoad 1 // Dynamic assembly load
755 #if defined(FEATURE_EVENT_TRACE)
756 // "mc.exe -MOF" already generates this block for XP-suported builds inside ClrEtwAll.h;
757 // on Vista+ builds, mc is run without -MOF, and we still have code that depends on it, so
758 // we manually place it here.
761 McGenEventTracingEnabled(
762 __in PMCGEN_TRACE_CONTEXT EnableInfo,
763 __in PCEVENT_DESCRIPTOR EventDescriptor
773 // Check if the event Level is lower than the level at which
774 // the channel is enabled.
775 // If the event Level is 0 or the channel is enabled at level 0,
776 // all levels are enabled.
779 if ((EventDescriptor->Level <= EnableInfo->Level) || // This also covers the case of Level == 0.
780 (EnableInfo->Level == 0)) {
783 // Check if Keyword is enabled
786 if ((EventDescriptor->Keyword == (ULONGLONG)0) ||
787 ((EventDescriptor->Keyword & EnableInfo->MatchAnyKeyword) &&
788 ((EventDescriptor->Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) {
795 #endif // defined(FEATURE_EVENT_TRACE)
798 #if defined(FEATURE_EVENT_TRACE)
801 ETW::SamplingLog::SendStackTrace(
802 MCGEN_TRACE_CONTEXT TraceContext,
803 PCEVENT_DESCRIPTOR Descriptor,
806 #define ARGUMENT_COUNT_CLRStackWalk 5
807 ULONG Result = ERROR_SUCCESS;
808 typedef struct _MCGEN_TRACE_BUFFER {
809 EVENT_TRACE_HEADER Header;
810 EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_CLRStackWalk];
811 } MCGEN_TRACE_BUFFER;
813 REGHANDLE RegHandle = TraceContext.RegistrationHandle;
814 if(!TraceContext.IsEnabled || !McGenEventTracingEnabled(&TraceContext, Descriptor))
820 UINT32 FrameCount = 0;
821 ETW::SamplingLog stackObj;
822 if(stackObj.GetCurrentThreadsCallStack(&FrameCount, &Stack) == ETW::SamplingLog::Completed)
824 UCHAR Reserved1=0, Reserved2=0;
825 UINT16 ClrInstanceId = GetClrInstanceId();
826 MCGEN_TRACE_BUFFER TraceBuf;
827 PEVENT_DATA_DESCRIPTOR EventData = TraceBuf.EventData;
829 EventDataDescCreate(&EventData[0], &ClrInstanceId, sizeof(const UINT16) );
831 EventDataDescCreate(&EventData[1], &Reserved1, sizeof(const UCHAR) );
833 EventDataDescCreate(&EventData[2], &Reserved2, sizeof(const UCHAR) );
835 EventDataDescCreate(&EventData[3], &FrameCount, sizeof(const unsigned int) );
837 EventDataDescCreate(&EventData[4], Stack, sizeof(PVOID) * FrameCount );
839 return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_CLRStackWalk, EventData);
844 #endif // FEATURE_EVENT_TRACE
846 #ifdef FEATURE_EVENT_TRACE
848 struct CallStackFrame
850 struct CallStackFrame* m_Next;
851 SIZE_T m_ReturnAddress;
853 #endif // _TARGET_X86_
854 #endif // FEATURE_EVENT_TRACE
856 #if defined(FEATURE_EVENT_TRACE)
859 McGenEventProviderEnabled(
860 __in PMCGEN_TRACE_CONTEXT Context,
862 __in ULONGLONG Keyword
870 // Check if the event Level is lower than the level at which
871 // the channel is enabled.
872 // If the event Level is 0 or the channel is enabled at level 0,
873 // all levels are enabled.
876 if ((Level <= Context->Level) || // This also covers the case of Level == 0.
877 (Context->Level == 0)) {
880 // Check if Keyword is enabled
883 if ((Keyword == (ULONGLONG)0) ||
884 ((Keyword & Context->MatchAnyKeyword) &&
885 ((Keyword & Context->MatchAllKeyword) == Context->MatchAllKeyword))) {
891 #endif // FEATURE_EVENT_TRACE
893 #if defined(FEATURE_EVENT_TRACE)
895 // This macro only checks if a provider is enabled
896 // It does not check the flags and keywords for which it is enabled
897 #define ETW_PROVIDER_ENABLED(ProviderSymbol) \
898 ProviderSymbol##_Context.IsEnabled
902 #define ETW_PROVIDER_ENABLED(ProviderSymbol) TRUE
904 #endif // FEATURE_EVENT_TRACE
906 #endif // !FEATURE_REDHAWK
908 // These parts of the ETW namespace are common for both FEATURE_REDHAWK and
909 // !FEATURE_REDHAWK builds.
912 struct ProfilingScanContext;
913 struct ProfilerWalkHeapContext;
918 // Class to wrap the logging of threads (runtime and rundown providers)
922 static DWORD GetEtwThreadFlags(Thread * pThread);
925 static VOID FireThreadCreated(Thread * pThread);
926 static VOID FireThreadDC(Thread * pThread);
930 #ifndef FEATURE_REDHAWK
932 #ifdef FEATURE_EVENT_TRACE
935 // Use this macro at the least before calling the Event Macros
938 #define ETW_TRACING_INITIALIZED(RegHandle) \
939 (g_pEtwTracer && RegHandle)
942 // Use this macro to check if an event is enabled
943 // if the fields in the event are not cheap to calculate
945 #define ETW_EVENT_ENABLED(Context, EventDescriptor) \
946 (MCGEN_ENABLE_CHECK(Context, EventDescriptor))
949 // Use this macro to check if a category of events is enabled
952 #define ETW_CATEGORY_ENABLED(Context, Level, Keyword) \
953 (Context.IsEnabled && McGenEventProviderEnabled(&Context, Level, Keyword))
958 // Special Handling of Startup events
961 #if defined(FEATURE_EVENT_TRACE)
962 // "mc.exe -MOF" already generates this block for XP-suported builds inside ClrEtwAll.h;
963 // on Vista+ builds, mc is run without -MOF, and we still have code that depends on it, so
964 // we manually place it here.
968 __in REGHANDLE RegHandle,
969 __in PCEVENT_DESCRIPTOR Descriptor,
970 __in_opt LPCGUID EventGuid,
971 __in const unsigned short ClrInstanceID
974 #define ARGUMENT_COUNT_h 1
975 ULONG Error = ERROR_SUCCESS;
976 typedef struct _MCGEN_TRACE_BUFFER {
977 EVENT_TRACE_HEADER Header;
978 EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_h];
979 } MCGEN_TRACE_BUFFER;
981 MCGEN_TRACE_BUFFER TraceBuf;
982 PEVENT_DATA_DESCRIPTOR EventData = TraceBuf.EventData;
984 EventDataDescCreate(&EventData[0], &ClrInstanceID, sizeof(const unsigned short) );
988 Error = EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_h, EventData);
993 MCGEN_CALLOUT(RegHandle,
1001 #endif // defined(FEATURE_EVENT_TRACE)
1003 class ETWTraceStartup {
1004 REGHANDLE TraceHandle;
1005 PCEVENT_DESCRIPTOR EventStartDescriptor;
1006 LPCGUID EventStartGuid;
1007 PCEVENT_DESCRIPTOR EventEndDescriptor;
1008 LPCGUID EventEndGuid;
1010 ETWTraceStartup(REGHANDLE _TraceHandle, PCEVENT_DESCRIPTOR _EventStartDescriptor, LPCGUID _EventStartGuid, PCEVENT_DESCRIPTOR _EventEndDescriptor, LPCGUID _EventEndGuid) {
1011 TraceHandle = _TraceHandle;
1012 EventStartDescriptor = _EventStartDescriptor;
1013 EventEndDescriptor = _EventEndDescriptor;
1014 EventStartGuid = _EventStartGuid;
1015 EventEndGuid = _EventEndGuid;
1016 StartupTraceEvent(TraceHandle, EventStartDescriptor, EventStartGuid);
1018 ~ETWTraceStartup() {
1019 StartupTraceEvent(TraceHandle, EventEndDescriptor, EventEndGuid);
1021 static void StartupTraceEvent(REGHANDLE _TraceHandle, PCEVENT_DESCRIPTOR _EventDescriptor, LPCGUID _EventGuid) {
1022 EVENT_DESCRIPTOR desc = *_EventDescriptor;
1023 if(ETW_TRACING_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, desc))
1025 CoMofTemplate_h(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context.RegistrationHandle, _EventDescriptor, _EventGuid, GetClrInstanceId());
1032 #else // FEATURE_EVENT_TRACE
1034 #define ETWOnStartup(StartEventName, EndEventName)
1035 #define ETWFireEvent(EventName)
1037 // Use this macro at the least before calling the Event Macros
1038 #define ETW_TRACING_INITIALIZED(RegHandle) (FALSE)
1040 // Use this macro to check if an event is enabled
1041 // if the fields in the event are not cheap to calculate
1042 #define ETW_EVENT_ENABLED(Context, EventDescriptor) (FALSE)
1044 // Use this macro to check if a category of events is enabled
1045 #define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (FALSE)
1047 // Use this macro to check if ETW is initialized and the event is enabled
1048 #define ETW_TRACING_ENABLED(Context, EventDescriptor) (FALSE)
1050 // Use this macro to check if ETW is initialized and the category is enabled
1051 #define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) (FALSE)
1053 #endif // FEATURE_EVENT_TRACE
1055 #endif // FEATURE_REDHAWK
1057 #endif //_ETWTRACER_HXX_