eac127e732a6cc3d5bd9e321c801b5482cd3ab5b
[platform/upstream/coreclr.git] / src / inc / eventtracebase.h
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 //
5 //
6 // File: eventtracebase.h
7 // Abstract: This module implements base Event Tracing support (excluding some of the
8 // CLR VM-specific ETW helpers).
9 //
10
11 //
12
13 //
14 // 
15 // #EventTracing
16 // Windows
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
26 // provider.
27 // ============================================================================
28
29 #ifndef _ETWTRACER_HXX_
30 #define _ETWTRACER_HXX_
31
32 struct EventStructTypeData;
33 void InitializeEventTracing();
34
35 // !!!!!!! NOTE !!!!!!!!
36 // The flags must match those in the ETW manifest exactly
37 // !!!!!!! NOTE !!!!!!!!
38
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.
41
42 enum EtwGCRootFlags
43 {
44     kEtwGCRootFlagsPinning =            0x1,
45     kEtwGCRootFlagsWeakRef =            0x2,
46     kEtwGCRootFlagsInterior =           0x4,
47     kEtwGCRootFlagsRefCounted =         0x8,
48 };
49
50 enum EtwGCRootKind
51 {
52     kEtwGCRootKindStack =               0,
53     kEtwGCRootKindFinalizer =           1,
54     kEtwGCRootKindHandle =              2,
55     kEtwGCRootKindOther =               3,
56 };
57
58 enum EtwTypeFlags
59 {
60     kEtwTypeFlagsDelegate =                         0x1,
61     kEtwTypeFlagsFinalizable =                      0x2,
62     kEtwTypeFlagsExternallyImplementedCOMObject =   0x4,
63     kEtwTypeFlagsArray =                            0x8,
64 };
65
66 enum EtwThreadFlags
67 {
68     kEtwThreadFlagGCSpecial =         0x00000001,
69     kEtwThreadFlagFinalizer =         0x00000002,
70     kEtwThreadFlagThreadPoolWorker =  0x00000004,
71 };
72
73 #ifdef FEATURE_EVENT_TRACE
74
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
78 // GC heap walker.
79 struct ProfilerWalkHeapContext
80 {
81 public:
82     ProfilerWalkHeapContext(BOOL fProfilerPinnedParam, LPVOID pvEtwContextParam)
83     {
84         fProfilerPinned = fProfilerPinnedParam;
85         pvEtwContext = pvEtwContextParam;
86     }
87
88     BOOL fProfilerPinned;
89     LPVOID pvEtwContext;
90 };
91
92 class Object;
93
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.
99
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
110
111 struct ProfilingScanContext;
112
113 //
114 // Use this macro to check if ETW is initialized and the event is enabled
115 //
116 #define ETW_TRACING_ENABLED(Context, EventDescriptor) \
117     (Context.IsEnabled && ETW_TRACING_INITIALIZED(Context.RegistrationHandle) && ETW_EVENT_ENABLED(Context, EventDescriptor))
118
119 //
120 // Using KEYWORDZERO means when checking the events category ignore the keyword
121 //
122 #define KEYWORDZERO 0x0
123
124 //
125 // Use this macro to check if ETW is initialized and the category is enabled
126 //
127 #define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) \
128     (ETW_TRACING_INITIALIZED(Context.RegistrationHandle) && ETW_CATEGORY_ENABLED(Context, Level, Keyword))
129
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);
134
135 #ifndef FEATURE_REDHAWK
136
137 // Headers
138 #include <initguid.h>
139 #include <wmistr.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))
144 #else
145 #define GetVersionEx(Version) (WszGetVersionEx((LPOSVERSIONINFOW)Version))
146 #endif // !DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE
147
148 #endif //!FEATURE_REDHAWK
149
150
151 #else // FEATURE_EVENT_TRACE
152
153 #include "etmdummy.h"
154 #endif // FEATURE_EVENT_TRACE
155
156 #ifndef FEATURE_REDHAWK
157
158 #include "corprof.h"
159
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;
165
166 #define GetClrInstanceId()  (static_cast<UINT16>(g_nClrInstanceId))
167
168 #if defined(FEATURE_EVENT_TRACE)
169 // Callback and stack support
170 #if !defined(DONOT_DEFINE_ETW_CALLBACK) && !defined(DACCESS_COMPILE)
171 extern "C" {
172     /* ETW control callback
173          * Desc:        This function handles the ETW control
174          *              callback.
175          * Ret:         success or failure
176      ***********************************************/
177     VOID EtwCallback(
178         _In_ LPCGUID SourceId,
179         _In_ ULONG ControlCode,
180         _In_ UCHAR Level,
181         _In_ ULONGLONG MatchAnyKeyword,
182         _In_ ULONGLONG MatchAllKeyword,
183         _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
184         _Inout_opt_ PVOID CallbackContext);
185 }
186
187 //
188 // User defined callback
189 //
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)
192
193 //
194 // User defined callback2
195 //
196 #define MCGEN_PRIVATE_ENABLE_CALLBACK_V2(SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeyword, FilterData, CallbackContext) \
197         EtwCallback(SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeyword, FilterData, CallbackContext)
198
199 extern "C" {
200     /* ETW callout
201          * Desc:        This function handles the ETW callout
202          * Ret:         success or failure
203      ***********************************************/
204     VOID EtwCallout(
205         REGHANDLE RegHandle,
206         PCEVENT_DESCRIPTOR Descriptor,
207         ULONG ArgumentCount,
208         PEVENT_DATA_DESCRIPTOR EventData);
209 }
210
211 //
212 // Call user defined callout
213 //
214 #define MCGEN_CALLOUT(RegHandle, Descriptor, NumberOfArguments, EventData) \
215         EtwCallout(RegHandle, Descriptor, NumberOfArguments, EventData)
216 #endif //!DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE
217
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 
225
226 /**************************/
227 /* CLR ETW infrastructure */
228 /**************************/
229 // #CEtwTracer
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.
243 // 
244
245 #include "daccess.h"
246 class Module;
247 class Assembly;
248 class MethodDesc;
249 class MethodTable;
250 class BaseDomain;
251 class AppDomain;
252 class SString;
253 class CrawlFrame;
254 class LoaderAllocator;
255 class AssemblyLoaderAllocator;
256 struct AllLoggedTypes;
257 class CrstBase;
258 class BulkTypeEventLogger;
259 class TypeHandle;
260 class Thread;
261
262
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
267 namespace ETW
268 {
269     // Class to wrap the ETW infrastructure logic
270     class CEtwTracer 
271     {
272 #if defined(FEATURE_EVENT_TRACE)
273         ULONG RegGuids(LPCGUID ProviderId, PENABLECALLBACK EnableCallback, PVOID CallbackContext, PREGHANDLE RegHandle);
274 #endif
275
276     public:
277 #ifdef FEATURE_EVENT_TRACE
278         // Registers all the Event Tracing providers
279         HRESULT Register();
280
281         // Unregisters all the Event Tracing providers
282         HRESULT UnRegister();        
283 #else
284         HRESULT Register()
285         {
286             return S_OK;
287         }
288         HRESULT UnRegister()
289         {
290             return S_OK;
291         }
292 #endif // FEATURE_EVENT_TRACE
293     };
294
295     class LoaderLog;
296     class MethodLog;   
297     // Class to wrap all the enumeration logic for ETW
298     class EnumerationLog
299     {
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();
311     public:
312         typedef union _EnumerationStructs
313         {
314             typedef enum _EnumerationOptions
315             {
316                 None=                               0x00000000,
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,
337                 
338                 // Helpers
339                 ModuleRangeEnabledAny = ModuleRangeLoad | ModuleRangeDCStart | ModuleRangeDCEnd | ModuleRangeLoadPrivate,
340                 JitMethodLoadOrDCStartAny = JitMethodLoad | JitMethodDCStart | MethodDCStartILToNativeMap,
341                 JitMethodUnloadOrDCEndAny = JitMethodUnload | JitMethodDCEnd | MethodDCEndILToNativeMap,
342             }EnumerationOptions;
343         }EnumerationStructs;
344
345         static VOID ProcessShutdown();
346         static VOID ModuleRangeRundown();
347         static VOID StartRundown();
348         static VOID EndRundown();
349         static VOID EnumerateForCaptureState();
350 #else
351     public:
352         static VOID ProcessShutdown() {};
353         static VOID StartRundown() {};
354         static VOID EndRundown() {};
355 #endif // FEATURE_EVENT_TRACE
356     };
357
358
359     // Class to wrap all the sampling logic for ETW
360     class SamplingLog
361     {
362 #if defined(FEATURE_EVENT_TRACE)
363     public:
364         typedef enum _EtwStackWalkStatus 
365         {
366             Completed = 0,
367             UnInitialized = 1,
368             InProgress = 2
369         } EtwStackWalkStatus;
370     private:
371         static const UINT8 s_MaxStackSize=100;
372         UINT32 m_FrameCount;
373         SIZE_T m_EBPStack[SamplingLog::s_MaxStackSize];
374         VOID Append(SIZE_T currentFrame);
375         EtwStackWalkStatus SaveCurrentStack(int skipTopNFrames=1);
376     public:
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
380     };
381     
382     // Class to wrap all Loader logic for ETW
383     class LoaderLog
384     {
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);
391     public:
392         typedef union _LoaderStructs
393         {
394             typedef enum _AppDomainFlags
395             {
396                 DefaultDomain=0x1,
397                 ExecutableDomain=0x2,
398                 SharedDomain=0x4
399             }AppDomainFlags;
400
401             typedef enum _AssemblyFlags
402             {
403                 DomainNeutralAssembly=0x1,
404                 DynamicAssembly=0x2,
405                 NativeAssembly=0x4,
406                 CollectibleAssembly=0x8,
407             }AssemblyFlags;
408
409             typedef enum _ModuleFlags
410             {
411                 DomainNeutralModule=0x1,
412                 NativeModule=0x2,
413                 DynamicModule=0x4,
414                 ManifestModule=0x8,
415                 IbcOptimized=0x10
416             }ModuleFlags;
417
418             typedef enum _RangeFlags
419             {
420                 HotRange=0x0
421             }RangeFlags;
422
423         }LoaderStructs;
424         
425         static VOID DomainLoadReal(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName=NULL);
426         
427         static VOID DomainLoad(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName = NULL)
428         {
429             if (MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context.IsEnabled)
430             {
431                 DomainLoadReal(pDomain, wszFriendlyName);
432             }
433         }
434
435         static VOID DomainUnload(AppDomain *pDomain);
436         static VOID CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator);
437         static VOID ModuleLoad(Module *pModule, LONG liReportedSharedModule);
438 #else
439     public:
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
445     };
446
447     // Class to wrap all Method logic for ETW
448     class MethodLog
449     {
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,
456             BOOL fLoadOrDCStart,
457             BOOL fUnloadOrDCEnd,
458             BOOL fSendMethodEvent,
459             BOOL fSendILToNativeMapEvent,
460             BOOL fGetReJitIDs);
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);
466     public:
467         typedef union _MethodStructs
468         {
469             typedef enum _MethodFlags
470             {
471                 DynamicMethod=0x1,
472                 GenericMethod=0x2,
473                 SharedGenericCode=0x4,
474                 JittedMethod=0x8,
475                 JitHelperMethod=0x10
476             }MethodFlags;
477
478             typedef enum _MethodExtent
479             {
480                 HotSection=0x00000000,
481                 ColdSection=0x10000000
482             }MethodExtent;
483
484         }MethodStructs;
485
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
494     public:
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
503     };
504
505     // Class to wrap all Security logic for ETW
506     class SecurityLog
507     {
508 #ifdef FEATURE_EVENT_TRACE
509     public:
510         static VOID StrongNameVerificationStart(DWORD dwInFlags, __in LPWSTR strFullyQualifiedAssemblyName);
511         static VOID StrongNameVerificationStop(DWORD dwInFlags,ULONG result, __in LPWSTR strFullyQualifiedAssemblyName);
512
513         static void FireFieldTransparencyComputationStart(LPCWSTR wszFieldName,
514                                                           LPCWSTR wszModuleName,
515                                                           DWORD dwAppDomain);
516         static void FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
517                                                         LPCWSTR wszModuleName,
518                                                         DWORD dwAppDomain,
519                                                         BOOL fIsCritical,
520                                                         BOOL fIsTreatAsSafe);
521
522         static void FireMethodTransparencyComputationStart(LPCWSTR wszMethodName,
523                                                            LPCWSTR wszModuleName,
524                                                            DWORD dwAppDomain);
525         static void FireMethodTransparencyComputationEnd(LPCWSTR wszMethodName,
526                                                          LPCWSTR wszModuleName,
527                                                          DWORD dwAppDomain,
528                                                          BOOL fIsCritical,
529                                                          BOOL fIsTreatAsSafe);
530
531         static void FireModuleTransparencyComputationStart(LPCWSTR wszModuleName, DWORD dwAppDomain);
532         static void FireModuleTransparencyComputationEnd(LPCWSTR wszModuleName,
533                                                          DWORD dwAppDomain,
534                                                          BOOL fIsAllCritical,
535                                                          BOOL fIsAllTransparent,
536                                                          BOOL fIsTreatAsSafe,
537                                                          BOOL fIsOpportunisticallyCritical,
538                                                          DWORD dwSecurityRuleSet);
539
540         static void FireTokenTransparencyComputationStart(DWORD dwToken,
541                                                           LPCWSTR wszModuleName,
542                                                           DWORD dwAppDomain);
543         static void FireTokenTransparencyComputationEnd(DWORD dwToken,
544                                                         LPCWSTR wszModuleName,
545                                                         DWORD dwAppDomain,
546                                                         BOOL fIsCritical,
547                                                         BOOL fIsTreatAsSafe);
548
549         static void FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
550                                                          LPCWSTR wszModuleName,
551                                                          DWORD dwAppDomain);
552         static void FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
553                                                        LPCWSTR wszModuleName,
554                                                        DWORD dwAppDomain,
555                                                        BOOL fIsAllCritical,
556                                                        BOOL fIsAllTransparent,
557                                                        BOOL fIsCritical,
558                                                        BOOL fIsTreatAsSafe);
559 #else
560     public:
561         static VOID StrongNameVerificationStart(DWORD dwInFlags,LPWSTR strFullyQualifiedAssemblyName) {};
562         static VOID StrongNameVerificationStop(DWORD dwInFlags,ULONG result, LPWSTR strFullyQualifiedAssemblyName) {};
563
564         static void FireFieldTransparencyComputationStart(LPCWSTR wszFieldName,
565                                                           LPCWSTR wszModuleName,
566                                                           DWORD dwAppDomain) {};
567         static void FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
568                                                         LPCWSTR wszModuleName,
569                                                         DWORD dwAppDomain,
570                                                         BOOL fIsCritical,
571                                                         BOOL fIsTreatAsSafe) {};
572
573         static void FireMethodTransparencyComputationStart(LPCWSTR wszMethodName,
574                                                            LPCWSTR wszModuleName,
575                                                            DWORD dwAppDomain) {};
576         static void FireMethodTransparencyComputationEnd(LPCWSTR wszMethodName,
577                                                          LPCWSTR wszModuleName,
578                                                          DWORD dwAppDomain,
579                                                          BOOL fIsCritical,
580                                                          BOOL fIsTreatAsSafe) {};
581
582         static void FireModuleTransparencyComputationStart(LPCWSTR wszModuleName, DWORD dwAppDomain) {};
583         static void FireModuleTransparencyComputationEnd(LPCWSTR wszModuleName,
584                                                          DWORD dwAppDomain,
585                                                          BOOL fIsAllCritical,
586                                                          BOOL fIsAllTransparent,
587                                                          BOOL fIsTreatAsSafe,
588                                                          BOOL fIsOpportunisticallyCritical,
589                                                          DWORD dwSecurityRuleSet) {};
590
591         static void FireTokenTransparencyComputationStart(DWORD dwToken,
592                                                           LPCWSTR wszModuleName,
593                                                           DWORD dwAppDomain) {};
594         static void FireTokenTransparencyComputationEnd(DWORD dwToken,
595                                                         LPCWSTR wszModuleName,
596                                                         DWORD dwAppDomain,
597                                                         BOOL fIsCritical,
598                                                         BOOL fIsTreatAsSafe) {};
599
600         static void FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
601                                                          LPCWSTR wszModuleName,
602                                                          DWORD dwAppDomain) {};
603         static void FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
604                                                        LPCWSTR wszModuleName,
605                                                        DWORD dwAppDomain,
606                                                        BOOL fIsAllCritical,
607                                                        BOOL fIsAllTransparent,
608                                                        BOOL fIsCritical,
609                                                        BOOL fIsTreatAsSafe) {};
610 #endif // FEATURE_EVENT_TRACE
611     };
612
613     // Class to wrap all Binder logic for ETW
614     class BinderLog
615     {
616     public:
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,
624                 NGEN_BIND_FAIL = 5,
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;
644         } BinderStructs;
645     };
646
647     // Class to wrap all Exception logic for ETW
648     class ExceptionLog
649     {
650     public:
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();
660
661 #else
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
672         {
673             typedef enum _ExceptionThrownFlags
674             {
675                 HasInnerException=0x1,
676                 IsNestedException=0x2,
677                 IsReThrownException=0x4,
678                 IsCSE=0x8,
679                 IsCLSCompliant=0x10
680             }ExceptionThrownFlags;
681         }ExceptionStructs;
682     };    
683     // Class to wrap all Contention logic for ETW
684     class ContentionLog
685     {
686     public:
687         typedef union _ContentionStructs 
688         {
689             typedef  enum _ContentionFlags { 
690                 ManagedContention=0,
691                 NativeContention=1
692             } ContentionFlags;
693         } ContentionStructs;
694     };    
695     // Class to wrap all Interop logic for ETW
696     class InteropLog
697     {
698     public:
699     };
700
701     // Class to wrap all Information logic for ETW
702     class InfoLog
703     {
704     public:
705         typedef union _InfoStructs 
706         {
707             typedef enum _StartupMode
708             {
709                 ManagedExe=0x1,
710                 HostedCLR=0x2,
711                 IJW=0x4,
712                 COMActivated=0x8,
713                 Other=0x10
714             }StartupMode;
715
716             typedef enum _Sku
717             {
718                 DesktopCLR=0x1,
719                 CoreCLR=0x2
720             }Sku;
721
722             typedef enum _EtwMode
723             {
724                 Normal=0x0,
725                 Callback=0x1
726             }EtwMode;
727         }InfoStructs;
728
729 #ifdef FEATURE_EVENT_TRACE
730         static VOID RuntimeInformation(INT32 type);
731 #else
732         static VOID RuntimeInformation(INT32 type) {};
733 #endif // FEATURE_EVENT_TRACE
734     };
735 };
736
737
738 //
739 // The ONE and only ONE global instantiation of this class
740 //
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
744
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
748
749 #define ETWFieldUnused 0 // Indicates that a particular field in the ETW event payload template is currently unused.
750
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
754
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.
759 FORCEINLINE 
760 BOOLEAN __stdcall
761 McGenEventTracingEnabled(
762     __in PMCGEN_TRACE_CONTEXT EnableInfo,
763     __in PCEVENT_DESCRIPTOR EventDescriptor
764     )
765 {
766
767     if(!EnableInfo){
768         return FALSE;
769     }
770
771
772     //
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.
777     //
778
779     if ((EventDescriptor->Level <= EnableInfo->Level) || // This also covers the case of Level == 0.
780         (EnableInfo->Level == 0)) {
781
782         //
783         // Check if Keyword is enabled
784         //
785
786         if ((EventDescriptor->Keyword == (ULONGLONG)0) ||
787             ((EventDescriptor->Keyword & EnableInfo->MatchAnyKeyword) &&
788              ((EventDescriptor->Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) {
789             return TRUE;
790         }
791     }
792
793     return FALSE;
794 }
795 #endif // defined(FEATURE_EVENT_TRACE)
796
797
798 #if defined(FEATURE_EVENT_TRACE)
799 ETW_INLINE
800 ULONG
801 ETW::SamplingLog::SendStackTrace(
802     MCGEN_TRACE_CONTEXT TraceContext,
803     PCEVENT_DESCRIPTOR Descriptor,
804     LPCGUID EventGuid)
805 {
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;
812
813     REGHANDLE RegHandle = TraceContext.RegistrationHandle;
814     if(!TraceContext.IsEnabled || !McGenEventTracingEnabled(&TraceContext, Descriptor))
815     {
816         return Result;
817     }
818
819     PVOID *Stack = NULL;
820     UINT32 FrameCount = 0;
821     ETW::SamplingLog stackObj;
822     if(stackObj.GetCurrentThreadsCallStack(&FrameCount, &Stack) == ETW::SamplingLog::Completed)
823     {
824         UCHAR Reserved1=0, Reserved2=0;
825         UINT16 ClrInstanceId = GetClrInstanceId();
826         MCGEN_TRACE_BUFFER TraceBuf;
827         PEVENT_DATA_DESCRIPTOR EventData = TraceBuf.EventData;
828
829         EventDataDescCreate(&EventData[0], &ClrInstanceId, sizeof(const UINT16)  );
830
831         EventDataDescCreate(&EventData[1], &Reserved1, sizeof(const UCHAR)  );
832
833         EventDataDescCreate(&EventData[2], &Reserved2, sizeof(const UCHAR)  );
834
835         EventDataDescCreate(&EventData[3], &FrameCount, sizeof(const unsigned int)  );
836
837         EventDataDescCreate(&EventData[4], Stack, sizeof(PVOID) * FrameCount );
838
839         return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_CLRStackWalk, EventData);
840     }
841     return Result;
842 };
843
844 #endif // FEATURE_EVENT_TRACE
845
846 #ifdef FEATURE_EVENT_TRACE
847 #ifdef _TARGET_X86_
848 struct CallStackFrame
849 {
850     struct CallStackFrame* m_Next;
851     SIZE_T m_ReturnAddress;
852 };
853 #endif // _TARGET_X86_
854 #endif // FEATURE_EVENT_TRACE
855
856 #if defined(FEATURE_EVENT_TRACE)
857 FORCEINLINE 
858 BOOLEAN __stdcall
859 McGenEventProviderEnabled(
860     __in PMCGEN_TRACE_CONTEXT Context,
861     __in UCHAR Level,
862     __in ULONGLONG Keyword
863     )
864 {
865     if(!Context) {
866         return FALSE;
867     }
868
869     //
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.
874     //
875
876     if ((Level <= Context->Level) || // This also covers the case of Level == 0.
877         (Context->Level == 0)) {
878
879         //
880         // Check if Keyword is enabled
881         //
882
883         if ((Keyword == (ULONGLONG)0) ||
884             ((Keyword & Context->MatchAnyKeyword) &&
885              ((Keyword & Context->MatchAllKeyword) == Context->MatchAllKeyword))) {
886             return TRUE;
887         }
888     }
889     return FALSE;
890 }
891 #endif // FEATURE_EVENT_TRACE
892
893 #if defined(FEATURE_EVENT_TRACE)
894
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
899
900 #else
901
902 #define ETW_PROVIDER_ENABLED(ProviderSymbol) TRUE
903
904 #endif // FEATURE_EVENT_TRACE
905
906 #endif // !FEATURE_REDHAWK
907
908 // These parts of the ETW namespace are common for both FEATURE_REDHAWK and
909 // !FEATURE_REDHAWK builds.
910
911
912 struct ProfilingScanContext;
913 struct ProfilerWalkHeapContext;
914 class Object;
915
916 namespace ETW
917 {
918     // Class to wrap the logging of threads (runtime and rundown providers)
919     class ThreadLog
920     {
921     private:
922         static DWORD GetEtwThreadFlags(Thread * pThread);
923
924     public:
925         static VOID FireThreadCreated(Thread * pThread);
926         static VOID FireThreadDC(Thread * pThread);
927     };
928 };
929
930 #ifndef FEATURE_REDHAWK
931
932 #ifdef FEATURE_EVENT_TRACE
933
934 //
935 // Use this macro at the least before calling the Event Macros
936 //
937
938 #define ETW_TRACING_INITIALIZED(RegHandle) \
939     (g_pEtwTracer && RegHandle)
940
941 //
942 // Use this macro to check if an event is enabled
943 // if the fields in the event are not cheap to calculate
944 //
945 #define ETW_EVENT_ENABLED(Context, EventDescriptor) \
946     (MCGEN_ENABLE_CHECK(Context, EventDescriptor))
947
948 //
949 // Use this macro to check if a category of events is enabled
950 // 
951
952 #define ETW_CATEGORY_ENABLED(Context, Level, Keyword) \
953     (Context.IsEnabled && McGenEventProviderEnabled(&Context, Level, Keyword))
954
955
956
957 //
958 // Special Handling of Startup events
959 //
960
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.
965 ETW_INLINE
966 ULONG
967 CoMofTemplate_h(
968     __in REGHANDLE RegHandle,
969     __in PCEVENT_DESCRIPTOR Descriptor,
970     __in_opt LPCGUID EventGuid,
971     __in const unsigned short  ClrInstanceID
972     )
973 {
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;
980
981     MCGEN_TRACE_BUFFER TraceBuf;
982     PEVENT_DATA_DESCRIPTOR EventData = TraceBuf.EventData;
983
984     EventDataDescCreate(&EventData[0], &ClrInstanceID, sizeof(const unsigned short)  );
985
986
987   {
988     Error = EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_h, EventData);
989
990   }
991
992 #ifdef MCGEN_CALLOUT
993 MCGEN_CALLOUT(RegHandle,
994               Descriptor,
995               ARGUMENT_COUNT_h,
996               EventData);
997 #endif
998
999     return Error;
1000 }
1001 #endif // defined(FEATURE_EVENT_TRACE)
1002
1003 class ETWTraceStartup {
1004     REGHANDLE TraceHandle;
1005     PCEVENT_DESCRIPTOR EventStartDescriptor;
1006     LPCGUID EventStartGuid;
1007     PCEVENT_DESCRIPTOR EventEndDescriptor;
1008     LPCGUID EventEndGuid;
1009 public:
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);
1017     }
1018     ~ETWTraceStartup() {
1019         StartupTraceEvent(TraceHandle, EventEndDescriptor, EventEndGuid);
1020     }
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))
1024         {
1025             CoMofTemplate_h(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context.RegistrationHandle, _EventDescriptor, _EventGuid, GetClrInstanceId());
1026         }
1027     }
1028 };
1029
1030
1031
1032 #else // FEATURE_EVENT_TRACE
1033
1034 #define ETWOnStartup(StartEventName, EndEventName)
1035 #define ETWFireEvent(EventName)
1036
1037 // Use this macro at the least before calling the Event Macros
1038 #define ETW_TRACING_INITIALIZED(RegHandle) (FALSE)
1039
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)
1043
1044 // Use this macro to check if a category of events is enabled
1045 #define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (FALSE)
1046
1047 // Use this macro to check if ETW is initialized and the event is enabled
1048 #define ETW_TRACING_ENABLED(Context, EventDescriptor) (FALSE)
1049
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)
1052
1053 #endif // FEATURE_EVENT_TRACE  
1054
1055 #endif // FEATURE_REDHAWK
1056
1057 #endif //_ETWTRACER_HXX_