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// See the LICENSE file in the project root for more information.
4//
5// File: eventtracebase.h
6// Abstract: This module implements base Event Tracing support (excluding some of the
7// CLR VM-specific ETW helpers).
8//
9
10//
11
12//
13//
14// #EventTracing
15// Windows
16// ETW (Event Tracing for Windows) is a high-performance, low overhead and highly scalable
17// tracing facility provided by the Windows Operating System. ETW is available on Win2K and above. There are
18// four main types of components in ETW: event providers, controllers, consumers, and event trace sessions.
19// An event provider is a logical entity that writes events to ETW sessions. The event provider must register
20// a provider ID with ETW through the registration API. A provider first registers with ETW and writes events
21// from various points in the code by invoking the ETW logging API. When a provider is enabled dynamically by
22// the ETW controller application, calls to the logging API sends events to a specific trace session
23// designated by the controller. Each event sent by the event provider to the trace session consists of a
24// fixed header that includes event metadata and additional variable user-context data. CLR is an event
25// provider.
26// ============================================================================
27
28#ifndef _ETWTRACER_HXX_
29#define _ETWTRACER_HXX_
30
31struct EventStructTypeData;
32void InitializeEventTracing();
33
34// !!!!!!! NOTE !!!!!!!!
35// The flags must match those in the ETW manifest exactly
36// !!!!!!! NOTE !!!!!!!!
37
38// These flags need to be defined either when FEATURE_EVENT_TRACE is enabled or the
39// PROFILING_SUPPORTED is set, since they are used both by event tracing and profiling.
40
41enum EtwTypeFlags
42{
43 kEtwTypeFlagsDelegate = 0x1,
44 kEtwTypeFlagsFinalizable = 0x2,
45 kEtwTypeFlagsExternallyImplementedCOMObject = 0x4,
46 kEtwTypeFlagsArray = 0x8,
47};
48
49enum EtwThreadFlags
50{
51 kEtwThreadFlagGCSpecial = 0x00000001,
52 kEtwThreadFlagFinalizer = 0x00000002,
53 kEtwThreadFlagThreadPoolWorker = 0x00000004,
54};
55
56#ifndef FEATURE_REDHAWK
57
58#if defined(FEATURE_EVENT_TRACE)
59
60#if defined(FEATURE_PERFTRACING)
61#define EVENT_PIPE_ENABLED() (EventPipeHelper::Enabled())
62#else
63#define EVENT_PIPE_ENABLED() (FALSE)
64#endif
65
66#if !defined(FEATURE_PAL)
67
68//
69// Use this macro at the least before calling the Event Macros
70//
71
72#define ETW_TRACING_INITIALIZED(RegHandle) \
73 ((g_pEtwTracer && RegHandle) || EVENT_PIPE_ENABLED())
74
75//
76// Use this macro to check if an event is enabled
77// if the fields in the event are not cheap to calculate
78//
79#define ETW_EVENT_ENABLED(Context, EventDescriptor) \
80 ((MCGEN_ENABLE_CHECK(Context, EventDescriptor)) || EVENT_PIPE_ENABLED())
81
82//
83// Use this macro to check if a category of events is enabled
84//
85
86#define ETW_CATEGORY_ENABLED(Context, Level, Keyword) \
87 ((Context.IsEnabled && McGenEventProviderEnabled(&Context, Level, Keyword)) || EVENT_PIPE_ENABLED())
88
89
90// This macro only checks if a provider is enabled
91// It does not check the flags and keywords for which it is enabled
92#define ETW_PROVIDER_ENABLED(ProviderSymbol) \
93 ((ProviderSymbol##_Context.IsEnabled) || EVENT_PIPE_ENABLED())
94
95
96#else //defined(FEATURE_PAL)
97#if defined(FEATURE_PERFTRACING)
98#define ETW_INLINE
99#define ETWOnStartup(StartEventName, EndEventName)
100#define ETWFireEvent(EventName)
101
102#define ETW_TRACING_INITIALIZED(RegHandle) (TRUE)
103#define ETW_EVENT_ENABLED(Context, EventDescriptor) (EventPipeHelper::Enabled() || XplatEventLogger::IsEventLoggingEnabled())
104#define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (EventPipeHelper::Enabled() || XplatEventLogger::IsEventLoggingEnabled())
105#define ETW_TRACING_ENABLED(Context, EventDescriptor) (EventEnabled##EventDescriptor())
106#define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) (EventPipeHelper::Enabled() || XplatEventLogger::IsEventLoggingEnabled())
107#define ETW_PROVIDER_ENABLED(ProviderSymbol) (TRUE)
108#else //defined(FEATURE_PERFTRACING)
109#define ETW_INLINE
110#define ETWOnStartup(StartEventName, EndEventName)
111#define ETWFireEvent(EventName)
112
113#define ETW_TRACING_INITIALIZED(RegHandle) (TRUE)
114#define ETW_EVENT_ENABLED(Context, EventDescriptor) (XplatEventLogger::IsEventLoggingEnabled())
115#define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (XplatEventLogger::IsEventLoggingEnabled())
116#define ETW_TRACING_ENABLED(Context, EventDescriptor) (EventEnabled##EventDescriptor())
117#define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) (XplatEventLogger::IsEventLoggingEnabled())
118#define ETW_PROVIDER_ENABLED(ProviderSymbol) (TRUE)
119#endif // defined(FEATURE_PERFTRACING)
120#endif // !defined(FEATURE_PAL)
121
122#else // FEATURE_EVENT_TRACE
123
124#define ETWOnStartup(StartEventName, EndEventName)
125#define ETWFireEvent(EventName)
126
127#define ETW_TRACING_INITIALIZED(RegHandle) (FALSE)
128#define ETW_EVENT_ENABLED(Context, EventDescriptor) (FALSE)
129#define ETW_CATEGORY_ENABLED(Context, Level, Keyword) (FALSE)
130#define ETW_TRACING_ENABLED(Context, EventDescriptor) (FALSE)
131#define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) (FALSE)
132#define ETW_PROVIDER_ENABLED(ProviderSymbol) (TRUE)
133
134#endif // FEATURE_EVENT_TRACE
135
136#endif // FEATURE_REDHAWK
137
138// During a heap walk, this is the storage for keeping track of all the nodes and edges
139// being batched up by ETW, and for remembering whether we're also supposed to call into
140// a profapi profiler. This is allocated toward the end of a GC and passed to us by the
141// GC heap walker.
142struct ProfilerWalkHeapContext
143{
144public:
145 ProfilerWalkHeapContext(BOOL fProfilerPinnedParam, LPVOID pvEtwContextParam)
146 {
147 fProfilerPinned = fProfilerPinnedParam;
148 pvEtwContext = pvEtwContextParam;
149 }
150
151 BOOL fProfilerPinned;
152 LPVOID pvEtwContext;
153};
154
155#ifdef FEATURE_EVENT_TRACE
156
157class Object;
158#if !defined(FEATURE_PAL)
159
160/***************************************/
161/* Tracing levels supported by CLR ETW */
162/***************************************/
163#define ETWMAX_TRACE_LEVEL 6 // Maximum Number of Trace Levels supported
164#define TRACE_LEVEL_NONE 0 // Tracing is not on
165#define TRACE_LEVEL_FATAL 1 // Abnormal exit or termination
166#define TRACE_LEVEL_ERROR 2 // Severe errors that need logging
167#define TRACE_LEVEL_WARNING 3 // Warnings such as allocation failure
168#define TRACE_LEVEL_INFORMATION 4 // Includes non-error cases such as Entry-Exit
169#define TRACE_LEVEL_VERBOSE 5 // Detailed traces from intermediate steps
170
171struct ProfilingScanContext;
172
173//
174// Use this macro to check if ETW is initialized and the event is enabled
175//
176#define ETW_TRACING_ENABLED(Context, EventDescriptor) \
177 ((Context.IsEnabled && ETW_TRACING_INITIALIZED(Context.RegistrationHandle) && ETW_EVENT_ENABLED(Context, EventDescriptor)) || EVENT_PIPE_ENABLED())
178
179//
180// Using KEYWORDZERO means when checking the events category ignore the keyword
181//
182#define KEYWORDZERO 0x0
183
184//
185// Use this macro to check if ETW is initialized and the category is enabled
186//
187#define ETW_TRACING_CATEGORY_ENABLED(Context, Level, Keyword) \
188 ((ETW_TRACING_INITIALIZED(Context.RegistrationHandle) && ETW_CATEGORY_ENABLED(Context, Level, Keyword)) || EVENT_PIPE_ENABLED())
189
190 #define ETWOnStartup(StartEventName, EndEventName) \
191 ETWTraceStartup trace##StartEventName##(Microsoft_Windows_DotNETRuntimePrivateHandle, &StartEventName, &StartupId, &EndEventName, &StartupId);
192 #define ETWFireEvent(EventName) \
193 ETWTraceStartup::StartupTraceEvent(Microsoft_Windows_DotNETRuntimePrivateHandle, &EventName, &StartupId);
194
195#ifndef FEATURE_REDHAWK
196// Headers
197#include <initguid.h>
198#include <wmistr.h>
199#include <evntrace.h>
200#include <evntprov.h>
201#endif //!FEATURE_REDHAWK
202#endif //!defined(FEATURE_PAL)
203
204
205#else // FEATURE_EVENT_TRACE
206
207#include "etmdummy.h"
208#endif // FEATURE_EVENT_TRACE
209
210#ifndef FEATURE_REDHAWK
211
212#include "corprof.h"
213
214// g_nClrInstanceId is defined in Utilcode\Util.cpp. The definition goes into Utilcode.lib.
215// This enables both the VM and Utilcode to raise ETW events.
216extern UINT32 g_nClrInstanceId;
217
218#define GetClrInstanceId() (static_cast<UINT16>(g_nClrInstanceId))
219
220#if defined(FEATURE_PERFTRACING)
221class EventPipeHelper
222{
223public:
224 static bool Enabled();
225};
226#endif // defined(FEATURE_PERFTRACING)
227
228#if defined(FEATURE_EVENT_TRACE) || defined(FEATURE_EVENTSOURCE_XPLAT)
229
230#include "clrconfig.h"
231 class XplatEventLogger
232{
233 public:
234 inline static BOOL IsEventLoggingEnabled()
235 {
236 static ConfigDWORD configEventLogging;
237 return configEventLogging.val(CLRConfig::EXTERNAL_EnableEventLog);
238 }
239};
240
241#endif //defined(FEATURE_EVENT_TRACE)
242
243#if defined(FEATURE_EVENT_TRACE)
244
245struct EventFilterDescriptor;
246
247VOID EventPipeEtwCallbackDotNETRuntimeStress(
248 _In_ LPCGUID SourceId,
249 _In_ ULONG ControlCode,
250 _In_ UCHAR Level,
251 _In_ ULONGLONG MatchAnyKeyword,
252 _In_ ULONGLONG MatchAllKeyword,
253 _In_opt_ EventFilterDescriptor* FilterData,
254 _Inout_opt_ PVOID CallbackContext);
255
256VOID EventPipeEtwCallbackDotNETRuntime(
257 _In_ LPCGUID SourceId,
258 _In_ ULONG ControlCode,
259 _In_ UCHAR Level,
260 _In_ ULONGLONG MatchAnyKeyword,
261 _In_ ULONGLONG MatchAllKeyword,
262 _In_opt_ EventFilterDescriptor* FilterData,
263 _Inout_opt_ PVOID CallbackContext);
264
265VOID EventPipeEtwCallbackDotNETRuntimeRundown(
266 _In_ LPCGUID SourceId,
267 _In_ ULONG ControlCode,
268 _In_ UCHAR Level,
269 _In_ ULONGLONG MatchAnyKeyword,
270 _In_ ULONGLONG MatchAllKeyword,
271 _In_opt_ EventFilterDescriptor* FilterData,
272 _Inout_opt_ PVOID CallbackContext);
273
274VOID EventPipeEtwCallbackDotNETRuntimePrivate(
275 _In_ LPCGUID SourceId,
276 _In_ ULONG ControlCode,
277 _In_ UCHAR Level,
278 _In_ ULONGLONG MatchAnyKeyword,
279 _In_ ULONGLONG MatchAllKeyword,
280 _In_opt_ EventFilterDescriptor* FilterData,
281 _Inout_opt_ PVOID CallbackContext);
282
283#ifndef FEATURE_PAL
284// Callback and stack support
285#if !defined(DONOT_DEFINE_ETW_CALLBACK) && !defined(DACCESS_COMPILE)
286extern "C" {
287 /* ETW control callback
288 * Desc: This function handles the ETW control
289 * callback.
290 * Ret: success or failure
291 ***********************************************/
292 VOID EtwCallback(
293 _In_ LPCGUID SourceId,
294 _In_ ULONG ControlCode,
295 _In_ UCHAR Level,
296 _In_ ULONGLONG MatchAnyKeyword,
297 _In_ ULONGLONG MatchAllKeyword,
298 _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
299 _Inout_opt_ PVOID CallbackContext);
300}
301
302//
303// User defined callback
304//
305#define MCGEN_PRIVATE_ENABLE_CALLBACK(RequestCode, Context, InOutBufferSize, Buffer) \
306 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)
307
308//
309// User defined callback2
310//
311#define MCGEN_PRIVATE_ENABLE_CALLBACK_V2(SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeyword, FilterData, CallbackContext) \
312 EtwCallback(SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeyword, FilterData, CallbackContext)
313
314extern "C" {
315 /* ETW callout
316 * Desc: This function handles the ETW callout
317 * Ret: success or failure
318 ***********************************************/
319 VOID EtwCallout(
320 REGHANDLE RegHandle,
321 PCEVENT_DESCRIPTOR Descriptor,
322 ULONG ArgumentCount,
323 PEVENT_DATA_DESCRIPTOR EventData);
324}
325
326//
327// Call user defined callout
328//
329#define MCGEN_CALLOUT(RegHandle, Descriptor, NumberOfArguments, EventData) \
330 EtwCallout(RegHandle, Descriptor, NumberOfArguments, EventData)
331#endif //!DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE
332
333#endif //!FEATURE_PAL
334
335#include "clretwallmain.h"
336
337#endif // FEATURE_EVENT_TRACE
338
339/**************************/
340/* CLR ETW infrastructure */
341/**************************/
342// #CEtwTracer
343// On Windows Vista, ETW has gone through a major upgrade, and one of the most significant changes is the
344// introduction of the unified event provider model and APIs. The older architecture used the classic ETW
345// events. The new ETW architecture uses the manifest based events. To support both types of events at the
346// same time, we use the manpp tool for generating event macros that can be directly used to fire ETW events
347// from various components within the CLR.
348// (http://diagnostics/sites/etw/Lists/Announcements/DispForm.aspx?ID=10&Source=http%3A%2F%2Fdiagnostics%2Fsites%2Fetw%2Fdefault%2Easpx)
349// Every ETW provider has to Register itself to the system, so that when enabled, it is capable of firing
350// ETW events. file:../VM/eventtrace.cpp#Registration is where the actual Provider Registration takes place.
351// At process shutdown, a registered provider need to be unregistered.
352// file:../VM/eventtrace.cpp#Unregistration. Since ETW can also be enabled at any instant after the process
353// has started, one may want to do something useful when that happens (e.g enumerate all the loaded modules
354// in the system). To enable this, we have to implement a callback routine.
355// file:../VM/eventtrace.cpp#EtwCallback is CLR's implementation of the callback.
356//
357
358#include "daccess.h"
359class Module;
360class Assembly;
361class MethodDesc;
362class MethodTable;
363class BaseDomain;
364class AppDomain;
365class SString;
366class CrawlFrame;
367class LoaderAllocator;
368class AssemblyLoaderAllocator;
369struct AllLoggedTypes;
370class CrstBase;
371class BulkTypeEventLogger;
372class TypeHandle;
373class Thread;
374
375
376// All ETW helpers must be a part of this namespace
377// We have auto-generated macros to directly fire the events
378// but in some cases, gathering the event payload information involves some work
379// and it can be done in a relevant helper class like the one's in this namespace
380namespace ETW
381{
382 // Class to wrap the ETW infrastructure logic
383#if !defined(FEATURE_PAL)
384 class CEtwTracer
385 {
386#if defined(FEATURE_EVENT_TRACE)
387 ULONG RegGuids(LPCGUID ProviderId, PENABLECALLBACK EnableCallback, PVOID CallbackContext, PREGHANDLE RegHandle);
388#endif
389
390 public:
391#ifdef FEATURE_EVENT_TRACE
392 // Registers all the Event Tracing providers
393 HRESULT Register();
394
395 // Unregisters all the Event Tracing providers
396 HRESULT UnRegister();
397#else
398 HRESULT Register()
399 {
400 return S_OK;
401 }
402 HRESULT UnRegister()
403 {
404 return S_OK;
405 }
406#endif // FEATURE_EVENT_TRACE
407 };
408#endif // !defined(FEATURE_PAL)
409
410 class LoaderLog;
411 class MethodLog;
412 // Class to wrap all the enumeration logic for ETW
413 class EnumerationLog
414 {
415 friend class ETW::LoaderLog;
416 friend class ETW::MethodLog;
417#ifdef FEATURE_EVENT_TRACE
418 static VOID SendThreadRundownEvent();
419 static VOID IterateDomain(BaseDomain *pDomain, DWORD enumerationOptions);
420 static VOID IterateAppDomain(AppDomain * pAppDomain, DWORD enumerationOptions);
421 static VOID IterateCollectibleLoaderAllocator(AssemblyLoaderAllocator *pLoaderAllocator, DWORD enumerationOptions);
422 static VOID IterateAssembly(Assembly *pAssembly, DWORD enumerationOptions);
423 static VOID IterateModule(Module *pModule, DWORD enumerationOptions);
424 static VOID EnumerationHelper(Module *moduleFilter, BaseDomain *domainFilter, DWORD enumerationOptions);
425 static DWORD GetEnumerationOptionsFromRuntimeKeywords();
426 public:
427 typedef union _EnumerationStructs
428 {
429 typedef enum _EnumerationOptions
430 {
431 None= 0x00000000,
432 DomainAssemblyModuleLoad= 0x00000001,
433 DomainAssemblyModuleUnload= 0x00000002,
434 DomainAssemblyModuleDCStart= 0x00000004,
435 DomainAssemblyModuleDCEnd= 0x00000008,
436 JitMethodLoad= 0x00000010,
437 JitMethodUnload= 0x00000020,
438 JitMethodDCStart= 0x00000040,
439 JitMethodDCEnd= 0x00000080,
440 NgenMethodLoad= 0x00000100,
441 NgenMethodUnload= 0x00000200,
442 NgenMethodDCStart= 0x00000400,
443 NgenMethodDCEnd= 0x00000800,
444 ModuleRangeLoad= 0x00001000,
445 ModuleRangeDCStart= 0x00002000,
446 ModuleRangeDCEnd= 0x00004000,
447 ModuleRangeLoadPrivate= 0x00008000,
448 MethodDCStartILToNativeMap= 0x00010000,
449 MethodDCEndILToNativeMap= 0x00020000,
450 JitMethodILToNativeMap= 0x00040000,
451 TypeUnload= 0x00080000,
452
453 // Helpers
454 ModuleRangeEnabledAny = ModuleRangeLoad | ModuleRangeDCStart | ModuleRangeDCEnd | ModuleRangeLoadPrivate,
455 JitMethodLoadOrDCStartAny = JitMethodLoad | JitMethodDCStart | MethodDCStartILToNativeMap,
456 JitMethodUnloadOrDCEndAny = JitMethodUnload | JitMethodDCEnd | MethodDCEndILToNativeMap,
457 }EnumerationOptions;
458 }EnumerationStructs;
459
460 static VOID ProcessShutdown();
461 static VOID ModuleRangeRundown();
462 static VOID StartRundown();
463 static VOID EndRundown();
464 static VOID EnumerateForCaptureState();
465#else
466 public:
467 static VOID ProcessShutdown() {};
468 static VOID StartRundown() {};
469 static VOID EndRundown() {};
470#endif // FEATURE_EVENT_TRACE
471 };
472
473
474 // Class to wrap all the sampling logic for ETW
475
476 class SamplingLog
477 {
478#if defined(FEATURE_EVENT_TRACE) && !defined(FEATURE_PAL)
479 public:
480 typedef enum _EtwStackWalkStatus
481 {
482 Completed = 0,
483 UnInitialized = 1,
484 InProgress = 2
485 } EtwStackWalkStatus;
486 private:
487 static const UINT8 s_MaxStackSize=100;
488 UINT32 m_FrameCount;
489 SIZE_T m_EBPStack[SamplingLog::s_MaxStackSize];
490 VOID Append(SIZE_T currentFrame);
491 EtwStackWalkStatus SaveCurrentStack(int skipTopNFrames=1);
492 public:
493 static ULONG SendStackTrace(MCGEN_TRACE_CONTEXT TraceContext, PCEVENT_DESCRIPTOR Descriptor, LPCGUID EventGuid);
494 EtwStackWalkStatus GetCurrentThreadsCallStack(UINT32 *frameCount, PVOID **Stack);
495#endif // FEATURE_EVENT_TRACE && !defined(FEATURE_PAL)
496 };
497
498 // Class to wrap all Loader logic for ETW
499 class LoaderLog
500 {
501 friend class ETW::EnumerationLog;
502#if defined(FEATURE_EVENT_TRACE)
503 static VOID SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL bFireDomainModuleEvents=FALSE);
504 static ULONG SendModuleRange(__in Module *pModule, __in DWORD dwEventOptions);
505 static VOID SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions);
506 static VOID SendDomainEvent(BaseDomain *pBaseDomain, DWORD dwEventOptions, LPCWSTR wszFriendlyName=NULL);
507 public:
508 typedef union _LoaderStructs
509 {
510 typedef enum _AppDomainFlags
511 {
512 DefaultDomain=0x1,
513 ExecutableDomain=0x2,
514 SharedDomain=0x4
515 }AppDomainFlags;
516
517 typedef enum _AssemblyFlags
518 {
519 DomainNeutralAssembly=0x1,
520 DynamicAssembly=0x2,
521 NativeAssembly=0x4,
522 CollectibleAssembly=0x8,
523 ReadyToRunAssembly=0x10,
524 }AssemblyFlags;
525
526 typedef enum _ModuleFlags
527 {
528 DomainNeutralModule=0x1,
529 NativeModule=0x2,
530 DynamicModule=0x4,
531 ManifestModule=0x8,
532 IbcOptimized=0x10,
533 ReadyToRunModule=0x20,
534 }ModuleFlags;
535
536 typedef enum _RangeFlags
537 {
538 HotRange=0x0
539 }RangeFlags;
540
541 }LoaderStructs;
542
543 static VOID DomainLoadReal(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName=NULL);
544
545 static VOID DomainLoad(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName = NULL)
546 {
547 if (ETW_PROVIDER_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER))
548 {
549 DomainLoadReal(pDomain, wszFriendlyName);
550 }
551 }
552
553 static VOID DomainUnload(AppDomain *pDomain);
554 static VOID CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator);
555 static VOID ModuleLoad(Module *pModule, LONG liReportedSharedModule);
556#else
557 public:
558 static VOID DomainLoad(BaseDomain *pDomain, __in_opt LPWSTR wszFriendlyName=NULL) {};
559 static VOID DomainUnload(AppDomain *pDomain) {};
560 static VOID CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator) {};
561 static VOID ModuleLoad(Module *pModule, LONG liReportedSharedModule) {};
562#endif // FEATURE_EVENT_TRACE
563 };
564
565 // Class to wrap all Method logic for ETW
566 class MethodLog
567 {
568 friend class ETW::EnumerationLog;
569#ifdef FEATURE_EVENT_TRACE
570 static VOID SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAllocator *pLoaderAllocatorFilter, DWORD dwEventOptions);
571 static VOID SendEventsForJitMethodsHelper(BaseDomain *pDomainFilter,
572 LoaderAllocator *pLoaderAllocatorFilter,
573 DWORD dwEventOptions,
574 BOOL fLoadOrDCStart,
575 BOOL fUnloadOrDCEnd,
576 BOOL fSendMethodEvent,
577 BOOL fSendILToNativeMapEvent,
578 BOOL fGetReJitIDs);
579 static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions);
580 static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
581 static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, SIZE_T pCode, ReJITID rejitID);
582 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, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE);
583 static VOID SendHelperEvent(ULONGLONG ullHelperStartAddress, ULONG ulHelperSize, LPCWSTR pHelperName);
584 public:
585 typedef union _MethodStructs
586 {
587 typedef enum _MethodFlags
588 {
589 DynamicMethod=0x1,
590 GenericMethod=0x2,
591 SharedGenericCode=0x4,
592 JittedMethod=0x8,
593 JitHelperMethod=0x10,
594 ProfilerRejectedPrecompiledCode=0x20,
595 ReadyToRunRejectedPrecompiledCode=0x40,
596 }MethodFlags;
597
598 typedef enum _MethodExtent
599 {
600 HotSection=0x00000000,
601 ColdSection=0x10000000
602 }MethodExtent;
603
604 }MethodStructs;
605
606 static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
607 static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE);
608 static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName);
609 static VOID StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG ulNoOfHelpers);
610 static VOID MethodRestored(MethodDesc * pMethodDesc);
611 static VOID MethodTableRestored(MethodTable * pMethodTable);
612 static VOID DynamicMethodDestroyed(MethodDesc *pMethodDesc);
613#else // FEATURE_EVENT_TRACE
614 public:
615 static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL) {};
616 static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE) {};
617 static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {};
618 static VOID StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG ulNoOfHelpers) {};
619 static VOID MethodRestored(MethodDesc * pMethodDesc) {};
620 static VOID MethodTableRestored(MethodTable * pMethodTable) {};
621 static VOID DynamicMethodDestroyed(MethodDesc *pMethodDesc) {};
622#endif // FEATURE_EVENT_TRACE
623 };
624
625 // Class to wrap all Security logic for ETW
626 class SecurityLog
627 {
628#ifdef FEATURE_EVENT_TRACE
629 public:
630 static VOID StrongNameVerificationStart(DWORD dwInFlags, __in LPWSTR strFullyQualifiedAssemblyName);
631 static VOID StrongNameVerificationStop(DWORD dwInFlags,ULONG result, __in LPWSTR strFullyQualifiedAssemblyName);
632
633 static void FireFieldTransparencyComputationStart(LPCWSTR wszFieldName,
634 LPCWSTR wszModuleName,
635 DWORD dwAppDomain);
636 static void FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
637 LPCWSTR wszModuleName,
638 DWORD dwAppDomain,
639 BOOL fIsCritical,
640 BOOL fIsTreatAsSafe);
641
642 static void FireMethodTransparencyComputationStart(LPCWSTR wszMethodName,
643 LPCWSTR wszModuleName,
644 DWORD dwAppDomain);
645 static void FireMethodTransparencyComputationEnd(LPCWSTR wszMethodName,
646 LPCWSTR wszModuleName,
647 DWORD dwAppDomain,
648 BOOL fIsCritical,
649 BOOL fIsTreatAsSafe);
650
651 static void FireModuleTransparencyComputationStart(LPCWSTR wszModuleName, DWORD dwAppDomain);
652 static void FireModuleTransparencyComputationEnd(LPCWSTR wszModuleName,
653 DWORD dwAppDomain,
654 BOOL fIsAllCritical,
655 BOOL fIsAllTransparent,
656 BOOL fIsTreatAsSafe,
657 BOOL fIsOpportunisticallyCritical,
658 DWORD dwSecurityRuleSet);
659
660 static void FireTokenTransparencyComputationStart(DWORD dwToken,
661 LPCWSTR wszModuleName,
662 DWORD dwAppDomain);
663 static void FireTokenTransparencyComputationEnd(DWORD dwToken,
664 LPCWSTR wszModuleName,
665 DWORD dwAppDomain,
666 BOOL fIsCritical,
667 BOOL fIsTreatAsSafe);
668
669 static void FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
670 LPCWSTR wszModuleName,
671 DWORD dwAppDomain);
672 static void FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
673 LPCWSTR wszModuleName,
674 DWORD dwAppDomain,
675 BOOL fIsAllCritical,
676 BOOL fIsAllTransparent,
677 BOOL fIsCritical,
678 BOOL fIsTreatAsSafe);
679#else
680 public:
681 static VOID StrongNameVerificationStart(DWORD dwInFlags, _In_z_ LPWSTR strFullyQualifiedAssemblyName) {};
682 static VOID StrongNameVerificationStop(DWORD dwInFlags,ULONG result, _In_z_ LPWSTR strFullyQualifiedAssemblyName) {};
683
684 static void FireFieldTransparencyComputationStart(LPCWSTR wszFieldName,
685 LPCWSTR wszModuleName,
686 DWORD dwAppDomain) {};
687 static void FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
688 LPCWSTR wszModuleName,
689 DWORD dwAppDomain,
690 BOOL fIsCritical,
691 BOOL fIsTreatAsSafe) {};
692
693 static void FireMethodTransparencyComputationStart(LPCWSTR wszMethodName,
694 LPCWSTR wszModuleName,
695 DWORD dwAppDomain) {};
696 static void FireMethodTransparencyComputationEnd(LPCWSTR wszMethodName,
697 LPCWSTR wszModuleName,
698 DWORD dwAppDomain,
699 BOOL fIsCritical,
700 BOOL fIsTreatAsSafe) {};
701
702 static void FireModuleTransparencyComputationStart(LPCWSTR wszModuleName, DWORD dwAppDomain) {};
703 static void FireModuleTransparencyComputationEnd(LPCWSTR wszModuleName,
704 DWORD dwAppDomain,
705 BOOL fIsAllCritical,
706 BOOL fIsAllTransparent,
707 BOOL fIsTreatAsSafe,
708 BOOL fIsOpportunisticallyCritical,
709 DWORD dwSecurityRuleSet) {};
710
711 static void FireTokenTransparencyComputationStart(DWORD dwToken,
712 LPCWSTR wszModuleName,
713 DWORD dwAppDomain) {};
714 static void FireTokenTransparencyComputationEnd(DWORD dwToken,
715 LPCWSTR wszModuleName,
716 DWORD dwAppDomain,
717 BOOL fIsCritical,
718 BOOL fIsTreatAsSafe) {};
719
720 static void FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
721 LPCWSTR wszModuleName,
722 DWORD dwAppDomain) {};
723 static void FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
724 LPCWSTR wszModuleName,
725 DWORD dwAppDomain,
726 BOOL fIsAllCritical,
727 BOOL fIsAllTransparent,
728 BOOL fIsCritical,
729 BOOL fIsTreatAsSafe) {};
730#endif // FEATURE_EVENT_TRACE
731 };
732
733 // Class to wrap all Binder logic for ETW
734 class BinderLog
735 {
736 public:
737 typedef union _BinderStructs {
738 typedef enum _NGENBINDREJECT_REASON {
739 NGEN_BIND_START_BIND = 0,
740 NGEN_BIND_NO_INDEX = 1,
741 NGEN_BIND_SYSTEM_ASSEMBLY_NOT_AVAILABLE = 2,
742 NGEN_BIND_NO_NATIVE_IMAGE = 3,
743 NGEN_BIND_REJECT_CONFIG_MASK = 4,
744 NGEN_BIND_FAIL = 5,
745 NGEN_BIND_INDEX_CORRUPTION = 6,
746 NGEN_BIND_REJECT_TIMESTAMP = 7,
747 NGEN_BIND_REJECT_NATIVEIMAGE_NOT_FOUND = 8,
748 NGEN_BIND_REJECT_IL_SIG = 9,
749 NGEN_BIND_REJECT_LOADER_EVAL_FAIL = 10,
750 NGEN_BIND_MISSING_FOUND = 11,
751 NGEN_BIND_REJECT_HOSTASM = 12,
752 NGEN_BIND_REJECT_IL_NOT_FOUND = 13,
753 NGEN_BIND_REJECT_APPBASE_NOT_FILE = 14,
754 NGEN_BIND_BIND_DEPEND_REJECT_REF_DEF_MISMATCH = 15,
755 NGEN_BIND_BIND_DEPEND_REJECT_NGEN_SIG = 16,
756 NGEN_BIND_APPLY_EXTERNAL_RELOCS_FAILED = 17,
757 NGEN_BIND_SYSTEM_ASSEMBLY_NATIVEIMAGE_NOT_AVAILABLE = 18,
758 NGEN_BIND_ASSEMBLY_HAS_DIFFERENT_GRANT = 19,
759 NGEN_BIND_ASSEMBLY_NOT_DOMAIN_NEUTRAL = 20,
760 NGEN_BIND_NATIVEIMAGE_VERSION_MISMATCH = 21,
761 NGEN_BIND_LOADFROM_NOT_ALLOWED = 22,
762 NGEN_BIND_DEPENDENCY_HAS_DIFFERENT_IDENTITY = 23
763 } NGENBINDREJECT_REASON;
764 } BinderStructs;
765 };
766
767 // Class to wrap all Exception logic for ETW
768 class ExceptionLog
769 {
770 public:
771#ifdef FEATURE_EVENT_TRACE
772 static VOID ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownException, BOOL bIsNewException);
773 static VOID ExceptionThrownEnd();
774 static VOID ExceptionCatchBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP);
775 static VOID ExceptionCatchEnd();
776 static VOID ExceptionFinallyBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP);
777 static VOID ExceptionFinallyEnd();
778 static VOID ExceptionFilterBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP);
779 static VOID ExceptionFilterEnd();
780
781#else
782 static VOID ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownException, BOOL bIsNewException) {};
783 static VOID ExceptionThrownEnd() {};
784 static VOID ExceptionCatchBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {};
785 static VOID ExceptionCatchEnd() {};
786 static VOID ExceptionFinallyBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {};
787 static VOID ExceptionFinallyEnd() {};
788 static VOID ExceptionFilterBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {};
789 static VOID ExceptionFilterEnd() {};
790#endif // FEATURE_EVENT_TRACE
791 typedef union _ExceptionStructs
792 {
793 typedef enum _ExceptionThrownFlags
794 {
795 HasInnerException=0x1,
796 IsNestedException=0x2,
797 IsReThrownException=0x4,
798 IsCSE=0x8,
799 IsCLSCompliant=0x10
800 }ExceptionThrownFlags;
801 }ExceptionStructs;
802 };
803 // Class to wrap all Contention logic for ETW
804 class ContentionLog
805 {
806 public:
807 typedef union _ContentionStructs
808 {
809 typedef enum _ContentionFlags {
810 ManagedContention=0,
811 NativeContention=1
812 } ContentionFlags;
813 } ContentionStructs;
814 };
815 // Class to wrap all Interop logic for ETW
816 class InteropLog
817 {
818 public:
819 };
820
821 // Class to wrap all Information logic for ETW
822 class InfoLog
823 {
824 public:
825 typedef union _InfoStructs
826 {
827 typedef enum _StartupMode
828 {
829 ManagedExe=0x1,
830 HostedCLR=0x2,
831 IJW=0x4,
832 COMActivated=0x8,
833 Other=0x10
834 }StartupMode;
835
836 typedef enum _Sku
837 {
838 DesktopCLR=0x1,
839 CoreCLR=0x2
840 }Sku;
841
842 typedef enum _EtwMode
843 {
844 Normal=0x0,
845 Callback=0x1
846 }EtwMode;
847 }InfoStructs;
848
849#ifdef FEATURE_EVENT_TRACE
850 static VOID RuntimeInformation(INT32 type);
851#else
852 static VOID RuntimeInformation(INT32 type) {};
853#endif // FEATURE_EVENT_TRACE
854 };
855
856 class CodeSymbolLog
857 {
858 public:
859#ifdef FEATURE_EVENT_TRACE
860 static VOID EmitCodeSymbols(Module* pModule);
861 static HRESULT GetInMemorySymbolsLength(Module* pModule, DWORD* pCountSymbolBytes);
862 static HRESULT ReadInMemorySymbols(Module* pmodule, DWORD symbolsReadOffset, BYTE* pSymbolBytes,
863 DWORD countSymbolBytes, DWORD* pCountSymbolBytesRead);
864#else
865 static VOID EmitCodeSymbols(Module* pModule) {}
866 static HRESULT GetInMemorySymbolsLength(Module* pModule, DWORD* pCountSymbolBytes) { return S_OK; }
867 static HRESULT ReadInMemorySymbols(Module* pmodule, DWORD symbolsReadOffset, BYTE* pSymbolBytes,
868 DWORD countSymbolBytes, DWORD* pCountSymbolBytesRead) { return S_OK; }
869#endif // FEATURE_EVENT_TRACE
870 };
871};
872
873
874#define ETW_IS_TRACE_ON(level) ( FALSE ) // for fusion which is eventually going to get removed
875#define ETW_IS_FLAG_ON(flag) ( FALSE ) // for fusion which is eventually going to get removed
876
877// Commonly used constats for ETW Assembly Loader and Assembly Binder events.
878#define ETWLoadContextNotAvailable (LOADCTX_TYPE_HOSTED + 1)
879#define ETWAppDomainIdNotAvailable 0 // Valid AppDomain IDs start from 1
880
881#define ETWFieldUnused 0 // Indicates that a particular field in the ETW event payload template is currently unused.
882
883#define ETWLoaderLoadTypeNotAvailable 0 // Static or Dynamic Load is only valid at LoaderPhaseStart and LoaderPhaseEnd events - for other events, 0 indicates "not available"
884#define ETWLoaderStaticLoad 0 // Static reference load
885#define ETWLoaderDynamicLoad 1 // Dynamic assembly load
886
887#if defined(FEATURE_EVENT_TRACE) && !defined(FEATURE_PAL)
888//
889// The ONE and only ONE global instantiation of this class
890//
891extern ETW::CEtwTracer * g_pEtwTracer;
892
893//
894// Special Handling of Startup events
895//
896
897// "mc.exe -MOF" already generates this block for XP-suported builds inside ClrEtwAll.h;
898// on Vista+ builds, mc is run without -MOF, and we still have code that depends on it, so
899// we manually place it here.
900ETW_INLINE
901ULONG
902CoMofTemplate_h(
903 __in REGHANDLE RegHandle,
904 __in PCEVENT_DESCRIPTOR Descriptor,
905 __in_opt LPCGUID EventGuid,
906 __in const unsigned short ClrInstanceID
907 )
908{
909#define ARGUMENT_COUNT_h 1
910 ULONG Error = ERROR_SUCCESS;
911typedef struct _MCGEN_TRACE_BUFFER {
912 EVENT_TRACE_HEADER Header;
913 EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_h];
914} MCGEN_TRACE_BUFFER;
915
916 MCGEN_TRACE_BUFFER TraceBuf;
917 PEVENT_DATA_DESCRIPTOR EventData = TraceBuf.EventData;
918
919 EventDataDescCreate(&EventData[0], &ClrInstanceID, sizeof(const unsigned short) );
920
921
922 {
923 Error = EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_h, EventData);
924
925 }
926
927#ifdef MCGEN_CALLOUT
928MCGEN_CALLOUT(RegHandle,
929 Descriptor,
930 ARGUMENT_COUNT_h,
931 EventData);
932#endif
933
934 return Error;
935}
936
937class ETWTraceStartup {
938 REGHANDLE TraceHandle;
939 PCEVENT_DESCRIPTOR EventStartDescriptor;
940 LPCGUID EventStartGuid;
941 PCEVENT_DESCRIPTOR EventEndDescriptor;
942 LPCGUID EventEndGuid;
943public:
944 ETWTraceStartup(REGHANDLE _TraceHandle, PCEVENT_DESCRIPTOR _EventStartDescriptor, LPCGUID _EventStartGuid, PCEVENT_DESCRIPTOR _EventEndDescriptor, LPCGUID _EventEndGuid) {
945 TraceHandle = _TraceHandle;
946 EventStartDescriptor = _EventStartDescriptor;
947 EventEndDescriptor = _EventEndDescriptor;
948 EventStartGuid = _EventStartGuid;
949 EventEndGuid = _EventEndGuid;
950 StartupTraceEvent(TraceHandle, EventStartDescriptor, EventStartGuid);
951 }
952 ~ETWTraceStartup() {
953 StartupTraceEvent(TraceHandle, EventEndDescriptor, EventEndGuid);
954 }
955 static void StartupTraceEvent(REGHANDLE _TraceHandle, PCEVENT_DESCRIPTOR _EventDescriptor, LPCGUID _EventGuid) {
956 EVENT_DESCRIPTOR desc = *_EventDescriptor;
957 if(ETW_TRACING_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, desc))
958 {
959 CoMofTemplate_h(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context.RegistrationHandle, _EventDescriptor, _EventGuid, GetClrInstanceId());
960 }
961 }
962};
963// "mc.exe -MOF" already generates this block for XP-suported builds inside ClrEtwAll.h;
964// on Vista+ builds, mc is run without -MOF, and we still have code that depends on it, so
965// we manually place it here.
966FORCEINLINE
967BOOLEAN __stdcall
968McGenEventTracingEnabled(
969 __in PMCGEN_TRACE_CONTEXT EnableInfo,
970 __in PCEVENT_DESCRIPTOR EventDescriptor
971 )
972{
973
974 if(!EnableInfo){
975 return FALSE;
976 }
977
978
979 //
980 // Check if the event Level is lower than the level at which
981 // the channel is enabled.
982 // If the event Level is 0 or the channel is enabled at level 0,
983 // all levels are enabled.
984 //
985
986 if ((EventDescriptor->Level <= EnableInfo->Level) || // This also covers the case of Level == 0.
987 (EnableInfo->Level == 0)) {
988
989 //
990 // Check if Keyword is enabled
991 //
992
993 if ((EventDescriptor->Keyword == (ULONGLONG)0) ||
994 ((EventDescriptor->Keyword & EnableInfo->MatchAnyKeyword) &&
995 ((EventDescriptor->Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) {
996 return TRUE;
997 }
998 }
999
1000 return FALSE;
1001}
1002
1003
1004ETW_INLINE
1005ULONG
1006ETW::SamplingLog::SendStackTrace(
1007 MCGEN_TRACE_CONTEXT TraceContext,
1008 PCEVENT_DESCRIPTOR Descriptor,
1009 LPCGUID EventGuid)
1010{
1011#define ARGUMENT_COUNT_CLRStackWalk 5
1012 ULONG Result = ERROR_SUCCESS;
1013typedef struct _MCGEN_TRACE_BUFFER {
1014 EVENT_TRACE_HEADER Header;
1015 EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_CLRStackWalk];
1016} MCGEN_TRACE_BUFFER;
1017
1018 REGHANDLE RegHandle = TraceContext.RegistrationHandle;
1019 if(!TraceContext.IsEnabled || !McGenEventTracingEnabled(&TraceContext, Descriptor))
1020 {
1021 return Result;
1022 }
1023
1024 PVOID *Stack = NULL;
1025 UINT32 FrameCount = 0;
1026 ETW::SamplingLog stackObj;
1027 if(stackObj.GetCurrentThreadsCallStack(&FrameCount, &Stack) == ETW::SamplingLog::Completed)
1028 {
1029 UCHAR Reserved1=0, Reserved2=0;
1030 UINT16 ClrInstanceId = GetClrInstanceId();
1031 MCGEN_TRACE_BUFFER TraceBuf;
1032 PEVENT_DATA_DESCRIPTOR EventData = TraceBuf.EventData;
1033
1034 EventDataDescCreate(&EventData[0], &ClrInstanceId, sizeof(const UINT16) );
1035
1036 EventDataDescCreate(&EventData[1], &Reserved1, sizeof(const UCHAR) );
1037
1038 EventDataDescCreate(&EventData[2], &Reserved2, sizeof(const UCHAR) );
1039
1040 EventDataDescCreate(&EventData[3], &FrameCount, sizeof(const unsigned int) );
1041
1042 EventDataDescCreate(&EventData[4], Stack, sizeof(PVOID) * FrameCount );
1043
1044 return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_CLRStackWalk, EventData);
1045 }
1046 return Result;
1047};
1048
1049#endif // FEATURE_EVENT_TRACE && !defined(FEATURE_PAL)
1050#ifdef FEATURE_EVENT_TRACE
1051#ifdef _TARGET_X86_
1052struct CallStackFrame
1053{
1054 struct CallStackFrame* m_Next;
1055 SIZE_T m_ReturnAddress;
1056};
1057#endif // _TARGET_X86_
1058#endif // FEATURE_EVENT_TRACE
1059
1060#if defined(FEATURE_EVENT_TRACE) && !defined(FEATURE_PAL)
1061FORCEINLINE
1062BOOLEAN __stdcall
1063McGenEventProviderEnabled(
1064 __in PMCGEN_TRACE_CONTEXT Context,
1065 __in UCHAR Level,
1066 __in ULONGLONG Keyword
1067 )
1068{
1069 if(!Context) {
1070 return FALSE;
1071 }
1072
1073 //
1074 // Check if the event Level is lower than the level at which
1075 // the channel is enabled.
1076 // If the event Level is 0 or the channel is enabled at level 0,
1077 // all levels are enabled.
1078 //
1079
1080 if ((Level <= Context->Level) || // This also covers the case of Level == 0.
1081 (Context->Level == 0)) {
1082
1083 //
1084 // Check if Keyword is enabled
1085 //
1086
1087 if ((Keyword == (ULONGLONG)0) ||
1088 ((Keyword & Context->MatchAnyKeyword) &&
1089 ((Keyword & Context->MatchAllKeyword) == Context->MatchAllKeyword))) {
1090 return TRUE;
1091 }
1092 }
1093 return FALSE;
1094}
1095#endif // FEATURE_EVENT_TRACE && !defined(FEATURE_PAL)
1096
1097
1098#endif // !FEATURE_REDHAWK
1099
1100// These parts of the ETW namespace are common for both FEATURE_REDHAWK and
1101// !FEATURE_REDHAWK builds.
1102
1103
1104struct ProfilingScanContext;
1105class Object;
1106
1107namespace ETW
1108{
1109 // Class to wrap the logging of threads (runtime and rundown providers)
1110 class ThreadLog
1111 {
1112 private:
1113 static DWORD GetEtwThreadFlags(Thread * pThread);
1114
1115 public:
1116 static VOID FireThreadCreated(Thread * pThread);
1117 static VOID FireThreadDC(Thread * pThread);
1118 };
1119};
1120
1121
1122#endif //_ETWTRACER_HXX_
1123