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.
5 /**************************************************************************************
7 ** Corprof.idl - CLR Profiling interfaces. **
9 **************************************************************************************/
11 /* -------------------------------------------------------------------------- *
13 * -------------------------------------------------------------------------- */
15 #if !DEFINITIONS_FROM_NON_IMPORTABLE_PLACES
17 cpp_quote("#define CorDB_CONTROL_Profiling \"Cor_Enable_Profiling\"")
18 cpp_quote("#define CorDB_CONTROL_ProfilingL L\"Cor_Enable_Profiling\"")
25 typedef LONG32 mdToken;
26 typedef mdToken mdModule;
27 typedef mdToken mdTypeDef;
28 typedef mdToken mdMethodDef;
29 typedef mdToken mdFieldDef;
30 typedef ULONG CorElementType;
32 // Forward declaration of enum in CorHdr.h
35 // Forward declaration of structs in Cor.h
39 DWORD dwOSPlatformId; // Operating system platform.
40 DWORD dwOSMajorVersion; // OS Major version.
41 DWORD dwOSMinorVersion; // OS Minor version.
46 USHORT usMajorVersion; // Major Version.
47 USHORT usMinorVersion; // Minor Version.
48 USHORT usBuildNumber; // Build Number.
49 USHORT usRevisionNumber; // Revision Number.
50 LPWSTR szLocale; // Locale.
51 ULONG cbLocale; // [IN/OUT] Size of the buffer in wide chars/Actual size.
52 DWORD *rProcessor; // Processor ID array.
53 ULONG ulProcessor; // [IN/OUT] Size of the Processor ID array/Actual # of entries filled in.
54 OSINFO *rOS; // OSINFO array.
55 ULONG ulOS; // [IN/OUT]Size of the OSINFO array/Actual # of entries filled in.
60 typedef const BYTE *LPCBYTE;
63 typedef BYTE COR_SIGNATURE;
64 typedef COR_SIGNATURE* PCOR_SIGNATURE;
65 typedef const COR_SIGNATURE* PCCOR_SIGNATURE;
70 cpp_quote("#ifndef _COR_IL_MAP")
71 cpp_quote("#define _COR_IL_MAP")
74 // Note that this structure is also defined in CorDebug.idl - PROPAGATE CHANGES
75 // BOTH WAYS, or this'll become a really insidious bug some day.
77 typedef struct _COR_IL_MAP
79 ULONG32 oldOffset; // Old IL offset relative to beginning of function
80 ULONG32 newOffset; // New IL offset relative to beginning of function
81 BOOL fAccurate; //put here for compatibility with the Debugger structure.
84 cpp_quote("#endif //_COR_IL_MAP")
86 cpp_quote("#ifndef _COR_DEBUG_IL_TO_NATIVE_MAP_")
87 cpp_quote("#define _COR_DEBUG_IL_TO_NATIVE_MAP_")
89 /* ICorProfilerInfo:: GetILToNativeMapping returns an array of
90 * COR_DEBUG_IL_TO_NATIVE_MAP structures. In order to convey that certain
91 * ranges of native instructions correspond to special regions of code (for
92 * example, the prolog), an entry in the array may have it's ilOffset field set
93 * to one of these values.
95 typedef enum CorDebugIlToNativeMappingTypes
100 } CorDebugIlToNativeMappingTypes;
102 typedef struct COR_DEBUG_IL_TO_NATIVE_MAP
105 ULONG32 nativeStartOffset;
106 ULONG32 nativeEndOffset;
107 } COR_DEBUG_IL_TO_NATIVE_MAP;
109 cpp_quote("#endif // _COR_DEBUG_IL_TO_NATIVE_MAP_")
111 cpp_quote("#ifndef _COR_FIELD_OFFSET_")
112 cpp_quote("#define _COR_FIELD_OFFSET_")
114 typedef struct _COR_FIELD_OFFSET
116 mdFieldDef ridOfField; // fieldDef token of the field
117 ULONG ulOffset; // offset (from the ObjectID pointer) of the field
120 cpp_quote("#endif // _COR_FIELD_OFFSET_")
123 #ifndef DO_NO_IMPORTS
128 typedef UINT_PTR ProcessID;
129 typedef UINT_PTR AssemblyID;
130 typedef UINT_PTR AppDomainID;
131 typedef UINT_PTR ModuleID;
132 typedef UINT_PTR ClassID;
133 typedef UINT_PTR ThreadID;
134 typedef UINT_PTR ContextID;
135 typedef UINT_PTR FunctionID;
136 typedef UINT_PTR ObjectID;
137 typedef UINT_PTR GCHandleID;
138 typedef UINT_PTR COR_PRF_ELT_INFO;
139 typedef UINT_PTR ReJITID;
141 typedef union {FunctionID functionID; UINT_PTR clientID;} FunctionIDOrClientID;
144 * The FunctionIDMapper type definition is used by the
145 * ICorProfilerInfo::SetFunctionIDMapper method to specify
146 * a function that will be called to map FunctionIDs to alternative
147 * values that will be passed to the function entry and function exit
148 * callbacks supplied to the ICorProfilerInfo::SetEnterLeaveFunctionHooks
149 * method. The mapper can be set only once and it is recommended to do so
150 * in the Initialize callback.
152 * NOTE: There is a known bug in this API that must be worked around.
153 * The return value of FunctionIDMapper cannot be NULL (unless the boolean
154 * value in pbHookTheFunction is FALSE). All other values are treated as
155 * opaque data to be passed to the entry/exit callback functions. The use
156 * of a NULL return value will produce unpredictable results, including
157 * possibly halting the process.
159 * NOTE: Profilers should be tolerant of cases where multiple threads of
160 * a profiled app are calling the same method simultaneously. In such
161 * cases, the profiler may receive multiple FunctionIDMapper callbacks
162 * for the same functionId. The profiler should be certain to return
163 * the same values from this callback when it is called multiple times
164 * with the same functionId.
167 typedef UINT_PTR __stdcall FunctionIDMapper(
169 BOOL *pbHookFunction);
171 typedef UINT_PTR __stdcall FunctionIDMapper2(
174 BOOL *pbHookFunction);
177 * Enum for specifying how much data to pass back with a stack snapshot
179 typedef enum _COR_PRF_SNAPSHOT_INFO
181 COR_PRF_SNAPSHOT_DEFAULT = 0x0,
183 // Return a register context for each frame
184 COR_PRF_SNAPSHOT_REGISTER_CONTEXT = 0x1,
186 // Use a quicker stack walk algorithm based on the EBP frame chain. This is available
188 COR_PRF_SNAPSHOT_X86_OPTIMIZED = 0x2,
189 } COR_PRF_SNAPSHOT_INFO;
192 * Opaque handle that represents information about a given stack frame. It is only
193 * valid during the callback to which it is passed.
195 typedef UINT_PTR COR_PRF_FRAME_INFO;
198 * Describes a range of function arguments stored contiguously in left-to-right
201 typedef struct _COR_PRF_FUNCTION_ARGUMENT_RANGE
203 UINT_PTR startAddress; // start address of the range
204 ULONG length; // contiguous length of the range
205 } COR_PRF_FUNCTION_ARGUMENT_RANGE;
208 * Describes the locations in memory of a function's arguments, in
209 * left-to-right order. Note that arguments stored in registers are
210 * spilled to memory to build these structures.
212 typedef struct _COR_PRF_FUNCTION_ARGUMENT_INFO
214 ULONG numRanges; // number of chunks of arguments
215 ULONG totalArgumentSize; // total size of arguments
216 COR_PRF_FUNCTION_ARGUMENT_RANGE ranges[1]; // chunks
217 } COR_PRF_FUNCTION_ARGUMENT_INFO;
220 * Represents one contiguous chunk of native code
222 typedef struct _COR_PRF_CODE_INFO
224 UINT_PTR startAddress;
229 * Enum for describing the type of static a field is. These may be bit-wise
230 * or'ed with each other if the field is multiple types.
234 COR_PRF_FIELD_NOT_A_STATIC = 0x0,
235 COR_PRF_FIELD_APP_DOMAIN_STATIC = 0x1,
236 COR_PRF_FIELD_THREAD_STATIC = 0x2,
237 COR_PRF_FIELD_CONTEXT_STATIC = 0x4,
238 COR_PRF_FIELD_RVA_STATIC = 0x8
239 } COR_PRF_STATIC_TYPE;
242 * Represents a function uniquely by combining the FunctionID
245 typedef struct _COR_PRF_FUNCTION
247 FunctionID functionId;
253 * Structure populated by profiler when declaring additional assembly references
254 * that the CLR should consider when performing an assembly reference closure
255 * walk. See ICorProfilerCallback6::GetAssemblyReferences and
256 * ICorProfilerAssemblyReferenceProvider::AddAssemblyReference
258 typedef struct _COR_PRF_ASSEMBLY_REFERENCE_INFO
260 void *pbPublicKeyOrToken; // Public key or token of the assembly.
261 ULONG cbPublicKeyOrToken; // Count of bytes in the public key or token.
262 LPCWSTR szName; // Name of the assembly being referenced.
263 ASSEMBLYMETADATA * pMetaData; // Assembly MetaData, as defined in cor.h
264 void *pbHashValue; // Hash Blob.
265 ULONG cbHashValue; // Count of bytes in the Hash Blob.
266 DWORD dwAssemblyRefFlags; // Flags.
267 } COR_PRF_ASSEMBLY_REFERENCE_INFO;
271 * Represents a IL methods uniquely by combining the module ID and method token.
273 typedef struct _COR_PRF_METHOD
276 mdMethodDef methodId;
282 * The following applies to ALL FunctionEnter[2,3], FunctionLeave[2,3],
283 * FunctionTailcall[2,3] hooks below:
285 * It is VERY IMPORTANT to note that these function implementations must be
286 * __declspec(naked), since the EE is not saving any registers before calling
287 * any of them. YOU MUST SAVE ALL REGISTERS YOU USE, INCLUDING FPU REGISTERS
288 * IF THE FPU STACK IS NOT EMPTY AND YOU INTEND TO USE IT.
290 * NOTE: The profiler should not block here, since the stack may not be in a
291 * GC-friendly state and so preemptive GC cannot be enabled. If the
292 * profiler blocks here and a GC is attempted, the runtime will block
293 * until this callback returns. Also, the profiler may NOT call into
294 * managed code or in any way cause a managed memory allocation.
298 * NOTE: DEPRECATED IN V2
300 * These functions are considered deprecated in V2 and higher. They will
301 * continue to work, but incur a performance penalty for usage. For equivalent
302 * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks with
303 * bits cleared for COR_PRF_ENABLE_FRAME_INFO, COR_PRF_ENABLE_FUNCTION_RETVAL
304 * and COR_PRF_ENABLE_FUNCTION_ARGS.
306 typedef void __stdcall FunctionEnter(
309 typedef void __stdcall FunctionLeave(
312 typedef void __stdcall FunctionTailcall(
316 * NOTE: DEPRECATED IN V4
318 * These functions are considered deprecated in V4 and higher. They will
319 * continue to work, but incur a performance penalty for usage. For equivalent
320 * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks.
323 typedef void __stdcall FunctionEnter2(
326 COR_PRF_FRAME_INFO func,
327 COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo);
329 typedef void __stdcall FunctionLeave2(
332 COR_PRF_FRAME_INFO func,
333 COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange);
335 typedef void __stdcall FunctionTailcall2(
338 COR_PRF_FRAME_INFO func);
341 * When you are not interested in inspecting arguments or return values, then
342 * use these to be notified as functions are called and return. Use
343 * SetEnterLeaveFunctionHooks3 to register your implementations of these
346 * functionIDOrClientID: if the profiler returned a remapped value from
347 * FunctionIDMapper[2], then this is that remapped value; else it is the
348 * true FunctionID of the function.
351 typedef void __stdcall FunctionEnter3(
352 FunctionIDOrClientID functionIDOrClientID);
354 typedef void __stdcall FunctionLeave3(
355 FunctionIDOrClientID functionIDOrClientID);
357 typedef void __stdcall FunctionTailcall3(
358 FunctionIDOrClientID functionIDOrClientID);
361 * When you are interested in inspecting arguments and return values, then
362 * use these to be notified as functions are called and return. Use
363 * SetEnterLeaveFunctionHooks3WithInfo to register your implementations of these
366 * functionIDOrClientID: if the profiler returned a remapped value from
367 * FunctionIDMapper[2], then this is that remapped value; else it is the
368 * true FunctionID of the function.
370 * eltInfo is an opaque handle that represents information about a given stack frame.
371 * It is only valid during the callback to which it is passed.
374 typedef void __stdcall FunctionEnter3WithInfo(
375 FunctionIDOrClientID functionIDOrClientID,
376 COR_PRF_ELT_INFO eltInfo);
378 typedef void __stdcall FunctionLeave3WithInfo(
379 FunctionIDOrClientID functionIDOrClientID,
380 COR_PRF_ELT_INFO eltInfo);
382 typedef void __stdcall FunctionTailcall3WithInfo(
383 FunctionIDOrClientID functionIDOrClientID,
384 COR_PRF_ELT_INFO eltInfo);
387 * Stack snapshot callback definition.
389 * This callback is called once per managed frame or run of unmanaged frames.
391 * funcID is the FunctionID of the managed function. If funcID == 0, the callback is
392 * for a run of unmanaged frames. The profiler may either ignore the frame, or use
393 * the register context to perform its own unmanaged stackwalk.
395 * ip is the native IP in the frame
397 * frameInfo is the COR_PRF_FRAME_INFO for this frame. It is only valid for
398 * use during this callback.
400 * context is a Win32 CONTEXT struct for the current platform (size given in
401 * contextSize). It will only be valid if the COR_PRF_SNAPSHOT_CONTEXT flag
402 * was passed to DoStackSnapshot.
404 * clientData is a void* passed straight through from DoStackSnapshot
406 * NOTE: One must limit the complexity of work done in StackSnapshotCallback.
407 * For example, particularly when using DoStackSnapshot in an asynchronous manner,
408 * the target thread may be holding locks. Executing code within StackSnapshotCallback
409 * that requires the same locks could lead to deadlock.
411 typedef HRESULT __stdcall StackSnapshotCallback(
414 COR_PRF_FRAME_INFO frameInfo,
421 // These flags represent classes of callback events
422 COR_PRF_MONITOR_NONE = 0x00000000,
424 // MONITOR_FUNCTION_UNLOADS controls the
425 // FunctionUnloadStarted callback.
426 COR_PRF_MONITOR_FUNCTION_UNLOADS = 0x00000001,
428 // MONITOR_CLASS_LOADS controls the ClassLoad*
429 // and ClassUnload* callbacks.
430 // See the comments on those callbacks for important
431 // behavior changes in V2.
432 COR_PRF_MONITOR_CLASS_LOADS = 0x00000002,
434 // MONITOR_MODULE_LOADS controls the
435 // ModuleLoad*, ModuleUnload*, and ModuleAttachedToAssembly
437 COR_PRF_MONITOR_MODULE_LOADS = 0x00000004,
439 // MONITOR_ASSEMBLY_LOADS controls the
440 // AssemblyLoad* and AssemblyUnload* callbacks
441 COR_PRF_MONITOR_ASSEMBLY_LOADS = 0x00000008,
443 // MONITOR_APPDOMAIN_LOADS controls the
444 // AppDomainCreation* and AppDomainShutdown* callbacks
445 COR_PRF_MONITOR_APPDOMAIN_LOADS = 0x00000010,
447 // MONITOR_JIT_COMPILATION controls the
448 // JITCompilation*, JITFunctionPitched, and JITInlining
450 COR_PRF_MONITOR_JIT_COMPILATION = 0x00000020,
453 // MONITOR_EXCEPTIONS controls the ExceptionThrown,
454 // ExceptionSearch*, ExceptionOSHandler*, ExceptionUnwind*,
455 // and ExceptionCatcher* callbacks.
456 COR_PRF_MONITOR_EXCEPTIONS = 0x00000040,
458 // MONITOR_GC controls the GarbageCollectionStarted/Finished,
459 // MovedReferences, SurvivingReferences,
460 // ObjectReferences, ObjectsAllocatedByClass,
461 // RootReferences*, HandleCreated/Destroyed, and FinalizeableObjectQueued
463 COR_PRF_MONITOR_GC = 0x00000080,
465 // MONITOR_OBJECT_ALLOCATED controls the
466 // ObjectAllocated callback.
467 COR_PRF_MONITOR_OBJECT_ALLOCATED = 0x00000100,
469 // MONITOR_THREADS controls the ThreadCreated,
470 // ThreadDestroyed, ThreadAssignedToOSThread,
471 // and ThreadNameChanged callbacks.
472 COR_PRF_MONITOR_THREADS = 0x00000200,
474 // MONITOR_REMOTING controls the Remoting*
476 COR_PRF_MONITOR_REMOTING = 0x00000400,
478 // MONITOR_CODE_TRANSITIONS controls the
479 // UnmanagedToManagedTransition and
480 // ManagedToUnmanagedTransition callbacks.
481 COR_PRF_MONITOR_CODE_TRANSITIONS = 0x00000800,
483 // MONITOR_ENTERLEAVE controls the
484 // FunctionEnter*/Leave*/Tailcall* callbacks
485 COR_PRF_MONITOR_ENTERLEAVE = 0x00001000,
487 // MONITOR_CCW controls the COMClassicVTable*
489 COR_PRF_MONITOR_CCW = 0x00002000,
491 // MONITOR_REMOTING_COOKIE controls whether
492 // a cookie will be passed to the Remoting* callbacks
493 COR_PRF_MONITOR_REMOTING_COOKIE = 0x00004000 | COR_PRF_MONITOR_REMOTING,
495 // MONITOR_REMOTING_ASYNC controls whether
496 // the Remoting* callbacks will monitor async events
497 COR_PRF_MONITOR_REMOTING_ASYNC = 0x00008000 | COR_PRF_MONITOR_REMOTING,
499 // MONITOR_SUSPENDS controls the RuntimeSuspend*,
500 // RuntimeResume*, RuntimeThreadSuspended, and
501 // RuntimeThreadResumed callbacks.
502 COR_PRF_MONITOR_SUSPENDS = 0x00010000,
504 // MONITOR_CACHE_SEARCHES controls the
505 // JITCachedFunctionSearch* callbacks.
506 // See the comments on those callbacks for important
507 // behavior changes in V2.
508 COR_PRF_MONITOR_CACHE_SEARCHES = 0x00020000,
510 // NOTE: ReJIT is now supported again. The profiler must set this flag on
511 // startup in order to use RequestReJIT or RequestRevert. If the profiler specifies
512 // this flag, then the profiler must also specify COR_PRF_DISABLE_ALL_NGEN_IMAGES
513 COR_PRF_ENABLE_REJIT = 0x00040000,
515 // V2 MIGRATION WARNING: DEPRECATED
516 // Inproc debugging is no longer supported. ENABLE_INPROC_DEBUGGING
518 COR_PRF_ENABLE_INPROC_DEBUGGING = 0x00080000,
520 // V2 MIGRATION NOTE: DEPRECATED
521 // The runtime now always tracks IL-native maps; this flag is thus always
522 // considered to be set.
523 COR_PRF_ENABLE_JIT_MAPS = 0x00100000,
525 // DISABLE_INLINING tells the runtime to disable all inlining
526 COR_PRF_DISABLE_INLINING = 0x00200000,
528 // DISABLE_OPTIMIZATIONS tells the runtime to disable all code optimizations
529 COR_PRF_DISABLE_OPTIMIZATIONS = 0x00400000,
531 // ENABLE_OBJECT_ALLOCATED tells the runtime that the profiler may want
532 // object allocation notifications. This must be set during initialization if the profiler
533 // ever wants object notifications (using COR_PRF_MONITOR_OBJECT_ALLOCATED)
534 COR_PRF_ENABLE_OBJECT_ALLOCATED = 0x00800000,
536 // MONITOR_CLR_EXCEPTIONS controls the ExceptionCLRCatcher*
538 COR_PRF_MONITOR_CLR_EXCEPTIONS = 0x01000000,
540 // All callback events are enabled with this flag
541 COR_PRF_MONITOR_ALL = 0x0107FFFF,
543 // ENABLE_FUNCTION_ARGS enables argument tracing through FunctionEnter2.
544 COR_PRF_ENABLE_FUNCTION_ARGS = 0X02000000,
546 // ENABLE_FUNCTION_RETVAL enables retval tracing through FunctionLeave2.
547 COR_PRF_ENABLE_FUNCTION_RETVAL = 0X04000000,
549 // ENABLE_FRAME_INFO enables retrieval of exact ClassIDs for generic functions using
550 // GetFunctionInfo2 with a COR_PRF_FRAME_INFO obtained from FunctionEnter2.
551 COR_PRF_ENABLE_FRAME_INFO = 0X08000000,
553 // ENABLE_STACK_SNAPSHOT enables the used of DoStackSnapshot calls.
554 COR_PRF_ENABLE_STACK_SNAPSHOT = 0X10000000,
556 // USE_PROFILE_IMAGES causes the native image search to look for profiler-enhanced
557 // images. If no profiler-enhanced image is found for a given assembly the
558 // runtime will fallback to JIT for that assembly.
559 COR_PRF_USE_PROFILE_IMAGES = 0x20000000,
561 // COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST will disable security
562 // transparency checks normally done during JIT compilation and class loading for
563 // full trust assemblies. This can make some instrumentation easier to perform.
564 COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST
567 // Prevents all NGEN images (including profiler-enhanced images) from loading. If
568 // this and COR_PRF_USE_PROFILE_IMAGES are both specified,
569 // COR_PRF_DISABLE_ALL_NGEN_IMAGES wins.
570 COR_PRF_DISABLE_ALL_NGEN_IMAGES = 0x80000000,
572 // The mask for valid mask bits
573 COR_PRF_ALL = 0x8FFFFFFF,
575 // COR_PRF_REQUIRE_PROFILE_IMAGE represents all flags that require profiler-enhanced
577 COR_PRF_REQUIRE_PROFILE_IMAGE = COR_PRF_USE_PROFILE_IMAGES |
578 COR_PRF_MONITOR_CODE_TRANSITIONS |
579 COR_PRF_MONITOR_ENTERLEAVE,
581 COR_PRF_ALLOWABLE_AFTER_ATTACH = COR_PRF_MONITOR_THREADS |
582 COR_PRF_MONITOR_MODULE_LOADS |
583 COR_PRF_MONITOR_ASSEMBLY_LOADS |
584 COR_PRF_MONITOR_APPDOMAIN_LOADS |
585 COR_PRF_ENABLE_STACK_SNAPSHOT |
587 COR_PRF_MONITOR_SUSPENDS |
588 COR_PRF_MONITOR_CLASS_LOADS |
589 COR_PRF_MONITOR_EXCEPTIONS |
590 COR_PRF_MONITOR_JIT_COMPILATION,
592 // MONITOR_IMMUTABLE represents all flags that may only be set during initialization.
593 // Trying to change any of these flags elsewhere will result in a
595 COR_PRF_MONITOR_IMMUTABLE = COR_PRF_MONITOR_CODE_TRANSITIONS |
596 COR_PRF_MONITOR_REMOTING |
597 COR_PRF_MONITOR_REMOTING_COOKIE |
598 COR_PRF_MONITOR_REMOTING_ASYNC |
599 COR_PRF_ENABLE_REJIT |
600 COR_PRF_ENABLE_INPROC_DEBUGGING |
601 COR_PRF_ENABLE_JIT_MAPS |
602 COR_PRF_DISABLE_OPTIMIZATIONS |
603 COR_PRF_DISABLE_INLINING |
604 COR_PRF_ENABLE_OBJECT_ALLOCATED |
605 COR_PRF_ENABLE_FUNCTION_ARGS |
606 COR_PRF_ENABLE_FUNCTION_RETVAL |
607 COR_PRF_ENABLE_FRAME_INFO |
608 COR_PRF_USE_PROFILE_IMAGES |
609 COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST |
610 COR_PRF_DISABLE_ALL_NGEN_IMAGES
614 * Additional flags the profiler can specify via SetEventMask2 when loading
618 COR_PRF_HIGH_MONITOR_NONE = 0x00000000,
620 COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES = 0x00000001,
622 COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x00000002,
624 COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS = 0x00000004,
626 COR_PRF_HIGH_DISABLE_TIERED_COMPILATION = 0x00000008,
628 COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0,
630 COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS,
632 // MONITOR_IMMUTABLE represents all flags that may only be set during initialization.
633 // Trying to change any of these flags elsewhere will result in a
635 COR_PRF_HIGH_MONITOR_IMMUTABLE = COR_PRF_HIGH_DISABLE_TIERED_COMPILATION,
637 } COR_PRF_HIGH_MONITOR;
640 * COR_PRF_MISC contains miscellaneous constant ID's used for special
645 // PROFILER_PARENT_UNKNOWN is the AssemblyID used by GetModuleInfo
646 // when a module has not yet been attached to an assembly.
647 PROFILER_PARENT_UNKNOWN = 0xFFFFFFFD,
649 // PROFILER_GLOBAL_CLASS is a ClassID used for globals that belong to no class
650 PROFILER_GLOBAL_CLASS = 0xFFFFFFFE,
652 // PROFILER_GLOBAL_MODULE is a ModuleID used for globals that belong
653 // to no module in particular
654 PROFILER_GLOBAL_MODULE = 0xFFFFFFFF
658 * COR_PRF_JIT_CACHE contains values used to express the result of a
659 * cached function search. Note that FOUND is 0, and thus this is not truly
664 COR_PRF_CACHED_FUNCTION_FOUND,
665 COR_PRF_CACHED_FUNCTION_NOT_FOUND
669 * COR_PRF_TRANSITION_REASON contains values used to describe
670 * the reason for a ManagedToUnmanaged or UnmanagedToManagedTransition
675 COR_PRF_TRANSITION_CALL,
676 COR_PRF_TRANSITION_RETURN
677 } COR_PRF_TRANSITION_REASON;
680 * COR_PRF_SUSPEND_REASON contains values used to describe the
681 * reason for suspending the runtime. See the RuntimeSuspension*
682 * callbacks for detailed descriptions of each.
686 COR_PRF_SUSPEND_OTHER = 0,
687 COR_PRF_SUSPEND_FOR_GC = 1,
688 COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN = 2,
689 COR_PRF_SUSPEND_FOR_CODE_PITCHING = 3,
690 COR_PRF_SUSPEND_FOR_SHUTDOWN = 4,
691 COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER = 6,
692 COR_PRF_SUSPEND_FOR_GC_PREP = 7,
693 COR_PRF_SUSPEND_FOR_REJIT = 8,
694 } COR_PRF_SUSPEND_REASON;
697 * COR_PRF_RUNTIME_TYPE contains values used to indicate the
702 COR_PRF_DESKTOP_CLR = 0x1,
703 COR_PRF_CORE_CLR = 0x2,
704 } COR_PRF_RUNTIME_TYPE;
707 /* -------------------------------------------------------------------------- *
708 * Forward declarations
709 * -------------------------------------------------------------------------- */
711 interface ICorProfilerCallback;
712 interface ICorProfilerCallback2;
713 interface ICorProfilerCallback3;
714 interface ICorProfilerCallback4;
715 interface ICorProfilerInfo;
716 interface ICorProfilerInfo2;
717 interface ICorProfilerInfo3;
718 interface ICorProfilerInfo4;
719 interface ICorProfilerObjectEnum;
720 interface ICorProfilerFunctionEnum;
721 interface ICorProfilerModuleEnum;
722 interface ICorProfilerThreadEnum;
723 interface ICorProfilerMethodEnum;
724 interface IMethodMalloc;
725 interface ICorProfilerFunctionControl;
726 interface ICorProfilerAssemblyReferenceProvider;
727 /* -------------------------------------------------------------------------- *
728 * User Callback interface
729 * -------------------------------------------------------------------------- */
732 * The ICorProfilerCallback interface is used by the CLR to notify a
733 * code profiler when events have occurred that the code profiler has registered
734 * an in interest in receiving. This is the primary callback interface through
735 * which the CLR communicates with the code profiler. A code profiler
736 * must register this callback interface in the Win32 registry. This object has
737 * several methods that receive notification from the runtime when an event is
738 * about to occur in an executing runtime process.
740 * The methods implemented on this interface return S_OK on success, or E_FAIL
746 uuid(176FBED1-A55C-4796-98CA-A9DA0EF883E7),
747 pointer_default(unique),
750 interface ICorProfilerCallback : IUnknown
755 * STARTUP/SHUTDOWN EVENTS
760 * The CLR calls Initialize to setup the code profiler
761 * whenever a new CLR application is started. The call provides
762 * an IUnknown interface pointer that should be QI'd for an ICorProfilerInfo
765 * NOTE: this is the only opportunity to enable callbacks that are a part
766 * of COR_PRF_MONITOR_IMMUTABLE, since they can no longer be changed after
767 * returning from this function. This is done through SetEventMask on the
768 * ICorProfilerInfo object.
771 [in] IUnknown *pICorProfilerInfoUnk);
774 * The CLR calls Shutdown to notify the code profiler that
775 * the application is exiting. This is the profiler's last opportunity to
776 * safely call functions on the ICorProfilerInfo interface. After returning
777 * from this function the runtime will proceed to unravel its internal data
778 * structures and any calls to ICorProfilerInfo are undefined in their
781 * NOTE: Certain IMMUTABLE events may still occur after Shutdown.
783 * NOTE: Shutdown will only fire where the managed application that is being
784 * profiled was started running managed code (i.e., the initial frame on the
785 * process' stack is managed). If the application being profiled started
786 * life as unmanaged code, which later 'jumped into' managed code (thereby
787 * creating an instance of the CLR), then Shutdown will not fire. In these
788 * cases, the profiler should include a DllMain routine in their library that
789 * uses Win32's DLL_PROCESS_DETACH call to free any resources and perform tidy-up
790 * processing of its data (flush traces to disk, etc)
792 * NOTE: The profiler must in general cope with unexpected shutdowns, such as
793 * when the process is "killed" by Win32's TerminateProcess.
795 * NOTE: Sometimes the CLR will violently kill certain managed threads
796 * (background threads) without delivering orderly destruction messages for them.
803 * APPLICATION DOMAIN EVENTS
808 * Called when an application domain creation has begun and ended.
809 * The ID is not valid for any information request until the Finished
812 * Some parts of app domain loading may take place lazily at some time
813 * after the Finished callback. Therefore, while a failure HRESULT in
814 * hrStatus definitely indicates a failure, a success HRESULT only indicates
815 * that the first part of app domain creation succeeded.
817 HRESULT AppDomainCreationStarted(
818 [in] AppDomainID appDomainId);
820 HRESULT AppDomainCreationFinished(
821 [in] AppDomainID appDomainId,
822 [in] HRESULT hrStatus);
825 * Called before and after an app domain is unloaded from a process.
826 * The ID is no longer valid after the Started event returns.
828 * Some parts of app domain unloading may take place lazily at some time
829 * after the Finished callback. Therefore, while a failure HRESULT in
830 * hrStatus definitely indicates a failure, a success HRESULT only indicates
831 * that the first part of app domain unloading succeeded.
833 HRESULT AppDomainShutdownStarted(
834 [in] AppDomainID appDomainId);
836 HRESULT AppDomainShutdownFinished(
837 [in] AppDomainID appDomainId,
838 [in] HRESULT hrStatus);
847 * Called when an Assembly load has begun and ended. The ID is not valid
848 * for any information request until the Finished event is called.
850 * Some parts of assembly loading may take place lazily at some time
851 * after the Finished callback. Therefore, while a failure HRESULT in
852 * hrStatus definitely indicates a failure, a success HRESULT only indicates
853 * that the first part of assembly loading succeeded.
855 HRESULT AssemblyLoadStarted(
856 [in] AssemblyID assemblyId);
858 HRESULT AssemblyLoadFinished(
859 [in] AssemblyID assemblyId,
860 [in] HRESULT hrStatus);
863 * Called before and after an assembly is unloaded.
864 * The ID is no longer valid after the Started event returns.
866 * Some parts of assembly unloading may take place lazily at some time
867 * after the Finished callback. Therefore, while a failure HRESULT in
868 * hrStatus definitely indicates a failure, a success HRESULT only indicates
869 * that the first part of assembly unloading succeeded.
871 HRESULT AssemblyUnloadStarted(
872 [in] AssemblyID assemblyId);
874 HRESULT AssemblyUnloadFinished(
875 [in] AssemblyID assemblyId,
876 [in] HRESULT hrStatus);
886 * Called when a module load has begun and ended. The ID is not valid
887 * for any information request until the Finished event is called.
889 * Some parts of module loading may take place lazily at some time
890 * after the Finished callback. Therefore, while a failure HRESULT in
891 * hrStatus definitely indicates a failure, a success HRESULT only indicates
892 * that the first part of module loading succeeded.
894 * Note that when a module load is reported as finished this indicates
895 * that the load has completed but it has not yet returned to the caller.
896 * This is the opportunity for the profiler to note that other notifications regarding
897 * this module may start coming afterwards however internal safeguards
898 * protecting the runtime from recursive loading are still present and so it is
899 * a bad time to begin inquiries on this module. The notification is informational
902 * Note: ModuleLoadFinished is a reasonable time to interrogate MetaData via API's
903 * like GetModuleMetadata, however APIs that create (e.g. ClassID's and FunctionID's)
904 * are not safe to use here. Profiler writers are advised to stay in the universe of
908 HRESULT ModuleLoadStarted(
909 [in] ModuleID moduleId);
911 HRESULT ModuleLoadFinished(
912 [in] ModuleID moduleId,
913 [in] HRESULT hrStatus);
916 * Called before and after a module is unloaded.
917 * The ID is no longer valid after the Started event returns.
919 * Some parts of module unloading may take place lazily at some time
920 * after the Finished callback. Therefore, while a failure HRESULT in
921 * hrStatus definitely indicates a failure, a success HRESULT only indicates
922 * that the first part of module unloading succeeded.
924 HRESULT ModuleUnloadStarted(
925 [in] ModuleID moduleId);
927 HRESULT ModuleUnloadFinished(
928 [in] ModuleID moduleId,
929 [in] HRESULT hrStatus);
932 * A module can get loaded through legacy means (ie: IAT or LoadLibrary) or
933 * through a metadata reference. The CLR loader therefore has many code
934 * paths for determining what assembly a module lives in. It is therefore
935 * possible that after a ModuleLoadFinished event, the module does not
936 * know what assembly it is in and getting the parent AssemblyID is not possible.
937 * This event is fired when the module is officially attached to its parent
938 * assembly. Calling GetModuleInfo after this function is called will return the
939 * proper parent assembly.
941 HRESULT ModuleAttachedToAssembly(
942 [in] ModuleID moduleId,
943 [in] AssemblyID AssemblyId);
953 * Called when a class load has begun and ended. The ID is not valid
954 * for any information request until the Finished event is called.
956 * Some parts of class loading may take place lazily at some time
957 * after the Finished callback. Therefore, while a failure HRESULT in
958 * hrStatus definitely indicates a failure, a success HRESULT only indicates
959 * that the first part of class loading succeeded.
961 * Note that when a class load is reported as finished this indicates
962 * that the load has completed but it has not yet returned to the caller.
963 * This is the opportunity for the profiler to note that other notifications regarding
964 * this class may start coming afterwards however internal safeguards
965 * protecting the runtime from recursive loading are still present and so it is
966 * a bad time to begin inquiries on this class. The notification is informational
970 HRESULT ClassLoadStarted(
971 [in] ClassID classId);
973 HRESULT ClassLoadFinished(
974 [in] ClassID classId,
975 [in] HRESULT hrStatus);
978 * Called before and after a class is unloaded.
979 * The ID is no longer valid after the Started event returns.
981 * Some parts of class unloading may take place lazily at some time
982 * after the Finished callback. Therefore, while a failure HRESULT in
983 * hrStatus definitely indicates a failure, a success HRESULT only indicates
984 * that the first part of class unloading succeeded.
986 HRESULT ClassUnloadStarted(
987 [in] ClassID classId);
989 HRESULT ClassUnloadFinished(
990 [in] ClassID classId,
991 [in] HRESULT hrStatus);
1000 * The CLR calls FunctionUnloadStarted to notify the code
1001 * profiler that a function is being unloaded. After returning from this
1002 * call, the FunctionID is no longer valid.
1004 HRESULT FunctionUnloadStarted(
1005 [in] FunctionID functionId);
1009 * The CLR calls JITCompilationStarted to notify the code
1010 * profiler that the JIT compiler is starting to compile a function.
1012 * The fIsSafeToBlock argument tells the profiler whether or not blocking
1013 * will affect the operation of the runtime. If true, blocking may cause
1014 * the runtime to wait for the calling thread to return from this callback.
1015 * Although this will not harm the runtime, it will skew the profiling
1018 * NOTE: It is possible to receive more than one JITCompilationStarted/
1019 * JITCompilationFinished pair for each method. This is because of how
1020 * the runtime handles class constructors: method A starts to be JIT'd,
1021 * then realizes that the class ctor for class B needs to be run, so
1022 * JIT's it and runs it, and while it's running makes a call to original
1023 * method A, which causes it to be JIT'd again, and causes the original
1024 * (incomplete) JIT'ing of A to be aborted. However, both attempts to
1025 * JIT A are reported with JIT compilation events. If the profiler is
1026 * going to replace IL code for this method with SetILFunctionBody, then
1027 * it must do so for both JITCompilationStarted events, but may use the
1028 * same IL block for both.
1030 * NOTE: A profiler should be tolerant of the sequence of JIT callbacks
1031 * received in cases where two threads are simultaneously calling a
1032 * method. For example, thread A receives JITCompilationStarted.
1033 * But before thread A receives JITCompilationFinished, thread B
1034 * receives FunctionEnter with the functionId from thread A's
1035 * JITCompilationStarted callback. It may appear that functionId should
1036 * not yet be valid because JITCompilationFinished had not yet been
1037 * received. But it is indeed valid in such a case.
1039 HRESULT JITCompilationStarted(
1040 [in] FunctionID functionId,
1041 [in] BOOL fIsSafeToBlock);
1044 * The CLR calls JITCompilationFinished to notify the code
1045 * profiler that the JIT compiler has finished compiling a function.
1047 * The fIsSafeToBlock argument tells the profiler whether or not blocking
1048 * will affect the operation of the runtime. If true, blocking may cause
1049 * the runtime to wait for the calling thread to return from this callback.
1050 * Although this will not harm the runtime, it will skew the profiling
1053 * The FunctionID is now valid in ICorProfilerInfo APIs.
1055 * The hrStatus provides the success or failure of the operation
1057 HRESULT JITCompilationFinished(
1058 [in] FunctionID functionId,
1059 [in] HRESULT hrStatus,
1060 [in] BOOL fIsSafeToBlock);
1063 * V2 MIGRATION WARNING: DOES NOT ALWAYS OCCUR
1064 * The JITCachedFunctionSearchStarted/Finished callbacks
1065 * will now occur only for some functions in regular NGEN images;
1066 * only profiler-optimized NGEN images will generate callbacks for
1067 * all functions in the image. Profilers which do not use these callbacks
1068 * to force a function to be JIT-compiled should move to using a lazy
1069 * strategy for gathering function information.
1071 * This notifies the profiler when a search for a prejitted function is
1074 * functionId: the function for which the search is being performed.
1075 * bUseCachedFunction: if true, the EE uses the cached function (if applicable)
1076 * if false, the EE jits the function instead of
1077 * using a pre-jitted version.
1079 * NOTE: Profilers should be tolerant of cases where multiple threads of
1080 * a profiled app are calling the same method simultaneously. For example,
1081 * thread A may receive JITCachedFunctionSearchStarted (and the
1082 * profiler sets *pbUseCachedFunction=FALSE to force a JIT), thread A
1083 * then receives JITCompilationStarted/JITCompilationFinished, then
1084 * thread B receives another JITCachedFunctionSearchStarted for the same
1085 * method. It might appear odd to receive this final callback, since the
1086 * profiler already stated its intention to JIT the method. But this is
1087 * occurring because the CLR in thread B decided to send this callback
1088 * before thread A responded to JITCachedFunctionSearchStarted
1089 * with *pbUseCachedFunction=FALSE, and the thread B callback
1090 * hadn't actually been sent until now due how the threads
1091 * happened to be scheduled. In such cases where the profiler
1092 * receives duplicate JITCachedFunctionSearchStarted callbacks for
1093 * the same functionId, the profiler should be certain to set
1094 * *pbUseCachedFunction to the same value from this callback
1095 * when it is called multiple times with the same functionId.
1097 HRESULT JITCachedFunctionSearchStarted(
1098 [in] FunctionID functionId,
1099 [out] BOOL *pbUseCachedFunction);
1102 * V2 MIGRATION WARNING: DOES NOT ALWAYS OCCUR
1103 * The JITCachedFunctionSearchStarted/Finished callbacks
1104 * will now occur only for some functions in regular NGEN images;
1105 * only profiler-optimized NGEN images will generate callbacks for
1106 * all functions in the image. Profilers which do not use these callbacks
1107 * to force a function to be JIT-compiled should move to using a lazy
1108 * strategy for gathering function information.
1110 * This notifies the profiler when a search for a cached function has been
1113 * functionId: the function for which the search has been performed.
1114 * result: the result of the search. There are two possible results:
1115 * COR_PRF_CACHED_FUNCTION_FOUND
1116 * COR_PRF_CACHED_FUNCTION_NOT_FOUND
1119 HRESULT JITCachedFunctionSearchFinished(
1120 [in] FunctionID functionId,
1121 [in] COR_PRF_JIT_CACHE result);
1124 * The CLR calls JITFunctionPitched to notify the profiler
1125 * that a jitted function was removed from memory. If the pitched
1126 * function is called in the future, the profiler will receive new
1127 * JIT compilation events as it is re-jitted.
1129 * Currently the CLR JIT does not pitch functions, so this callback
1130 * will not be received.
1132 * NOTE: the FunctionID is not valid until it is re-jitted. When it is
1133 * re-jitted, it will use the same FunctionID value.
1135 HRESULT JITFunctionPitched(
1136 [in] FunctionID functionId);
1139 * The CLR calls JITInlining to notify the profiler that the jitter
1140 * is about to inline calleeId into callerId. Set pfShouldInline to FALSE
1141 * to prevent the callee from being inlined into the caller, and set to
1142 * TRUE to allow the inline to occur.
1144 * NOTE: Inlined functions do not provide Enter/Leave events, so if you desire
1145 * an accurate callgraph, you should set FALSE. Be aware that
1146 * setting FALSE will affect performance, since inlining typically
1147 * increases speed and reduces separate jitting events for the inlined
1150 * NOTE: It is also possible to globally disable inlining by setting the
1151 * COR_PRF_DISABLE_INLINING flag.
1153 HRESULT JITInlining(
1154 [in] FunctionID callerId,
1155 [in] FunctionID calleeId,
1156 [out] BOOL *pfShouldInline);
1165 * The CLR calls ThreadCreated to notify the code profiler
1166 * that a thread has been created. The ThreadID is valid immediately.
1168 HRESULT ThreadCreated(
1169 [in] ThreadID threadId);
1172 * The CLR calls ThreadDestroyed to notify the code profiler
1173 * that a thread has been destroyed. The ThreadID is no longer valid
1174 * at the time of this call.
1176 HRESULT ThreadDestroyed(
1177 [in] ThreadID threadId);
1180 * The CLR calls ThreadAssignedToOSThread to tell the profiler
1181 * that a managed thread is being implemented via a particualr OS thread.
1182 * This callback exists so that the profiler can maintain an accurate
1183 * OS to Managed thread mapping across fibres.
1185 HRESULT ThreadAssignedToOSThread(
1186 [in] ThreadID managedThreadId,
1187 [in] DWORD osThreadId);
1196 // Client-side events
1200 * NOTE: each of the following pairs of callbacks will occur on the same
1202 * RemotingClientInvocationStarted & RemotingClientSendingMessage
1203 * RemotingClientReceivingReply & RemotingClientInvocationFinished
1204 * RemotingServerInvocationReturned & RemotingServerSendingReply
1206 * There are a few issues with the remoting callbacks that should be outlined.
1207 * First, remoting function execution is not reflected by the profiler API, so
1208 * the notifications for functions that are called from the client and executed
1209 * to the server are not properly received. The actual invocation happens via a
1210 * proxy object. That creates the illusion to the profiler that certain
1211 * functions get jit-compiled but they never get used. Second, the profiler does
1212 * not receive accurate notifications for asynchronous remoting events.
1216 * The CLR calls RemotingClientInvocationStarted to notify the profiler that
1217 * a remoting call has begun. This event is the same for synchronous and
1218 * asynchronous calls.
1220 HRESULT RemotingClientInvocationStarted();
1223 * The CLR calls RemotingClientSendingMessage to notify the profiler that
1224 * a remoting call is requiring the the caller to send an invocation request through
1225 * a remoting channel.
1227 * pCookie - if remoting GUID cookies are active, this value will correspond with the
1228 * the value provided in RemotingServerReceivingMessage, if the channel
1229 * succeeds in transmitting the message, and if GUID cookies are active on
1230 * the server-side process. This allows easy pairing of remoting calls,
1231 * and the creation of a logical call stack.
1232 * fIsAsync - is true if the call is asynchronous.
1234 HRESULT RemotingClientSendingMessage(
1236 [in] BOOL fIsAsync);
1239 * The CLR calls RemotingClientReceivingReply to notify the profiler that
1240 * the server-side portion of a remoting call has completed and that the client is
1241 * now receiving and about to process the reply.
1243 * pCookie - if remoting GUID cookies are active, this value will correspond with the
1244 * the value provided in RemotingServerSendingReply, if the channel
1245 * succeeds in transmitting the message, and if GUID cookies are active on
1246 * the server-side process. This allows easy pairing of remoting calls.
1247 * fIsAsync - is true if the call is asynchronous.
1249 HRESULT RemotingClientReceivingReply(
1251 [in] BOOL fIsAsync);
1254 * The CLR calls RemotingClientInvocationFinished to notify the profiler that
1255 * a remoting invocation has run to completion on the client side. If the call was
1256 * synchronous, this means that it has also run to completion on the server side. If
1257 * the call was asynchronous, a reply may still be expected when the call is handled.
1258 * If the call is asynchronous, and a reply is expected, then the reply will occur in
1259 * the form of a call to RemotingClientReceivingReply and an additional call to
1260 * RemotingClientInvocationFinished to indicate the required secondary processing of
1261 * an asynchronous call.
1263 HRESULT RemotingClientInvocationFinished();
1266 // Server-side events
1270 * The CLR calls RemotingServerReceivingMessage to notify the profiler that
1271 * the process has received a remote method invocation (or activation) request. If
1272 * the message request is asynchronous, then the request may be serviced by any
1275 * pCookie - if remoting GUID cookies are active, this value will correspond with the
1276 * the value provided in RemotingClientSendingMessage, if the channel
1277 * succeeds in transmitting the message, and if GUID cookies are active on
1278 * the client-side process. This allows easy pairing of remoting calls.
1279 * fIsAsync - is true if the call is asynchronous.
1281 HRESULT RemotingServerReceivingMessage(
1283 [in] BOOL fIsAsync);
1286 * The CLR calls RemotingServerInvocationStarted to notify the profiler that
1287 * the process is invoking a method due to a remote method invocation request.
1289 HRESULT RemotingServerInvocationStarted();
1292 * The CLR calls RemotingServerInvocationReturned to notify the profiler that
1293 * the process has finished invoking a method due to a remote method invocation request.
1295 HRESULT RemotingServerInvocationReturned();
1298 * The CLR calls RemotingServerSendingReply to notify the profiler that
1299 * the process has finished processing a remote method invocation request and is
1300 * about to transmit the reply through a channel.
1302 * pCookie - if remoting GUID cookies are active, this value will correspond with the
1303 * the value provided in RemotingClientReceivingReply, if the channel
1304 * succeeds in transmitting the message, and if GUID cookies are active on
1305 * the client-side process. This allows easy pairing of remoting calls.
1306 * fIsAsync - is true if the call is asynchronous.
1308 HRESULT RemotingServerSendingReply(
1310 [in] BOOL fIsAsync);
1319 * The CLR calls UnmanagedToManagedTransition to notify the
1320 * code profiler that a transition from unmanaged code to managed code has
1321 * occurred. functionId is always the ID of the callee, and reason
1322 * indicates whether the transition was due to a call into managed code from
1323 * unmanaged, or a return from an unmanaged function called by a managed one.
1325 * Note that if the reason is COR_PRF_TRANSITION_RETURN and the functionId is
1326 * non-NULL, then the functionId is that of the unmanaged function, and will
1327 * never have been jitted. Unmanaged functions still have some basic
1328 * information associated with them, such as a name, and some metadata.
1330 * Note that if the reason is COR_PRF_TRANSITION_RETURN and the callee was
1331 * a PInvoke call indirect, then the runtime does not know the destination
1332 * of the call and functionId will be NULL.
1334 * Note that if the reason is COR_PRF_TRANSITION_CALL then it may be possible
1335 * that the callee has not yet been JIT-compiled.
1337 HRESULT UnmanagedToManagedTransition(
1338 [in] FunctionID functionId,
1339 [in] COR_PRF_TRANSITION_REASON reason);
1343 * The CLR calls ManagedToUnmanagedTransition to notify the
1344 * code profiler that a transition from managed code to unmanaged code has
1345 * occurred. functionId is always the ID of the callee, and reason
1346 * indicates whether the transition was due to a call into unmanaged code from
1347 * managed, or a return from an managed function called by an unmanaged one.
1349 * Note that if the reason is COR_PRF_TRANSITION_CALL, then the functionId
1350 * is that of the unmanaged function, and will never have been jitted.
1351 * Unmanaged functions still have some basic information associated with
1352 * them, such as a name, and some metadata.
1354 * Note that if the reason is COR_PRF_TRANSITION_CALL and the callee is
1355 * a PInvoke call indirect, then the runtime does not know the destination
1356 * of the call and functionId will be NULL.
1358 HRESULT ManagedToUnmanagedTransition(
1359 [in] FunctionID functionId,
1360 [in] COR_PRF_TRANSITION_REASON reason);
1365 * RUNTIME SUSPENSION EVENTS
1370 * The CLR calls RuntimeSuspendStarted to notify the code profiler
1371 * that the runtime is about to suspend all of the runtime threads.
1372 * All runtime threads that are in unmanaged code are permitted to continue
1373 * running until they try to re-enter the runtime, at which point they will
1374 * also suspend until the runtime resumes. This also applies to new threads
1375 * that enter the runtime. All threads within the runtime are either
1376 * suspended immediately if they are in interruptible code, or asked to
1377 * suspend when they do reach interruptible code.
1379 * suspendReason make be any of the following values:
1380 * COR_PRF_SUSPEND_FOR_GC
1381 * the runtime is suspending to service a GC request. The GC-related
1382 * callbacks will occur between the RuntimeSuspendFinished and
1383 * RuntimeResumeStarted events.
1384 * COR_PRF_SUSPEND_FOR_CODE_PITCHING
1385 * the runtime is suspending so that code pitching may occur. This
1386 * only occurs when the EJit is active with code pitching enabled.
1387 * Code pitching callbacks will occur between the
1388 * RuntimeSuspendFinished and RuntimeResumeStarted events.
1389 * COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN
1390 * the runtime is suspending so that an AppDomain can be shut down.
1391 * While the runtime is suspended, the runtime will determine which
1392 * threads are in the AppDomain that is being shut down, set them to
1393 * abort when they resume, and then resumes the runtime. There are
1394 * no AppDomain-specific callbacks during this suspension.
1395 * COR_PRF_SUSPEND_FOR_SHUTDOWN
1396 * the runtime is shutting down, and it must suspend all threads to
1397 * complete the operation.
1398 * COR_PRF_SUSPEND_FOR_GC_PREP
1399 * the runtime is preparing for a GC.
1400 * COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER
1401 * the runtime is suspending for in-process debugging.
1402 * COR_PRF_SUSPEND_OTHER
1403 * the runtime is suspending for a reason other than those above.
1405 HRESULT RuntimeSuspendStarted(
1406 [in] COR_PRF_SUSPEND_REASON suspendReason);
1409 * The CLR calls RuntimeSuspendFinished to notify the code profiler
1410 * that the runtime has suspended all threads needed for a runtime
1411 * suspension. Note that not all runtime threads are required to be
1412 * suspended, as described in the comment for RuntimeSuspendStarted.
1414 * NOTE: It is guaranteed that this event will occur on the same ThreadID
1415 * as RuntimeSuspendStarted occurred on.
1417 HRESULT RuntimeSuspendFinished();
1420 * The CLR calls RuntimeSuspendAborted to notify the code profiler
1421 * that the runtime is aborting the runtime suspension that was occurring.
1422 * This may occur if two threads simultaneously attempt to suspend the
1425 * NOTE: It is guaranteed that this event will occur on the same ThreadID
1426 * as the RuntimeSuspendStarted occurred on, and that only one of
1427 * RuntimeSuspendFinished and RuntimeSuspendAborted may occur on a single
1428 * thread following a RuntimeSuspendStarted event.
1430 HRESULT RuntimeSuspendAborted();
1433 * The CLR calls RuntimeResumeStarted to notify the code profiler
1434 * that the runtime is about to resume all of the runtime threads.
1436 HRESULT RuntimeResumeStarted();
1439 * The CLR calls RuntimeResumeFinished to notify the code profiler
1440 * that the runtime has finished resuming all of it's threads and is now
1441 * back in normal operation.
1443 * NOTE: It is *NOT* guaranteed that this event will occur on the same
1444 * ThreadID as the RuntimeSuspendStarted occurred on, but is guaranteed
1445 * to occur on the same ThreadID as the RuntimeResumeStarted occurred on.
1447 HRESULT RuntimeResumeFinished();
1450 * The CLR calls RuntimeThreadSuspended to notify the code profiler
1451 * that a particular thread has been suspended.
1453 * This notification may occur any time between the RuntimeSuspendStarted
1454 * and the associated RuntimeResumeStarted. Notifications that occur
1455 * between RuntimeSuspendFinished and RuntimeResumeStarted are for
1456 * threads that had been running in unmanaged code and were suspended
1457 * upon entry to the runtime.
1459 HRESULT RuntimeThreadSuspended(
1460 [in] ThreadID threadId);
1463 * The CLR calls RuntimeThreadResumed to notify the code profiler
1464 * that a particular thread has been resumed after being suspended due to
1465 * a runtime suspension.
1467 HRESULT RuntimeThreadResumed(
1468 [in] ThreadID threadId);
1474 * NOTE: All of these callbacks (except ObjectAllocated) are made while the
1475 * runtime is suspended, so none of the ObjectID values can change until
1476 * the runtime resumes and another GC occurs.
1478 * NOTE: The profiler will receive GC-related events (except ObjectAllocated)
1479 * when the profiler has been suspended for COR_PRF_SUSPEND_FOR_GC *except*
1480 * for one special case. When the runtime is shutting down, there is a
1481 * stage where it is suspended for COR_PRF_SUSPEND_FOR_SHUTDOWN reason and
1482 * is never resumed. But after this suspension a garbage collection may
1483 * occur without a COR_PRF_SUSPEND_FOR_GC suspension notification, and
1484 * the profiler will thus receive GC-related callbacks.
1486 * NOTE: All of these callbacks (except ObjectAllocated) may be called more than
1487 * once during the same GC. These calls should be considered multiple parts of
1488 * one long report; the profiler should simply aggregate the information provided
1493 * The CLR calls MovedReferences with information about
1494 * object references that moved as a result of garbage collection.
1496 * cMovedObjectIDRanges is a count of the number of ObjectID ranges that
1498 * oldObjectIDRangeStart is an array of elements, each of which is the start
1499 * value of a range of ObjectID values before being moved.
1500 * newObjectIDRangeStart is an array of elements, each of which is the start
1501 * value of a range of ObjectID values after being moved.
1502 * cObjectIDRangeLength is an array of elements, each of which states the
1503 * size of the moved ObjectID value range.
1505 * The last three arguments of this function are parallel arrays.
1507 * In other words, if an ObjectID value lies within the range
1508 * oldObjectIDRangeStart[i] <= ObjectID < oldObjectIDRangeStart[i] + cObjectIDRangeLength[i]
1509 * for 0 <= i < cMovedObjectIDRanges, then the ObjectID value has changed to
1510 * ObjectID - oldObjectIDRangeStart[i] + newObjectIDRangeStart[i]
1512 * NOTE: None of the objectIDs returned by MovedReferences are valid during the callback
1513 * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
1514 * should not attempt to inspect objects during a MovedReferences call. At
1515 * GarbageCollectionFinished, all objects have been moved to their new locations, and
1516 * inspection may be done.
1518 * THIS CALLBACK IS OBSOLETE. It reports ranges for objects >4GB as ULONG_MAX
1519 * on 64-bit platforms. Use ICorProfilerCallback4::MovedReferences2 instead.
1521 HRESULT MovedReferences(
1522 [in] ULONG cMovedObjectIDRanges,
1523 [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
1524 [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
1525 [in, size_is(cMovedObjectIDRanges)] ULONG cObjectIDRangeLength[] );
1528 * The CLR calls ObjectAllocated to notify the code profiler
1529 * an object was allocated on the heap. This notification does not fire
1530 * for allocations from the stack, nor from unmanaged memory.
1532 * It is possible to receive a classId that corresponds to a regular class
1533 * that has not been loaded yet. The profiler will receive a class load
1534 * callback for that class immediately after the object creation callback.
1536 HRESULT ObjectAllocated(
1537 [in] ObjectID objectId,
1538 [in] ClassID classId);
1541 * The CLR calls ObjectsAllocatedByClass to notify the code
1542 * profiler about the number of objects of a particular class that were
1543 * allocated since the previous garbage collection. The classes and the
1544 * counts are passed in parallel arrays. (Classes for which no instances
1545 * have been allocated since the previous GC are omitted entirely.)
1547 * NOTE: This callback will not report objects allocated in the large
1550 * NOTE: The numbers here are only estimates. Use ObjectAllocated for
1553 HRESULT ObjectsAllocatedByClass(
1554 [in] ULONG cClassCount,
1555 [in, size_is(cClassCount)] ClassID classIds[] ,
1556 [in, size_is(cClassCount)] ULONG cObjects[] );
1559 * The CLR calls ObjectReferences to provide information
1560 * about objects in memory referenced by a given object. This function
1561 * is called for each object remaining in the GC heap after a collection
1562 * has completed. If the profiler returns an error from this callback,
1563 * the profiling services will discontinue invoking this callback until the
1564 * next GC. This callback can be used in conjunction with the
1565 * RootReferences callback to create a complete object reference graph for
1568 * NOTE: The CLR will ensure that each object reference is reported only
1569 * once by this function.
1571 * NOTE: None of the objectIDs returned by ObjectReferences are valid during the callback
1572 * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
1573 * should not attempt to inspect objects during an ObjectReferences call. At
1574 * GarbageCollectionFinished, all objects have been moved to their new locations, and
1575 * inspection may be done.
1577 HRESULT ObjectReferences(
1578 [in] ObjectID objectId,
1579 [in] ClassID classId,
1580 [in] ULONG cObjectRefs,
1581 [in, size_is(cObjectRefs)] ObjectID objectRefIds[] );
1584 * The CLR calls RootReferences with information about root
1585 * references after a garbage collection has occurred. Static object
1586 * references and references to objects on a stack are co-mingled in the
1589 * NOTE: It is possible to get NULL ObjectIDs in the RootReferences callback.
1590 * For example, all object references declared on the stack are treated as
1591 * roots by the GC, and will always be reported.
1593 * NOTE: None of the objectIDs returned by RootReferences are valid during the callback
1594 * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
1595 * should not attempt to inspect objects during a RootReferences call. At
1596 * GarbageCollectionFinished, all objects have been moved to their new locations, and
1597 * inspection may be done.
1599 HRESULT RootReferences(
1600 [in] ULONG cRootRefs,
1601 [in, size_is(cRootRefs)] ObjectID rootRefIds[] );
1611 // Exception creation
1615 * The CLR calls ExceptionThrown to notify the code
1616 * profiler that an exception has been thrown.
1618 * NOTE: This function is only called if the exception reaches
1621 * NOTE: The profiler should not block here, since the stack may not be in a
1622 * GC-friendly state and so preemptive GC cannot be enabled. If the
1623 * profiler blocks here and a GC is attempted, the runtime will block
1624 * until this callback returns. Also, the profiler may NOT call into
1625 * managed code or in any way cause a managed memory allocation.
1627 HRESULT ExceptionThrown(
1628 [in] ObjectID thrownObjectId);
1635 * The CLR calls ExceptionSearchFunctionEnter to notify the profiler
1636 * that the search phase of exception handling has entered a function.
1638 HRESULT ExceptionSearchFunctionEnter(
1639 [in] FunctionID functionId);
1642 * The CLR calls ExceptionSearchFunctionLeave to notify the profiler
1643 * that the search phase of exception handling has left a function.
1645 HRESULT ExceptionSearchFunctionLeave();
1648 * The CLR will call ExceptionSearchFilterEnter just before excecuting
1649 * a user filter. The functionID is that of the function containing the filter.
1651 HRESULT ExceptionSearchFilterEnter(
1652 [in] FunctionID functionId);
1655 * The CLR will call ExceptionSearchFilterLeave immediately after
1656 * executing a user filter.
1658 HRESULT ExceptionSearchFilterLeave();
1661 * The CLR will call ExceptionSearchCatcherFound when the search
1662 * phase of exception handling has located a handler for the exception that
1665 HRESULT ExceptionSearchCatcherFound(
1666 [in] FunctionID functionId);
1669 * DEPRECATED. It is the job of the unmanaged profiler to detect OS
1670 * handling of exceptions.
1672 HRESULT ExceptionOSHandlerEnter(
1673 [in] UINT_PTR __unused);
1676 * DEPRECATED. It is the job of the unmanaged profiler to detect OS
1677 * handling of exceptions.
1679 HRESULT ExceptionOSHandlerLeave(
1680 [in] UINT_PTR __unused);
1687 * The CLR calls ExceptionUnwindFunctionEnter to notify the profiler
1688 * that the unwind phase of exception handling has entered a function.
1690 * NOTE: The profiler should not block here, since the stack may not be in a
1691 * GC-friendly state and so preemptive GC cannot be enabled. If the
1692 * profiler blocks here and a GC is attempted, the runtime will block
1693 * until this callback returns. Also, the profiler may NOT call into
1694 * managed code or in any way cause a managed memory allocation.
1696 HRESULT ExceptionUnwindFunctionEnter(
1697 [in] FunctionID functionId);
1700 * The CLR calls ExceptionUnwindFunctionLeave to notify the profiler
1701 * that the unwind phase of exception handling has left a function. The
1702 * function instance and it's stack data has now been removed from the stack.
1704 * NOTE: The profiler should not block here, since the stack may not be in a
1705 * GC-friendly state and so preemptive GC cannot be enabled. If the
1706 * profiler blocks here and a GC is attempted, the runtime will block
1707 * until this callback returns. Also, the profiler may NOT call into
1708 * managed code or in any way cause a managed memory allocation.
1710 HRESULT ExceptionUnwindFunctionLeave();
1713 * The CLR calls ExceptionUnwindFinallyEnter to notify the profiler
1714 * that the unwind phase of exception is entering a finally clause contained
1715 * in the specified function.
1717 * NOTE: The profiler should not block here, since the stack may not be in a
1718 * GC-friendly state and so preemptive GC cannot be enabled. If the
1719 * profiler blocks here and a GC is attempted, the runtime will block
1720 * until this callback returns. Also, the profiler may NOT call into
1721 * managed code or in any way cause a managed memory allocation.
1723 HRESULT ExceptionUnwindFinallyEnter(
1724 [in] FunctionID functionId);
1727 * The CLR calls ExceptionUnwindFinallyLeave to notify the profiler
1728 * that the unwind phase of exception is leaving a finally clause.
1730 * NOTE: The profiler should not block here, since the stack may not be in a
1731 * GC-friendly state and so preemptive GC cannot be enabled. If the
1732 * profiler blocks here and a GC is attempted, the runtime will block
1733 * until this callback returns. Also, the profiler may NOT call into
1734 * managed code or in any way cause a managed memory allocation.
1736 HRESULT ExceptionUnwindFinallyLeave();
1739 * The CLR calls this function just before passing control to
1740 * the appropriate catch block. Note that this is called only if the
1741 * catch point is in JIT'ed code. An exception that is caught in
1742 * unmanaged code, or in the internal code of the CLR will
1743 * not generate this notification. The ObjectID is passed again since
1744 * a GC could have moved the object since the ExceptionThrown
1747 * NOTE: The profiler should not block here, since the stack may not be in a
1748 * GC-friendly state and so preemptive GC cannot be enabled. If the
1749 * profiler blocks here and a GC is attempted, the runtime will block
1750 * until this callback returns. Also, the profiler may NOT call into
1751 * managed code or in any way cause a managed memory allocation.
1753 HRESULT ExceptionCatcherEnter(
1754 [in] FunctionID functionId,
1755 [in] ObjectID objectId);
1758 * The CLR calls ExceptionCatcherLeave when the runtime leaves
1759 * the catcher's code.
1761 * NOTE: The profiler should not block here, since the stack may not be in a
1762 * GC-friendly state and so preemptive GC cannot be enabled. If the
1763 * profiler blocks here and a GC is attempted, the runtime will block
1764 * until this callback returns. Also, the profiler may NOT call into
1765 * managed code or in any way cause a managed memory allocation.
1767 HRESULT ExceptionCatcherLeave();
1770 * CLR<->COM interop vtable creation/destruction.
1774 * The CLR calls this function when an CLR<->COM interop vtable
1775 * for a particular IID and for a particular class has been created.
1776 * This provides the ClassID of the class for which this vtable has been
1777 * created, the IID it implements, the start of the vtable and how many
1780 * NOTE: The profiler should not block here, since the stack may not be in a
1781 * GC-friendly state and so preemptive GC cannot be enabled. If the
1782 * profiler blocks here and a GC is attempted, the runtime will block
1783 * until this callback returns. Also, the profiler may NOT call into
1784 * managed code or in any way cause a managed memory allocation.
1786 * NOTE: It is possible to receive a NULL GUID if the interface is
1789 HRESULT COMClassicVTableCreated(
1790 [in] ClassID wrappedClassId,
1791 [in] REFGUID implementedIID,
1796 * The CLR calls this function when a CLR<->COM interop vtable is
1797 * being destroyed. Provided are the ClassID, IID and vtable pointer for
1798 * the destroyed vtable.
1800 * NOTE: The profiler should not block here, since the stack may not be in a
1801 * GC-friendly state and so preemptive GC cannot be enabled. If the
1802 * profiler blocks here and a GC is attempted, the runtime will block
1803 * until this callback returns. Also, the profiler may NOT call into
1804 * managed code or in any way cause a managed memory allocation.
1806 * NOTE: It is possible to receive a NULL GUID if the interface is
1809 * NOTE: This callback is likely never to occur, since the destruction of
1810 * vtables occurs very close to Shutdown.
1812 HRESULT COMClassicVTableDestroyed(
1813 [in] ClassID wrappedClassId,
1814 [in] REFGUID implementedIID,
1815 [in] void *pVTable);
1818 * DEPRECATED. These callbacks are no longer delivered.
1820 HRESULT ExceptionCLRCatcherFound();
1822 HRESULT ExceptionCLRCatcherExecute();
1826 * COR_PRF_GC_ROOT_KIND describes the kind of GC root exposed by
1827 * the RootReferences2 callback.
1832 COR_PRF_GC_ROOT_STACK = 1, // Variables on the stack
1833 COR_PRF_GC_ROOT_FINALIZER = 2, // Entry in the finalizer queue
1834 COR_PRF_GC_ROOT_HANDLE = 3, // GC Handle
1835 COR_PRF_GC_ROOT_OTHER = 0 //Misc. roots
1836 } COR_PRF_GC_ROOT_KIND;
1840 * COR_PRF_GC_ROOT_FLAGS describes properties of a GC root
1841 * exposed by the RootReferences callback.
1846 COR_PRF_GC_ROOT_PINNING = 0x1, // Prevents GC from moving the object
1847 COR_PRF_GC_ROOT_WEAKREF = 0x2, // Does not prevent collection
1848 COR_PRF_GC_ROOT_INTERIOR = 0x4, // Refers to a field of the object rather than the object itself
1849 COR_PRF_GC_ROOT_REFCOUNTED = 0x8, // Whether it prevents collection depends on a refcount - if not,
1850 // COR_PRF_GC_ROOT_WEAKREF will be set also
1851 } COR_PRF_GC_ROOT_FLAGS;
1855 * COR_PRF_FINALIZER_FLAGS is used by FinalizableObjectQueued to describe
1856 * the finalizer for the object.
1861 COR_PRF_FINALIZER_CRITICAL = 0x1 // Critical finalizer
1862 } COR_PRF_FINALIZER_FLAGS;
1866 * COR_PRF_GC_GENERATION contains the numbers used to represent each GC generation
1867 * in the GetGenerationBounds and GetObjectGeneration functions.
1872 COR_PRF_GC_GEN_0 = 0,
1873 COR_PRF_GC_GEN_1 = 1,
1874 COR_PRF_GC_GEN_2 = 2,
1875 COR_PRF_GC_LARGE_OBJECT_HEAP = 3
1876 } COR_PRF_GC_GENERATION;
1880 * COR_PRF_GC_GENERATION_RANGE describes a range of memory in the GetGenerationBounds and GetObjectGeneration functions.
1881 * Note that the rangeLength member is only guaranteed to be accurate if GetGenerationBounds or GetObjectGeneration are
1882 * called from a GarbageCollectionStarted or GarbageCollectionFinished notification
1884 typedef struct COR_PRF_GC_GENERATION_RANGE
1886 COR_PRF_GC_GENERATION generation; // what generation the range of memory belongs to
1887 ObjectID rangeStart; // the start of the range
1888 UINT_PTR rangeLength; // the used length of the range
1889 UINT_PTR rangeLengthReserved; // the amount of memory reserved for the range (including rangeLength)
1891 } COR_PRF_GC_GENERATION_RANGE;
1896 * COR_PRF_CLAUSE_TYPE defines the various clause codes for the EX clauses
1900 COR_PRF_CLAUSE_NONE = 0, // not a real clause (only used in error cases)
1901 COR_PRF_CLAUSE_FILTER = 1,
1902 COR_PRF_CLAUSE_CATCH = 2,
1903 COR_PRF_CLAUSE_FINALLY = 3,
1904 } COR_PRF_CLAUSE_TYPE;
1907 * COR_PRF_EX_CLAUSE_INFO identifies a specific exception clause instance and its associated frame.
1908 * When an exception notification is received, GetNotifiedExceptionClauseInfo() may be used to get the
1909 * native address and frame information for the exception clause (catch/finally/filter) that is
1910 * about to be run (ExceptionCatchEnter, ExceptionUnwindFinallyEnter, ExceptionFilterEnter) or has just
1911 * been run (ExceptionCatchLeave, ExceptionUnwindFinallyLeave, ExceptionFilterLeave).
1913 typedef struct COR_PRF_EX_CLAUSE_INFO
1915 COR_PRF_CLAUSE_TYPE clauseType; // the type of clause we just entered or left
1916 UINT_PTR programCounter; // the native entry point of the clause handler (e.g. EIP)
1917 UINT_PTR framePointer; // the logical frame pointer (e.g. EBP) for that clause handler
1918 UINT_PTR shadowStackPointer; // the shadow stack pointer (IA64 only, BSP)
1919 } COR_PRF_EX_CLAUSE_INFO;
1922 * COR_PRF_GC_REASON describes the reason for a given GC.
1926 COR_PRF_GC_INDUCED = 1, // Induced by GC.Collect
1927 COR_PRF_GC_OTHER = 0 // Anything else
1928 } COR_PRF_GC_REASON;
1931 * Bits from COR_PRF_MODULE_FLAGS are returned to the profiler in GetModuleInfo2's
1932 * pdwModuleFlags output parameter. Some combinations of 2 or more flags are possible,
1933 * though not all combinations are possible.
1937 // The module was loaded from disk
1938 COR_PRF_MODULE_DISK = 0x00000001,
1940 // The module had been generated via NGEN
1941 COR_PRF_MODULE_NGEN = 0x00000002,
1943 // The module was created via methods in the Reflection.Emit namespace
1944 COR_PRF_MODULE_DYNAMIC = 0x00000004,
1946 // The module's lifetime is managed by the garbage collector.
1947 COR_PRF_MODULE_COLLECTIBLE = 0x00000008,
1949 // The module contains no metadata and is used strictly as a resource. The managed
1950 // equivalent of this bit is the System.Reflection.Module.IsResource() method.
1951 COR_PRF_MODULE_RESOURCE = 0x00000010,
1953 // The module's layout in memory is flat, as opposed to mapped. For modules that have
1954 // this bit set, profilers that directly read information out of the PE header will
1955 // need to be careful when interpreting RVAs present in the PE header.
1956 COR_PRF_MODULE_FLAT_LAYOUT = 0x00000020,
1958 // The Windows Runtime content type flag is set in the metadata for this module's
1960 COR_PRF_MODULE_WINDOWS_RUNTIME = 0x00000040,
1961 } COR_PRF_MODULE_FLAGS;
1963 * The ICorProfilerCallback2 interface is used by the CLR to notify a
1964 * code profiler when events have occurred that the code profiler has registered
1965 * an in interest in receiving. These are new callbacks implemented in V2.0
1968 * The methods implemented on this interface return S_OK on success, or E_FAIL
1974 uuid(8A8CC829-CCF2-49fe-BBAE-0F022228071A),
1975 pointer_default(unique),
1978 interface ICorProfilerCallback2 : ICorProfilerCallback
1988 * The CLR calls ThreadNameChanged to notify the code profiler
1989 * that a thread's name has changed.
1991 * name is not NULL terminated.
1994 HRESULT ThreadNameChanged(
1995 [in] ThreadID threadId,
1997 [in, annotation("_In_reads_opt_(cchName)")] WCHAR name[]);
2001 * GARBAGE COLLECTION EVENTS
2006 * The CLR calls GarbageCollectionStarted before beginning a
2007 * garbage collection. All GC callbacks pertaining to this
2008 * collection will occur between the GarbageCollectionStarted
2009 * callback and the corresponding GarbageCollectionFinished
2010 * callback. Corresponding GarbageCollectionStarted and
2011 * GarbageCollectionFinished callbacks need not occur on the same thread.
2013 * cGenerations indicates the total number of entries in
2014 * the generationCollected array
2015 * generationCollected is an array of booleans, indexed
2016 * by COR_PRF_GC_GENERATIONS, indicating which
2017 * generations are being collected in this collection
2018 * reason indicates whether this GC was induced
2019 * by the application calling GC.Collect().
2021 * NOTE: It is safe to inspect objects in their original locations
2022 * during this callback. The GC will begin moving objects after
2023 * the profiler returns from this callback. Therefore, after
2024 * returning, the profiler should consider all ObjectIDs to be invalid
2025 * until it receives a GarbageCollectionFinished callback.
2027 HRESULT GarbageCollectionStarted(
2028 [in] int cGenerations,
2029 [in, size_is(cGenerations)] BOOL generationCollected[],
2030 [in] COR_PRF_GC_REASON reason);
2033 * The CLR calls SurvivingReferences with information about
2034 * object references that survived a garbage collection.
2036 * Generally, the CLR calls SurvivingReferences for non-compacting garbage collections.
2037 * For compacting garbage collections, MovedReferences is called instead.
2039 * The exception to this rule is that the CLR always calls SurvivingReferences for objects
2040 * in the large object heap, which is not compacted.
2042 * Multiple calls to SurvivingReferences may be received during a particular
2043 * garbage collection, due to limited internal buffering, multiple threads reporting
2044 * in the case of server gc, and other reasons.
2045 * In the case of multiple calls, the information is cumulative - all of the references
2046 * reported in any SurvivingReferences call survive this collection.
2048 * cSurvivingObjectIDRanges is a count of the number of ObjectID ranges that
2050 * objectIDRangeStart is an array of elements, each of which is the start
2051 * value of a range of ObjectID values that survived the collection.
2052 * cObjectIDRangeLength is an array of elements, each of which states the
2053 * size of the surviving ObjectID value range.
2055 * The last two arguments of this function are parallel arrays.
2057 * In other words, if an ObjectID value lies within the range
2058 * objectIDRangeStart[i] <= ObjectID < objectIDRangeStart[i] + cObjectIDRangeLength[i]
2059 * for 0 <= i < cMovedObjectIDRanges, then the ObjectID has survived the collection
2061 * THIS CALLBACK IS OBSOLETE. It reports ranges for objects >4GB as ULONG_MAX
2062 * on 64-bit platforms. Use ICorProfilerCallback4::SurvivingReferences2 instead.
2064 HRESULT SurvivingReferences(
2065 [in] ULONG cSurvivingObjectIDRanges,
2066 [in, size_is(cSurvivingObjectIDRanges)] ObjectID objectIDRangeStart[] ,
2067 [in, size_is(cSurvivingObjectIDRanges)] ULONG cObjectIDRangeLength[] );
2069 * The CLR calls GarbageCollectionFinished after a garbage
2070 * collection has completed and all GC callbacks have been
2073 * NOTE: It is now safe to inspect objects in their
2076 HRESULT GarbageCollectionFinished();
2079 * The CLR calls FinalizeableObjectQueued to notify the code profiler
2080 * that an object with a finalizer (destructor in C# parlance) has
2081 * just been queued to the finalizer thread for execution of its
2084 * finalizerFlags describes aspects of the finalizer, and takes its
2085 * value from COR_PRF_FINALIZER_FLAGS.
2089 HRESULT FinalizeableObjectQueued(
2090 [in] DWORD finalizerFlags,
2091 [in] ObjectID objectID);
2094 * The CLR calls RootReferences2 with information about root
2095 * references after a garbage collection has occurred.
2096 * For each root reference in rootRefIds, there is information in
2097 * rootClassifications to classify it. Depending on the classification,
2098 * rootsIds may contain additional information. The information in
2099 * rootKinds and rootFlags contains information about the location and
2100 * properties of the reference.
2102 * If the profiler implements ICorProfilerCallback2, both
2103 * ICorProfilerCallback::RootReferences and ICorProfilerCallback2::RootReferences2
2104 * are called. As the information passed to RootReferences2 is a superset
2105 * of the one passed to RootReferences, profilers will normally implement
2106 * one or the other, but not both.
2108 * If the root kind is STACK, the ID is the FunctionID of the
2109 * function containing the variable. If the FunctionID is 0, the function
2110 * is an unnamed function internal to the CLR.
2112 * If the root kind is HANDLE, the ID is the GCHandleID.
2114 * For the other root kinds, the ID is an opaque value and should
2117 * It's possible for entries in rootRefIds to be 0 - this just
2118 * implies the corresponding root reference was null and thus did not
2119 * refer to an object on the managed heap.
2121 * NOTE: None of the objectIDs returned by RootReferences2 are valid during the callback
2122 * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
2123 * should not attempt to inspect objects during a RootReferences2 call. At
2124 * GarbageCollectionFinished, all objects have been moved to their new locations, and
2125 * inspection may be done.
2128 HRESULT RootReferences2(
2129 [in] ULONG cRootRefs,
2130 [in, size_is(cRootRefs)] ObjectID rootRefIds[],
2131 [in, size_is(cRootRefs)] COR_PRF_GC_ROOT_KIND rootKinds[],
2132 [in, size_is(cRootRefs)] COR_PRF_GC_ROOT_FLAGS rootFlags[],
2133 [in, size_is(cRootRefs)] UINT_PTR rootIds[]);
2136 * The CLR calls HandleCreated when a gc handle has been created.
2140 HRESULT HandleCreated(
2141 [in] GCHandleID handleId,
2142 [in] ObjectID initialObjectId);
2145 * The CLR calls HandleDestroyed when a gc handle has been destroyed.
2149 HRESULT HandleDestroyed(
2150 [in] GCHandleID handleId);
2155 uuid(4FD2ED52-7731-4b8d-9469-03D2CC3086C5),
2156 pointer_default(unique),
2159 interface ICorProfilerCallback3 : ICorProfilerCallback2
2161 HRESULT InitializeForAttach(
2162 [in] IUnknown * pCorProfilerInfoUnk,
2163 [in] void * pvClientData,
2164 [in] UINT cbClientData);
2166 HRESULT ProfilerAttachComplete();
2168 HRESULT ProfilerDetachSucceeded();
2173 uuid(7B63B2E3-107D-4d48-B2F6-F61E229470D2),
2174 pointer_default(unique),
2177 interface ICorProfilerCallback4 : ICorProfilerCallback3
2180 * Similar to JITCompilationStarted, except called when rejitting a method
2182 HRESULT ReJITCompilationStarted(
2183 [in] FunctionID functionId,
2184 [in] ReJITID rejitId,
2185 [in] BOOL fIsSafeToBlock);
2188 * This is called exactly once per method (which may represent more than
2189 * one function id), to allow the code profiler to set alternate code
2190 * generation flags or a new method body.
2192 HRESULT GetReJITParameters(
2193 [in] ModuleID moduleId,
2194 [in] mdMethodDef methodId,
2195 [in] ICorProfilerFunctionControl *pFunctionControl);
2198 * Similar to JITCompilationFinished, except called when rejitting a method
2200 HRESULT ReJITCompilationFinished(
2201 [in] FunctionID functionId,
2202 [in] ReJITID rejitId,
2203 [in] HRESULT hrStatus,
2204 [in] BOOL fIsSafeToBlock);
2207 * This is called to report an error encountered while processing a ReJIT request.
2208 * This may either be called from within the RequestReJIT call itself, or called after
2209 * RequestReJIT returns, if the error was encountered later on.
2212 [in] ModuleID moduleId,
2213 [in] mdMethodDef methodId,
2214 [in] FunctionID functionId,
2215 [in] HRESULT hrStatus);
2218 * The CLR calls MovedReferences with information about
2219 * object references that moved as a result of garbage collection.
2221 * cMovedObjectIDRanges is a count of the number of ObjectID ranges that
2223 * oldObjectIDRangeStart is an array of elements, each of which is the start
2224 * value of a range of ObjectID values before being moved.
2225 * newObjectIDRangeStart is an array of elements, each of which is the start
2226 * value of a range of ObjectID values after being moved.
2227 * cObjectIDRangeLength is an array of elements, each of which states the
2228 * size of the moved ObjectID value range.
2230 * The last three arguments of this function are parallel arrays.
2232 * In other words, if an ObjectID value lies within the range
2233 * oldObjectIDRangeStart[i] <= ObjectID < oldObjectIDRangeStart[i] + cObjectIDRangeLength[i]
2234 * for 0 <= i < cMovedObjectIDRanges, then the ObjectID value has changed to
2235 * ObjectID - oldObjectIDRangeStart[i] + newObjectIDRangeStart[i]
2237 * NOTE: None of the objectIDs returned by MovedReferences are valid during the callback
2238 * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
2239 * should not attempt to inspect objects during a MovedReferences call. At
2240 * GarbageCollectionFinished, all objects have been moved to their new locations, and
2241 * inspection may be done.
2243 * If the profiler implements ICorProfilerCallback4, ICorProfilerCallback4::MovedReferences2
2244 * is called first and ICorProfilerCallback::MovedReferences is called second but only if
2245 * ICorProfilerCallback4::MovedReferences2 returned success. Profilers can return failure
2246 * from ICorProfilerCallback4::MovedReferences2 to save some chattiness.
2248 HRESULT MovedReferences2(
2249 [in] ULONG cMovedObjectIDRanges,
2250 [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
2251 [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
2252 [in, size_is(cMovedObjectIDRanges)] SIZE_T cObjectIDRangeLength[] );
2255 * The CLR calls SurvivingReferences with information about
2256 * object references that survived a garbage collection.
2258 * Generally, the CLR calls SurvivingReferences for non-compacting garbage collections.
2259 * For compacting garbage collections, MovedReferences is called instead.
2261 * The exception to this rule is that the CLR always calls SurvivingReferences for objects
2262 * in the large object heap, which is not compacted.
2264 * Multiple calls to SurvivingReferences may be received during a particular
2265 * garbage collection, due to limited internal buffering, multiple threads reporting
2266 * in the case of server gc, and other reasons.
2267 * In the case of multiple calls, the information is cumulative - all of the references
2268 * reported in any SurvivingReferences call survive this collection.
2270 * cSurvivingObjectIDRanges is a count of the number of ObjectID ranges that
2272 * objectIDRangeStart is an array of elements, each of which is the start
2273 * value of a range of ObjectID values that survived the collection.
2274 * cObjectIDRangeLength is an array of elements, each of which states the
2275 * size of the surviving ObjectID value range.
2277 * The last two arguments of this function are parallel arrays.
2279 * In other words, if an ObjectID value lies within the range
2280 * objectIDRangeStart[i] <= ObjectID < objectIDRangeStart[i] + cObjectIDRangeLength[i]
2281 * for 0 <= i < cMovedObjectIDRanges, then the ObjectID has survived the collection
2283 * If the profiler implements ICorProfilerCallback4, ICorProfilerCallback4::SurvivingReferences2
2284 * is called first and ICorProfilerCallback2::SurvivingReferences is called second but only if
2285 * ICorProfilerCallback4::SurvivingReferences2 returned success. Profilers can return failure
2286 * from ICorProfilerCallback4::SurvivingReferences2 to save some chattiness.
2288 HRESULT SurvivingReferences2(
2289 [in] ULONG cSurvivingObjectIDRanges,
2290 [in, size_is(cSurvivingObjectIDRanges)] ObjectID objectIDRangeStart[] ,
2291 [in, size_is(cSurvivingObjectIDRanges)] SIZE_T cObjectIDRangeLength[] );
2298 uuid(8DFBA405-8C9F-45F8-BFFA-83B14CEF78B5),
2299 pointer_default(unique),
2302 interface ICorProfilerCallback5 : ICorProfilerCallback4
2305 * The CLR calls ConditionalWeakTableElementReferences with information
2306 * about dependent handles after a garbage collection has occurred.
2308 * For each root ID in rootIds, keyRefIds will contain the ObjectID for
2309 * the primary element in the dependent handle pair, and valueRefIds will
2310 * contain the ObjectID for the secondary element (keyRefIds[i] keeps
2311 * valueRefIds[i] alive).
2313 * NOTE: None of the objectIDs returned by ConditionalWeakTableElementReferences
2314 * are valid during the callback itself, as the GC may be in the middle
2315 * of moving objects from old to new. Thus profilers should not attempt
2316 * to inspect objects during a ConditionalWeakTableElementReferences call.
2317 * At GarbageCollectionFinished, all objects have been moved to their new
2318 * locations, and inspection may be done.
2320 HRESULT ConditionalWeakTableElementReferences(
2321 [in] ULONG cRootRefs,
2322 [in, size_is(cRootRefs)] ObjectID keyRefIds[],
2323 [in, size_is(cRootRefs)] ObjectID valueRefIds[],
2324 [in, size_is(cRootRefs)] GCHandleID rootIds[]);
2330 uuid(FC13DF4B-4448-4F4F-950C-BA8D19D00C36),
2331 pointer_default(unique),
2334 interface ICorProfilerCallback6 : ICorProfilerCallback5
2336 // Controlled by the COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES event mask flag.
2337 // Notifies the profiler of a very early stage in the loading of an Assembly, where the CLR
2338 // performs an assembly reference closure walk. This is useful ONLY if the profiler will need
2339 // to modify the metadata of the Assembly to add AssemblyRefs (later, in ModuleLoadFinished). In
2340 // such a case, the profiler should implement this callback as well, to inform the CLR that assembly references
2341 // will be added once the module has loaded. This is useful to ensure that assembly sharing decisions
2342 // made by the CLR during this early stage remain valid even though the profiler plans to modify the metadata
2343 // assembly references later on. This can be used to avoid some instances where profiler metadata
2344 // modifications can cause the SECURITY_E_INCOMPATIBLE_SHARE error to be thrown.
2346 // The profiler uses the ICorProfilerAssemblyReferenceProvider provided to add assembly references
2347 // to the CLR assembly reference closure walker. The ICorProfilerAssemblyReferenceProvider
2348 // should only be used from within this callback. The profiler will still need to explicitly add assembly
2349 // references via IMetaDataAssemblyEmit, from within the ModuleLoadFinished callback for the referencing assembly,
2350 // even though the profiler implements this GetAssemblyReferences callback. This callback does not result in
2351 // modified metadata; only in a modified assembly reference closure walk.
2353 // The profiler should be prepared to receive duplicate calls to this callback for the same assembly,
2354 // and should respond identically for each such duplicate call (by making the same set of
2355 // ICorProfilerAssemblyReferenceProvider::AddAssemblyReference calls).
2356 HRESULT GetAssemblyReferences(
2357 [in, string] const WCHAR * wszAssemblyPath,
2358 [in] ICorProfilerAssemblyReferenceProvider * pAsmRefProvider);
2364 uuid(F76A2DBA-1D52-4539-866C-2AA518F9EFC3),
2365 pointer_default(unique),
2368 interface ICorProfilerCallback7 : ICorProfilerCallback6
2370 // This event is triggered whenever the symbol stream associated with an
2371 // in-memory module is updated. Even when symbols are provided up-front in
2372 // a call to the managed API Assembly.Load(byte[], byte[], ...) the runtime
2373 // may not actually associate the symbolic data with the module until after
2374 // the ModuleLoadFinished callback has occured. This event provides a later
2375 // opportunity to collect symbols for such modules.
2377 // This event is controlled by the COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED
2380 // Note: This event is not currently raised for symbols implicitly created or
2381 // modified via Reflection.Emit APIs.
2382 HRESULT ModuleInMemorySymbolsUpdated(ModuleID moduleId);
2388 uuid(5BED9B15-C079-4D47-BFE2-215A140C07E0),
2389 pointer_default(unique),
2392 interface ICorProfilerCallback8 : ICorProfilerCallback7
2394 // This event is triggered whenever a dynamic method is jit compiled.
2395 // These include various IL Stubs and LCG Methods.
2396 // The goal is to provide profiler writers with enough information to identify
2397 // it to users as beyond unknown code addresses.
2398 // Note: FunctionID's provided here cannot be used to resolve to their metadata
2399 // tokens since dynamic methods have no metadata.
2401 // Documentation Note: pILHeader is only valid during the callback
2403 HRESULT DynamicMethodJITCompilationStarted(
2404 [in] FunctionID functionId,
2405 [in] BOOL fIsSafeToBlock,
2406 [in] LPCBYTE pILHeader,
2407 [in] ULONG cbILHeader);
2409 HRESULT DynamicMethodJITCompilationFinished(
2410 [in] FunctionID functionId,
2411 [in] HRESULT hrStatus,
2412 [in] BOOL fIsSafeToBlock);
2417 uuid(27583EC3-C8F5-482F-8052-194B8CE4705A),
2418 pointer_default(unique),
2421 interface ICorProfilerCallback9 : ICorProfilerCallback8
2423 // This event is triggered whenever a dynamic method is garbage collected
2424 // and subsequently unloaded.
2426 HRESULT DynamicMethodUnloaded([in] FunctionID functionId);
2431 * COR_PRF_CODEGEN_FLAGS controls various flags and hooks for a specific
2432 * method. A combination of COR_PRF_CODEGEN_FLAGS is provided by the
2433 * profiler in its call to ICorProfilerFunctionControl::SetCodegenFlags()
2434 * when rejitting a method.
2438 COR_PRF_CODEGEN_DISABLE_INLINING = 0x0001,
2439 COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS = 0x0002,
2440 } COR_PRF_CODEGEN_FLAGS;
2444 * The CLR implements the ICorProfilerInfo interface. This interface is
2445 * used by a code profiler to communicate with the CLR to control event
2446 * monitoring and request information. The CLR passes an
2447 * ICorProfilerInfo interface to each code profiler during initialization.
2449 * A code profiler can call methods on the ICorProfilerInfo interface to get
2450 * information about managed code being executed under the control of the CLR
2452 * The ICorProfilerInfo interface implemented by the CLR uses the free
2455 * The methods implemented on this interface return S_OK on success, or E_FAIL
2462 uuid(28B5557D-3F3F-48b4-90B2-5F9EEA2F6C48),
2463 pointer_default(unique),
2466 interface ICorProfilerInfo : IUnknown
2469 * The code profiler calls GetClassFromObject to obtain the ClassID of an
2470 * object given its ObjectID.
2472 HRESULT GetClassFromObject(
2473 [in] ObjectID objectId,
2474 [out] ClassID *pClassId);
2477 * V2 MIGRATION WARNING - DOES NOT WORK FOR GENERIC TYPES
2479 * This function will be removed in a future release, so
2480 * use GetClassFromTokenAndTypeArgs for all types.
2482 HRESULT GetClassFromToken(
2483 [in] ModuleID moduleId,
2484 [in] mdTypeDef typeDef,
2485 [out] ClassID *pClassId);
2488 * V2 MIGRATION WARNING - WILL NOT WORK WITH .NET FRAMEWORK
2491 * This function will be removed in a future release; use GetCodeInfo2
2494 HRESULT GetCodeInfo(
2495 [in] FunctionID functionId,
2496 [out] LPCBYTE *pStart,
2497 [out] ULONG *pcSize);
2500 * RECOMMENDATION: USE GetEventMask2 INSTEAD. WHILE THIS METHOD CONTINUES TO
2501 * TO WORK, GetEventMask2 PROVIDES MORE FUNCTIONALITY.
2503 * The code profiler calls GetEventMask to obtain the current event
2504 * categories for which it is to receive event notifications from the COM+
2507 HRESULT GetEventMask(
2508 [out] DWORD *pdwEvents);
2511 * The code profiler calls GetFunctionFromIP to map an instruction pointer
2512 * in managed code to a FunctionID.
2514 HRESULT GetFunctionFromIP(
2516 [out] FunctionID *pFunctionId);
2519 * V2 MIGRATION WARNING - WILL NOT WORK FOR GENERIC FUNCTIONS OR
2520 * FUNCTIONS ON GENERIC TYPES
2522 * This function will be removed in a future release, so use
2523 * GetFunctionFromTokenAndTypeArgs for all functions.
2525 HRESULT GetFunctionFromToken(
2526 [in] ModuleID moduleId,
2528 [out] FunctionID *pFunctionId);
2531 * The code profiler calls GetHandleFromThread to map a ThreadID to a Win32
2532 * thread handle. The profiler must call DuplicateHandle on the handle
2535 HRESULT GetHandleFromThread(
2536 [in] ThreadID threadId,
2537 [out] HANDLE *phThread);
2540 * The code profiler calls GetObjectSize to obtain the size of an object.
2541 * Note that types like arrays and strings may have a different size for each object.
2543 * THIS API IS OBSOLETE. It does not work for objects >4GB on 64-bit platforms.
2544 * Use ICorProfilerInfo4::GetObjectSize2 instead.
2546 HRESULT GetObjectSize(
2547 [in] ObjectID objectId,
2548 [out] ULONG *pcSize);
2551 * This will return S_OK if the ClassID provided is an array class, and will
2552 * fill out the information for any non-null out params. S_FALSE will be
2553 * returned if the ClassID is not an array.
2555 * classId : the ClassID to return information about
2556 * pBaseElemType : the array's base element type
2557 * pBaseClassId : the base ClassID if the element type == ELEMENT_TYPE_CLASS
2558 * pcRank : the number of dimensions of the array
2560 HRESULT IsArrayClass(
2561 [in] ClassID classId,
2562 [out] CorElementType *pBaseElemType,
2563 [out] ClassID *pBaseClassId,
2564 [out] ULONG *pcRank);
2567 * The code profiler calls GetThreadInfo to obtain the current Win32 thread ID for
2568 * the specified thread.
2570 HRESULT GetThreadInfo(
2571 [in] ThreadID threadId,
2572 [out] DWORD *pdwWin32ThreadId);
2575 * The code profiler calls GetCurrentThreadID to get the managed thread ID
2576 * for the current thread.
2578 * NOTE: GetCurrentThreadID may return CORPROF_E_NOT_MANAGED_THREAD if the
2579 * current thread is an internal runtime thread, and the returned value of
2580 * pThreadId will be NULL.
2582 HRESULT GetCurrentThreadID(
2583 [out] ThreadID *pThreadId);
2586 * V2 MIGRATION NOTE - More information is available for generic types
2587 * from GetClassIDInfo2.
2589 * Returns the parent module a class is defined in, along with the
2590 * metadata token for the class. One can call GetModuleMetaData
2591 * to obtain the metadata interface for a given module. The token
2592 * can then be used to access the metadata for this class.
2594 HRESULT GetClassIDInfo(
2595 [in] ClassID classId,
2596 [out] ModuleID *pModuleId,
2597 [out] mdTypeDef *pTypeDefToken);
2600 * Return the parent class for a given function. Also return the metadata
2601 * token which can be used to read the metadata.
2603 * V2 MIGRATION WARNING - LESS INFORMATION FOR GENERIC CLASSES
2604 * The ClassID of a function on a generic class may not be obtainable without
2605 * more context about the use of the function. In this case, *pClassId will be 0;
2606 * try using GetFunctionInfo2 with a COR_PRF_FRAME_INFO to give more context.
2608 HRESULT GetFunctionInfo(
2609 [in] FunctionID functionId,
2610 [out] ClassID *pClassId,
2611 [out] ModuleID *pModuleId,
2612 [out] mdToken *pToken);
2615 * RECOMMENDATION: USE SetEventMask2 INSTEAD. WHILE THIS METHOD CONTINUES TO
2616 * TO WORK, SetEventMask2 PROVIDES MORE FUNCTIONALITY.
2618 * The code profiler calls SetEventMask to set the event categories for
2619 * which it is set to receive notification from the CLR.
2621 HRESULT SetEventMask(
2622 [in] DWORD dwEvents);
2625 * The code profiler calls SetFunctionHooks to specify handlers
2626 * for FunctionEnter, FunctionLeave, and FunctionTailcall.
2628 * Note that only one set of callbacks may be active at a time. Thus,
2629 * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
2630 * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
2631 * wins. SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
2632 * when both are set.
2634 * Each function pointer may be null to disable that callback.
2636 * SetEnterLeaveFunctionHooks may only be called from the
2637 * profiler's Initialize() callback.
2639 HRESULT SetEnterLeaveFunctionHooks(
2640 [in] FunctionEnter *pFuncEnter,
2641 [in] FunctionLeave *pFuncLeave,
2642 [in] FunctionTailcall *pFuncTailcall);
2645 * This is used for mapping FunctionIDs to alternative values that will be
2646 * passed to the callbacks
2648 HRESULT SetFunctionIDMapper(
2649 [in] FunctionIDMapper *pFunc);
2652 * For a given function, retrieve the token value and an instance of the
2653 * meta data interface which can be used against this token.
2655 HRESULT GetTokenAndMetaDataFromFunction(
2656 [in] FunctionID functionId,
2658 [out] IUnknown **ppImport,
2659 [out] mdToken *pToken);
2662 * Retrieve information about a given module.
2664 * When the module is loaded from disk, the name returned will be the filename;
2665 * otherwise, the name will be the name from the metadata Module table (i.e.,
2666 * the same as the managed System.Reflection.Module.ScopeName).
2668 * NOTE: While this function may be called as soon as the moduleId is alive,
2669 * the AssemblyID of the containing assembly will not be available until the
2670 * ModuleAttachedToAssembly callback.
2672 * NOTE: More information is available by using ICorProfilerInfo3::GetModuleInfo2 instead.
2674 HRESULT GetModuleInfo(
2675 [in] ModuleID moduleId,
2676 [out] LPCBYTE *ppBaseLoadAddress,
2678 [out] ULONG *pcchName,
2679 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
2681 [out] AssemblyID *pAssemblyId);
2684 * Get a metadata interface instance which maps to the given module.
2685 * One may ask for the metadata to be opened in read+write mode, but
2686 * this will result in slower metadata execution of the program, because
2687 * changes made to the metadata cannot be optimized as they were from
2690 * NOTE: Some modules (such as resource modules) have no metadata. In
2691 * those cases, GetModuleMetaData will return S_FALSE, and a NULL
2694 * NOTE: the only values valid for dwOpenFlags are ofRead and ofWrite.
2696 HRESULT GetModuleMetaData(
2697 [in] ModuleID moduleId,
2698 [in] DWORD dwOpenFlags,
2700 [out] IUnknown **ppOut);
2703 * Retrieve a pointer to the body of a method starting at it's header.
2704 * A method is scoped by the module it lives in. Because this function
2705 * is designed to give a tool access to IL before it has been loaded
2706 * by the Runtime, it uses the metadata token of the method to find
2707 * the instance desired.
2709 * GetILFunctionBody can return CORPROF_E_FUNCTION_NOT_IL if the methodId
2710 * points to a method without any IL (such as an abstract method, or a
2713 HRESULT GetILFunctionBody(
2714 [in] ModuleID moduleId,
2715 [in] mdMethodDef methodId,
2716 [out] LPCBYTE *ppMethodHeader,
2717 [out] ULONG *pcbMethodSize);
2720 * IL method bodies must be located as RVA's to the loaded module, which
2721 * means they come after the module within 4 gb. In order to make it
2722 * easier for a tool to swap out the body of a method, this allocator
2723 * will ensure memory is allocated within that range.
2725 HRESULT GetILFunctionBodyAllocator(
2726 [in] ModuleID moduleId,
2727 [out] IMethodMalloc **ppMalloc);
2730 * Replaces the method body for a function in a module. This will replace
2731 * the RVA of the method in the metadata to point to this new method body,
2732 * and adjust any internal data structures as required. This function can
2733 * only be called on those methods which have never been compiled by a JITTER.
2734 * Please use the GetILFunctionAllocator to allocate space for the new method to
2735 * ensure the buffer is compatible.
2737 HRESULT SetILFunctionBody(
2738 [in] ModuleID moduleId,
2739 [in] mdMethodDef methodid,
2740 [in] LPCBYTE pbNewILMethodHeader);
2743 * Retrieve app domain information given its id.
2745 HRESULT GetAppDomainInfo(
2746 [in] AppDomainID appDomainId,
2748 [out] ULONG *pcchName,
2749 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
2751 [out] ProcessID *pProcessId);
2754 * Retrieve information about an assembly given its ID.
2756 HRESULT GetAssemblyInfo(
2757 [in] AssemblyID assemblyId,
2759 [out] ULONG *pcchName,
2760 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
2762 [out] AppDomainID *pAppDomainId,
2763 [out] ModuleID *pModuleId);
2767 * V2 MIGRATION WARNING: DEPRECATED. Returns E_NOTIMPL always.
2769 * See ICorProfilerInfo4::RequestReJIT instead
2772 HRESULT SetFunctionReJIT(
2773 [in] FunctionID functionId);
2776 * ForceGC forces a GC to occur within the runtime.
2778 * NOTE: This method needs to be called from a thread that does not have any
2779 * profiler callbacks on its stack. The most convenient way to implement this is
2780 * to create a separate thread within the profiler and have it call ForceGC when
2787 * V2 MIGRATION NOTE - Calling SetILInstrumentedCodeMap on any one
2788 * of the multiple FunctionIDs that represent a generic function in a given
2789 * AppDomain will affect all instantiations of that function in the AppDomain.
2791 * fStartJit should be set to true the first time this function is called for
2792 * a given FunctionID, and false thereafter.
2794 * The format of the map is as follows:
2795 * The debugger will assume that each oldOffset refers to an IL offset
2796 * within the original, unmodified IL code. newOffset refers to the corresponding
2797 * IL offset within the new, instrumented code.
2799 * The map should be sorted in increasing order. For stepping to work properly:
2800 * - Instrumented IL should not be reordered (so both old & new are sorted)
2801 * - original IL should not be removed
2802 * - the map should include entries to map all of the sequence points from the pdb.
2804 * The map does not interpolate missing entries. So given the following map:
2808 * - An old offset of 0,1,2,3,4 will be mapped to a new offset of 0
2809 * - An old offset of 5,6,7, or 8 will be mapped to new offset 10.
2810 * - An old offset of 9 or higher will be mapped to new offset 20.
2811 * - A new offset of 0, 1,...8,9 will be mapped to old offset 0
2812 * - A new offset of 10,11,...18,19 will be mapped to old offset 5.
2813 * - A new offset of 20 or higher will be mapped to old offset 9.
2816 HRESULT SetILInstrumentedCodeMap(
2817 [in] FunctionID functionId,
2818 [in] BOOL fStartJit,
2819 [in] ULONG cILMapEntries,
2820 [in, size_is(cILMapEntries)] COR_IL_MAP rgILMapEntries[] );
2825 HRESULT GetInprocInspectionInterface(
2826 [out] IUnknown **ppicd);
2831 HRESULT GetInprocInspectionIThisThread(
2832 [out] IUnknown **ppicd);
2835 * This will return the ContextID currently associated with the calling
2836 * runtime thread. This will set pContextId to NULL if the calling thread
2837 * is not a runtime thread.
2839 HRESULT GetThreadContext(
2840 [in] ThreadID threadId,
2841 [out] ContextID *pContextId);
2846 HRESULT BeginInprocDebugging(
2847 [in] BOOL fThisThreadOnly,
2848 [out] DWORD *pdwProfilerContext);
2853 HRESULT EndInprocDebugging(
2854 [in] DWORD dwProfilerContext);
2857 * GetILToNativeMapping returns a map from IL offsets to native
2858 * offsets for this code. An array of COR_PROF_IL_TO_NATIVE_MAP
2859 * structs will be returned, and some of the ilOffsets in this array
2860 * may be the values specified in CorDebugIlToNativeMappingTypes.
2862 HRESULT GetILToNativeMapping(
2863 [in] FunctionID functionId,
2865 [out] ULONG32 *pcMap,
2866 [out, size_is(cMap), length_is(*pcMap)]
2867 COR_DEBUG_IL_TO_NATIVE_MAP map[]);
2871 * The CLR implements the ICorProfilerInfo2 interface. This interface is
2872 * used by a code profiler to communicate with the CLR to control event
2873 * monitoring and request information. The CLR passes an
2874 * ICorProfilerInfo2 interface to each code profiler during initialization.
2876 * A code profiler can call methods on the ICorProfilerInfo2 interface to get
2877 * information about managed code being executed under the control of the CLR
2879 * The ICorProfilerInfo2 interface implemented by the CLR uses the free
2882 * The methods implemented on this interface return S_OK on success, or E_FAIL
2889 uuid(CC0935CD-A518-487d-B0BB-A93214E65478),
2890 pointer_default(unique),
2893 interface ICorProfilerInfo2 : ICorProfilerInfo
2896 * The code profiler calls DoStackSnapshot to do sparse one-off stack snapshots.
2898 * Passing NULL for thread yields a snapshot of the current thread. If a ThreadID
2899 * of a different thread is passed, the runtime will suspend that thread, perform
2900 * the snapshot, and resume.
2902 * infoFlags come from the COR_PRF_SNAPSHOT_INFO enum.
2904 * context is a platform-dependent CONTEXT structure, representing the complete
2905 * register context that the profiling API will use to seed the stack walk. If this
2906 * is non-NULL, it must point to JITd or NGENd code, or else DoStackSnapshot
2907 * will return CORPROF_E_STACKSNAPSHOT_UNMANAGED_CTX. Contexts are
2908 * only provided by profilers that hijack threads to force them to walk their
2909 * own stacks; profilers should not attempt to provide a context when walking
2910 * another thread's stack. If context is NULL, the stack walk will begin at the
2911 * last available managed frame for the target thread.
2913 * See the definition of StackSnapshotCallback for more information.
2915 HRESULT DoStackSnapshot(
2916 [in] ThreadID thread,
2917 [in] StackSnapshotCallback *callback,
2918 [in] ULONG32 infoFlags,
2919 [in] void *clientData,
2920 [in, size_is(contextSize)] BYTE context[],
2921 [in] ULONG32 contextSize);
2924 * The code profiler calls SetFunctionHooks2 to specify handlers
2925 * for FunctionEnter2, FunctionLeave2, and FunctionTailcall2
2928 * Note that only one set of callbacks may be active at a time. Thus,
2929 * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
2930 * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
2931 * wins. SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
2932 * when both are set.
2934 * Each pointer may be null to disable that particular callback.
2936 * SetEnterLeaveFunctionHooks2 may only be called from the
2937 * profiler's Initialize() callback.
2939 HRESULT SetEnterLeaveFunctionHooks2(
2940 [in] FunctionEnter2 *pFuncEnter,
2941 [in] FunctionLeave2 *pFuncLeave,
2942 [in] FunctionTailcall2 *pFuncTailcall);
2945 * GetFunctionInfo2 returns the parent class of a function, plus the
2946 * function's metadata token and the ClassIDs of its type arguments
2949 * When a COR_PRF_FRAME_INFO obtained from a FunctionEnter2
2950 * callback is passed, the ClassID and all type arguments will be exact.
2952 * When a COR_PRF_FRAME_INFO from any other source is passed, or
2953 * when 0 is passed as the frameInfo argument, exact ClassID and type
2954 * arguments cannot always be determined. The value returned in pClassId
2955 * may be NULL and some type args will come back as System.Object.
2958 HRESULT GetFunctionInfo2(
2959 [in] FunctionID funcId,
2960 [in] COR_PRF_FRAME_INFO frameInfo,
2961 [out] ClassID *pClassId,
2962 [out] ModuleID *pModuleId,
2963 [out] mdToken *pToken,
2964 [in] ULONG32 cTypeArgs,
2965 [out] ULONG32 *pcTypeArgs,
2966 [out] ClassID typeArgs[]);
2969 * GetStringLayout returns detailed information about how string objects are stored.
2971 * *pBufferLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
2972 * stores the length of the string's buffer
2974 * *pStringLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
2975 * stores the length of the string itself
2977 * *pBufferOffset is the offset (from the ObjectID pointer) to the actual buffer
2978 * of wide characters
2980 * Strings may or may not be null-terminated.
2982 HRESULT GetStringLayout(
2983 [out] ULONG *pBufferLengthOffset,
2984 [out] ULONG *pStringLengthOffset,
2985 [out] ULONG *pBufferOffset);
2988 * GetClassLayout returns detailed information how a specific class is stored.
2989 * It only returns the fields defined by the class itself; if the parent class
2990 * defined fields as well, the profiler must call GetClassLayout on the parent class
2991 * to obtain those fields.
2993 * It will fail with E_INVALIDARG for string and array classes.
2995 HRESULT GetClassLayout(
2996 [in] ClassID classID,
2997 [in, out] COR_FIELD_OFFSET rFieldOffset[],
2998 [in] ULONG cFieldOffset,
2999 [out] ULONG *pcFieldOffset,
3000 [out] ULONG *pulClassSize);
3003 * Returns the parent module a class is defined in, along with the
3004 * metadata token for the class, the ClassID of its parent class, and the
3005 * ClassIDs of its type arguments (if any).
3007 * One can call GetModuleMetaData to obtain the metadata interface for
3008 * a given module. The token can then be used to access the metadata for this
3011 HRESULT GetClassIDInfo2(
3012 [in] ClassID classId,
3013 [out] ModuleID *pModuleId,
3014 [out] mdTypeDef *pTypeDefToken,
3015 [out] ClassID *pParentClassId,
3016 [in] ULONG32 cNumTypeArgs,
3017 [out] ULONG32 *pcNumTypeArgs,
3018 [out] ClassID typeArgs[]);
3021 * GetCodeInfo2 returns the extents of native code associated with the
3022 * given FunctionID. These extents are returned sorted in order of increasing
3025 HRESULT GetCodeInfo2(
3026 [in] FunctionID functionID,
3027 [in] ULONG32 cCodeInfos,
3028 [out] ULONG32 *pcCodeInfos,
3029 [out, size_is(cCodeInfos), length_is(*pcCodeInfos)]
3030 COR_PRF_CODE_INFO codeInfos[]);
3033 * GetClassFromTokenAndTypeArgs returns the ClassID of a type given its metadata
3034 * token (typedef) and the ClassIDs of its type arguments (if any).
3036 * cTypeArgs must be equal to the number of type parameters for the given type
3037 * (0 for non-generic types)
3038 * typeArgs may be NULL if cTypeArgs == 0
3040 * Calling this function with a TypeRef token can have unpredictable results; callers
3041 * should resolve the TypeRef to a TypeDef and use that.
3043 * If the type is not already loaded, calling this function will cause it to be.
3044 * Loading is a dangerous operation in many contexts. For example, calling
3045 * this function during loading of modules or other types could lead to an infinite
3046 * loop as the runtime attempts to circularly load things.
3048 * In general, use of this function is discouraged. If profilers are interested in
3049 * events for a particular type, they should store the ModuleID and TypeDef of that type,
3050 * and use GetClassIDInfo2 to check whether a given ClassID is the desired type.
3052 HRESULT GetClassFromTokenAndTypeArgs(
3053 [in] ModuleID moduleID,
3054 [in] mdTypeDef typeDef,
3055 [in] ULONG32 cTypeArgs,
3056 [in, size_is(cTypeArgs)] ClassID typeArgs[],
3057 [out] ClassID* pClassID);
3060 * GetFunctionFromTokenAndTypeArgs returns the FunctionID of a function given
3061 * its metadata token (methoddef), containing class, and type args (if any).
3063 * classID may be 0 if the containing class is not generic
3064 * typeArgs may be NULL if cTypeArgs == 0
3066 * Calling this function with a MethodRef token can have unpredictable results; callers
3067 * should resolve the MethodRef to a MethodDef and use that.
3069 * If the function is not already loaded, calling this function will cause it to be.
3070 * Loading is a dangerous operation in many contexts. For example, calling
3071 * this function during loading of modules or types could lead to an infinite
3072 * loop as the runtime attempts to circularly load things.
3074 * In general, use of this function is discouraged. If profilers are interested in
3075 * events for a particular function, they should store the ModuleID and MethodDef of that function,
3076 * and use GetFunctionInfo2 to check whether a given FunctionID is the desired function.
3078 HRESULT GetFunctionFromTokenAndTypeArgs(
3079 [in] ModuleID moduleID,
3080 [in] mdMethodDef funcDef,
3081 [in] ClassID classId,
3082 [in] ULONG32 cTypeArgs,
3083 [in, size_is(cTypeArgs)] ClassID typeArgs[],
3084 [out] FunctionID* pFunctionID);
3087 * Returns an enumerator over all frozen objects in the given module.
3089 HRESULT EnumModuleFrozenObjects(
3090 [in] ModuleID moduleID,
3091 [out] ICorProfilerObjectEnum** ppEnum);
3096 * GetArrayObjectInfo returns detailed information about an array object.
3097 * objectId is a valid array object.
3098 * cDimensions is the rank (# of dimensions).
3100 * pDimensionSizes, pDimensionLowerBounds are parallel arrays describing the size and lower bound for each dimension.
3101 * (*ppData) is a pointer to the raw buffer for the array, which is laid out according to the C++
3104 HRESULT GetArrayObjectInfo(
3105 [in] ObjectID objectId,
3106 [in] ULONG32 cDimensions,
3107 [out, size_is(cDimensions)] ULONG32 pDimensionSizes[],
3108 [out, size_is(cDimensions)] int pDimensionLowerBounds[],
3109 [out] BYTE **ppData);
3112 * GetBoxClassLayout returns information about how a particular value type is laid out
3115 * *pBufferOffset is the offset (from the ObjectID pointer) to where the value type
3116 * is stored within the box. The value type's class layout may then be used to
3119 HRESULT GetBoxClassLayout(
3120 [in] ClassID classId,
3121 [out] ULONG32 *pBufferOffset);
3125 * GetThreadAppDomain returns the AppDomainID currently associated with\
3126 * the given ThreadID
3128 HRESULT GetThreadAppDomain(
3129 [in] ThreadID threadId,
3130 [out] AppDomainID *pAppDomainId);
3134 * GetRVAStaticAddress gets the address of the home for the given
3135 * RVA static. It must be called from a managed thread. Otherwise,
3136 * it will return CORPROF_E_NOT_MANAGED_THREAD.
3138 HRESULT GetRVAStaticAddress(
3139 [in] ClassID classId,
3140 [in] mdFieldDef fieldToken,
3141 [out] void **ppAddress);
3144 * GetAppDomainStaticAddress gets the address of the home for the given
3145 * AppDomain static in the given AppDomain.
3147 * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3148 * has not been assigned a home in the given AppDomain.
3150 HRESULT GetAppDomainStaticAddress(
3151 [in] ClassID classId,
3152 [in] mdFieldDef fieldToken,
3153 [in] AppDomainID appDomainId,
3154 [out] void **ppAddress);
3157 * GetThreadStaticAddress gets the address of the home for the given
3158 * Thread static in the given Thread. threadId must be the current thread
3159 * ID or NULL, which means using curernt thread ID.
3161 * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3162 * has not been assigned a home in the given Thread.
3164 HRESULT GetThreadStaticAddress(
3165 [in] ClassID classId,
3166 [in] mdFieldDef fieldToken,
3167 [in] ThreadID threadId,
3168 [out] void **ppAddress);
3171 * GetContextStaticAddress gets the address of the home for the given
3172 * Context static in the given context. It must be called from a managed
3173 * thread. Otherwise, it will return CORPROF_E_NOT_MANAGED_THREAD.
3175 * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3176 * has not been assigned a home in the given Context.
3178 HRESULT GetContextStaticAddress(
3179 [in] ClassID classId,
3180 [in] mdFieldDef fieldToken,
3181 [in] ContextID contextId,
3182 [out] void **ppAddress);
3185 * GetStaticFieldInfo gets COR_PRF_STATIC_TYPE for a specific
3186 * field in a class. This information can be used to decide which
3187 * function to call to get the address of the static.
3189 * NOTE: One should still check the metadata for a static to ensure
3190 * it is actually going to have an address. Statics that are literals
3191 * (aka constants) exist only in the metadata and do not have an address.
3194 HRESULT GetStaticFieldInfo(
3195 [in] ClassID classId,
3196 [in] mdFieldDef fieldToken,
3197 [out] COR_PRF_STATIC_TYPE *pFieldInfo);
3200 * GetGenerationBounds returns the memory regions that make up a given
3201 * GC generation in memory. It may be called from any profiler callback as long
3202 * as a GC is not in progress. (To be exact, it may be called from any callback
3203 * except for those that occur between GarbageCollectionStarted and GarbageCollectionFinished.)
3205 * Most shifting of generations takes place during garbage collections; between
3206 * collections generations may grow, but generally do not move around. Therefore
3207 * the most interesting places to call this function are in GarbageCollectionStarted
3210 * During program startup, some objects are allocated by the CLR itself, generally
3211 * in generations 3 and 0. So by the time managed code starts executing, these
3212 * generations will already contain objects. Generations 1 and 2 will be normally
3213 * empty, except for dummy objects generated by the garbage collector (of size 12
3214 * bytes in 32-bit implementations of the CLR, larger in 64-bit implementaions).
3215 * You may also see generation 2 ranges that are inside modules generated by ngen.
3216 * These are "frozen objects" generated at ngen time rather than allocated by the
3217 * garbage collector.
3219 * cObjectRanges is a count of the number of elements allocated by the caller for
3221 * pcObjectRanges is an out param for the number of ranges in the given generation
3222 * ranges is an array of elements of type COR_PRF_GC_GENERATION_RANGE, each of which
3223 * describes a range of memory used by the garbage collector
3226 HRESULT GetGenerationBounds(
3227 [in] ULONG cObjectRanges,
3228 [out] ULONG *pcObjectRanges,
3229 [out, size_is(cObjectRanges), length_is(*pcObjectRanges)] COR_PRF_GC_GENERATION_RANGE ranges[]);
3232 * GetObjectGeneration returns which generation the given object is currently in, along
3233 * with the start and length of the segment containing the object. It may be called
3234 * at any time as long as a GC is not in progress.
3237 HRESULT GetObjectGeneration(
3238 [in] ObjectID objectId,
3239 [out] COR_PRF_GC_GENERATION_RANGE *range);
3243 * When an exception notification is received, GetNotifiedExceptionClauseInfo() may be used
3244 * to get the native address and frame information for the exception clause (catch/finally/filter)
3245 * that is about to be run (ExceptionCatchEnter, ExceptionUnwindFinallyEnter, ExceptionFilterEnter)
3246 * or has just been run (ExceptionCatchLeave, ExceptionUnwindFinallyLeave, ExceptionFilterLeave).
3248 * This call may be made at any time after one of the Enter calls above until either the matching
3249 * Leave call is received or until a nested exception throws out of the current clause in which case
3250 * there will be no Leave notification for that clause. Note it is not possible for a throw to escape
3251 * a Filter so there is always a Leave in that case.
3254 * S_OK indicates success
3255 * S_FALSE indicates that no exception clause is active
3256 * CORPROF_E_NOT_MANAGED_THREAD indicates an unmanaged thread.
3259 HRESULT GetNotifiedExceptionClauseInfo(
3260 [out] COR_PRF_EX_CLAUSE_INFO *pinfo);
3264 * The CLR implements the ICorProfilerInfo3 interface. This interface is
3265 * used by a code profiler to communicate with the CLR to control event
3266 * monitoring and request information. The CLR passes an
3267 * ICorProfilerInfo3 interface to each code profiler during initialization.
3269 * A code profiler can call methods on the ICorProfilerInfo3 interface to get
3270 * information about managed code being executed under the control of the CLR
3272 * The ICorProfilerInfo3 interface implemented by the CLR uses the free
3275 * The methods implemented on this interface return S_OK on success, or E_FAIL
3282 uuid(B555ED4F-452A-4E54-8B39-B5360BAD32A0),
3283 pointer_default(unique),
3286 interface ICorProfilerInfo3 : ICorProfilerInfo2
3289 * Returns an enumerator for all previously jitted functions. May overlap with
3290 * functions previously reported via CompilationStarted callbacks.
3291 * NOTE: The returned enumeration will only include '0' for the value of the
3292 * COR_PRF_FUNCTION::reJitId field. If you require valid COR_PRF_FUNCTION::reJitId values, use
3293 * ICorProfilerInfo4::EnumJITedFunctions2.
3295 HRESULT EnumJITedFunctions([out] ICorProfilerFunctionEnum** ppEnum);
3297 HRESULT RequestProfilerDetach([in] DWORD dwExpectedCompletionMilliseconds);
3299 HRESULT SetFunctionIDMapper2(
3300 [in] FunctionIDMapper2 *pFunc,
3301 [in] void *clientData);
3304 * GetStringLayout2 returns detailed information about how string objects are stored.
3306 * *pStringLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
3307 * stores the length of the string itself
3309 * *pBufferOffset is the offset (from the ObjectID pointer) to the actual buffer
3310 * of wide characters
3312 * Strings may or may not be null-terminated.
3314 HRESULT GetStringLayout2(
3315 [out] ULONG *pStringLengthOffset,
3316 [out] ULONG *pBufferOffset);
3319 * The code profiler calls SetFunctionHooks3 to specify handlers
3320 * for FunctionEnter3, FunctionLeave3, and FunctionTailcall3, and calls
3321 * SetFunctionHooks3WithInfo to specify handlers for FunctionEnter3WithInfo,
3322 * FunctionLeave3WithInfo, and FunctionTailcall3WithInfo.
3324 * Note that only one set of callbacks may be active at a time. Thus,
3325 * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
3326 * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
3327 * wins. SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
3328 * when both are set.
3330 * Each function pointer may be null to disable that callback.
3332 * SetEnterLeaveFunctionHooks3(WithInfo) may only be called from the
3333 * profiler's Initialize() callback.
3335 HRESULT SetEnterLeaveFunctionHooks3(
3336 [in] FunctionEnter3 *pFuncEnter3,
3337 [in] FunctionLeave3 *pFuncLeave3,
3338 [in] FunctionTailcall3 *pFuncTailcall3);
3341 HRESULT SetEnterLeaveFunctionHooks3WithInfo(
3342 [in] FunctionEnter3WithInfo *pFuncEnter3WithInfo,
3343 [in] FunctionLeave3WithInfo *pFuncLeave3WithInfo,
3344 [in] FunctionTailcall3WithInfo *pFuncTailcall3WithInfo);
3347 * The profiler can call GetFunctionEnter3Info to gather frame info and argument info
3348 * in FunctionEnter3WithInfo callback. The profiler needs to allocate sufficient space
3349 * for COR_PRF_FUNCTION_ARGUMENT_INFO of the function it's inspecting and indicate the
3350 * size in a ULONG pointed by pcbArgumentInfo.
3352 HRESULT GetFunctionEnter3Info(
3353 [in] FunctionID functionId,
3354 [in] COR_PRF_ELT_INFO eltInfo,
3355 [out] COR_PRF_FRAME_INFO *pFrameInfo,
3356 [in, out] ULONG *pcbArgumentInfo,
3357 [out, size_is(*pcbArgumentInfo)] COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo);
3360 * The profiler can call GetFunctionLeave3Info to gather frame info and return value
3361 * in FunctionLeave3WithInfo callback.
3363 HRESULT GetFunctionLeave3Info(
3364 [in] FunctionID functionId,
3365 [in] COR_PRF_ELT_INFO eltInfo,
3366 [out] COR_PRF_FRAME_INFO *pFrameInfo,
3367 [out] COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange);
3370 * The profiler can call GetFunctionTailcall3Info to gather frame info in
3371 * FunctionTailcall3WithInfo callback.
3373 HRESULT GetFunctionTailcall3Info(
3374 [in] FunctionID functionId,
3375 [in] COR_PRF_ELT_INFO eltInfo,
3376 [out] COR_PRF_FRAME_INFO *pFrameInfo);
3378 HRESULT EnumModules([out] ICorProfilerModuleEnum** ppEnum);
3381 * The profiler can call GetRuntimeInformation to query CLR version information.
3382 * Passing NULL to any parameter is acceptable except pcchVersionString cannot
3383 * be NULL if szVersionString is not NULL.
3385 HRESULT GetRuntimeInformation([out] USHORT *pClrInstanceId,
3386 [out] COR_PRF_RUNTIME_TYPE *pRuntimeType,
3387 [out] USHORT *pMajorVersion,
3388 [out] USHORT *pMinorVersion,
3389 [out] USHORT *pBuildNumber,
3390 [out] USHORT *pQFEVersion,
3391 [in] ULONG cchVersionString,
3392 [out] ULONG *pcchVersionString,
3393 [out, annotation("_Out_writes_to_(cchVersionString, *pcchVersionString)")]
3394 WCHAR szVersionString[]);
3397 * GetThreadStaticAddress2 gets the address of the home for the given
3398 * Thread static in the given Thread.
3400 * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3401 * has not been assigned a home in the given Thread.
3403 HRESULT GetThreadStaticAddress2(
3404 [in] ClassID classId,
3405 [in] mdFieldDef fieldToken,
3406 [in] AppDomainID appDomainId,
3407 [in] ThreadID threadId,
3408 [out] void **ppAddress);
3411 * GetAppDomainsContainingModule returns the AppDomainIDs in which the
3412 * given module has been loaded
3414 HRESULT GetAppDomainsContainingModule(
3415 [in] ModuleID moduleId,
3416 [in] ULONG32 cAppDomainIds,
3417 [out] ULONG32 *pcAppDomainIds,
3418 [out, size_is(cAppDomainIds), length_is(*pcAppDomainIds)] AppDomainID appDomainIds[]);
3422 * Retrieve information about a given module.
3424 * When the module is loaded from disk, the name returned will be the filename;
3425 * otherwise, the name will be the name from the metadata Module table (i.e.,
3426 * the same as the managed System.Reflection.Module.ScopeName).
3428 * *pdwModuleFlags will be filled in with a bitmask of values from COR_PRF_MODULE_FLAGS
3429 * that specify some properties of the module.
3431 * NOTE: While this function may be called as soon as the moduleId is alive,
3432 * the AssemblyID of the containing assembly will not be available until the
3433 * ModuleAttachedToAssembly callback.
3436 HRESULT GetModuleInfo2(
3437 [in] ModuleID moduleId,
3438 [out] LPCBYTE *ppBaseLoadAddress,
3440 [out] ULONG *pcchName,
3441 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
3443 [out] AssemblyID *pAssemblyId,
3444 [out] DWORD *pdwModuleFlags);
3451 * This interface lets you iterate over the frozen objects from ngen images.
3456 uuid(2C6269BD-2D13-4321-AE12-6686365FD6AF),
3457 pointer_default(unique),
3460 interface ICorProfilerObjectEnum : IUnknown
3468 [out] ICorProfilerObjectEnum **ppEnum);
3471 [out] ULONG *pcelt);
3475 [out, size_is(celt), length_is(*pceltFetched)] ObjectID objects[],
3476 [out] ULONG *pceltFetched);
3481 * This interface lets you iterate over functions in the runtime.
3486 uuid(FF71301A-B994-429D-A10B-B345A65280EF),
3487 pointer_default(unique),
3490 interface ICorProfilerFunctionEnum : IUnknown
3492 HRESULT Skip([in] ULONG celt);
3496 HRESULT Clone([out] ICorProfilerFunctionEnum **ppEnum);
3498 HRESULT GetCount([out] ULONG *pcelt);
3500 HRESULT Next([in] ULONG celt,
3501 [out, size_is(celt), length_is(*pceltFetched)]
3502 COR_PRF_FUNCTION ids[],
3503 [out] ULONG * pceltFetched);
3507 * This interface lets you iterate over modules in the runtime.
3512 uuid(b0266d75-2081-4493-af7f-028ba34db891),
3513 pointer_default(unique),
3516 interface ICorProfilerModuleEnum : IUnknown
3518 HRESULT Skip([in] ULONG celt);
3522 HRESULT Clone([out] ICorProfilerModuleEnum **ppEnum);
3524 HRESULT GetCount([out] ULONG *pcelt);
3526 HRESULT Next([in] ULONG celt,
3527 [out, size_is(celt), length_is(*pceltFetched)]
3529 [out] ULONG * pceltFetched);
3533 * NOTE: DEPRECATED, now you can use your any allocator.
3535 * This is simple allocator that only allows you to allocate memory.
3536 * You may not free it. This was used in conjunction with
3537 * ICorProfilerInfo::SetILFunctionBody.
3541 uuid(A0EFB28B-6EE2-4d7b-B983-A75EF7BEEDB8),
3542 pointer_default(unique),
3545 interface IMethodMalloc : IUnknown
3548 * Tries to allocate memory above the start address of the module from
3549 * which it was created. It is important to note that this method may
3550 * fail to allocate the memory specified above the start address, and
3551 * may as a result return NULL.
3558 * The CLR implements the ICorProfilerFunctionControl interface. This interface
3559 * is used by a code profiler to communicate with the CLR to control how the
3560 * JIT should generate code when rejitting a specific method.
3562 * The ICorProfilerFunctionControl interface implemented by the CLR uses the
3563 * free threaded model.
3568 uuid(F0963021-E1EA-4732-8581-E01B0BD3C0C6),
3569 pointer_default(unique),
3572 interface ICorProfilerFunctionControl : IUnknown
3575 * Set one or more flags from COR_PRF_CODEGEN_FLAGS to control code
3576 * generation just for this method.
3578 HRESULT SetCodegenFlags(
3582 * Override the method body.
3584 HRESULT SetILFunctionBody(
3585 [in] ULONG cbNewILMethodHeader,
3586 [in, size_is(cbNewILMethodHeader)] LPCBYTE pbNewILMethodHeader);
3589 * This is not currently implemented, and will return E_NOTIMPL
3591 HRESULT SetILInstrumentedCodeMap(
3592 [in] ULONG cILMapEntries,
3593 [in, size_is(cILMapEntries)] COR_IL_MAP rgILMapEntries[]);
3598 * The CLR implements the ICorProfilerInfo4 interface. This interface is
3599 * used by a code profiler to communicate with the CLR to control event
3600 * monitoring and request information. The CLR passes an
3601 * ICorProfilerInfo4 interface to each code profiler during initialization.
3603 * A code profiler can call methods on the ICorProfilerInfo4 interface to get
3604 * information about managed code being executed under the control of the CLR
3606 * The ICorProfilerInfo4 interface implemented by the CLR uses the free
3609 * The methods implemented on this interface return S_OK on success, or E_FAIL
3616 uuid(0d8fdcaa-6257-47bf-b1bf-94dac88466ee),
3617 pointer_default(unique),
3620 interface ICorProfilerInfo4 : ICorProfilerInfo3
3622 HRESULT EnumThreads([out] ICorProfilerThreadEnum **ppEnum);
3623 HRESULT InitializeCurrentThread();
3626 * Call RequestReJIT to have the runtime re-JIT a particular set of methods.
3627 * A code profiler can then adjust the code generated when the method is
3628 * re-JITed through the ICorProfilerFunctionControl interface. This does
3629 * not impact currently executing methods, only future invocations.
3631 * A return code of S_OK indicates that all of the requested methods were
3632 * attempted to be rejitted. However, the profiler must implement
3633 * ICorProfilerCallback4::ReJITError to determine which of the methods were
3634 * successfully re-JITed.
3636 * A failure return value (E_*) indicates some failure that prevents any
3639 HRESULT RequestReJIT(
3640 [in] ULONG cFunctions,
3641 [in, size_is(cFunctions)] ModuleID moduleIds[],
3642 [in, size_is(cFunctions)] mdMethodDef methodIds[]);
3645 * RequestRevert will instruct the runtime to revert to using/calling the
3646 * original method (original IL and flags) rather than whatever was
3647 * ReJITed. This does not change any currently active methods, only future
3651 HRESULT RequestRevert(
3652 [in] ULONG cFunctions,
3653 [in, size_is(cFunctions)] ModuleID moduleIds[],
3654 [in, size_is(cFunctions)] mdMethodDef methodIds[],
3655 [out, size_is(cFunctions)] HRESULT status[]);
3658 * Same as GetCodeInfo2, except instead of always returning the code info
3659 * associated with the original IL/function, you can request the code info
3660 * for a particular re-JITed version of a function.
3662 HRESULT GetCodeInfo3(
3663 [in] FunctionID functionID,
3664 [in] ReJITID reJitId,
3665 [in] ULONG32 cCodeInfos,
3666 [out] ULONG32 * pcCodeInfos,
3667 [out, size_is(cCodeInfos), length_is(*pcCodeInfos)]
3668 COR_PRF_CODE_INFO codeInfos[]);
3671 * Same as GetFunctionFromIP, but also returns which re-JITed version is
3672 * associated with the IP address.
3674 HRESULT GetFunctionFromIP2(
3676 [out] FunctionID * pFunctionId,
3677 [out] ReJITID * pReJitId);
3680 * GetReJITIDs can be used to find all of the re-JITed versions of the
3683 HRESULT GetReJITIDs(
3684 [in] FunctionID functionId,
3685 [in] ULONG cReJitIds,
3686 [out] ULONG * pcReJitIds,
3687 [out, size_is(cReJitIds), length_is(*pcReJitIds)]
3688 ReJITID reJitIds[]);
3691 * Same as GetILToNativeMapping, but allows the code profiler to specify
3692 * which re-JITed version it applies to.
3694 HRESULT GetILToNativeMapping2(
3695 [in] FunctionID functionId,
3696 [in] ReJITID reJitId,
3698 [out] ULONG32 * pcMap,
3699 [out, size_is(cMap),length_is(*pcMap)]
3700 COR_DEBUG_IL_TO_NATIVE_MAP map[]);
3703 * Returns an enumerator for all previously jitted functions. May overlap with
3704 * functions previously reported via CompilationStarted callbacks. The returned
3705 * enumeration will include values for the COR_PRF_FUNCTION::reJitId field
3707 HRESULT EnumJITedFunctions2([out] ICorProfilerFunctionEnum** ppEnum);
3710 * The code profiler calls GetObjectSize to obtain the size of an object.
3711 * Note that types like arrays and strings may have a different size for each object.
3713 HRESULT GetObjectSize2(
3714 [in] ObjectID objectId,
3715 [out] SIZE_T *pcSize);
3721 uuid(07602928-CE38-4B83-81E7-74ADAF781214),
3722 pointer_default(unique),
3725 interface ICorProfilerInfo5 : ICorProfilerInfo4
3728 * The code profiler calls GetEventMask2 to obtain the current event
3729 * categories for which it is to receive event notifications from the CLR
3731 * *pdwEventsLow is a bitwise combination of values from COR_PRF_MONITOR
3732 * *pdwEventsHigh is a bitwise combination of values from COR_PRF_HIGH_MONITOR
3734 HRESULT GetEventMask2(
3735 [out] DWORD *pdwEventsLow,
3736 [out] DWORD *pdwEventsHigh);
3739 * The code profiler calls SetEventMask2 to set the event categories for
3740 * which it is set to receive notification from the CLR.
3742 * dwEventsLow is a bitwise combination of values from COR_PRF_MONITOR
3743 * dwEventsHigh is a bitwise combination of values from COR_PRF_HIGH_MONITOR
3745 HRESULT SetEventMask2(
3746 [in] DWORD dwEventsLow,
3747 [in] DWORD dwEventsHigh);
3753 uuid(F30A070D-BFFB-46A7-B1D8-8781EF7B698A),
3754 pointer_default(unique),
3757 interface ICorProfilerInfo6 : ICorProfilerInfo5
3760 * Returns an enumerator for all methods that
3761 * - belong to a given NGen or R2R module (inlinersModuleId) and
3762 * - inlined a body of a given method (inlineeModuleId / inlineeMethodId).
3764 * If incompleteData is set to TRUE after function is called, it means that the methods enumerator
3765 * doesn't contain all methods inlining a given method.
3766 * It can happen when one or more direct or indirect dependencies of inliners module haven't been loaded yet.
3767 * If profiler needs accurate data it should retry later when more modules are loaded (preferably on each module load).
3769 * It can be used to lift limitation on inlining for ReJIT.
3771 * NOTE: If the inlinee method is decorated with the System.Runtime.Versioning.NonVersionable attribute then
3772 * then some inliners may not ever be reported. If you need to get a full accounting you can avoid the issue
3773 * by disabling the use of all native images.
3776 HRESULT EnumNgenModuleMethodsInliningThisMethod(
3777 [in] ModuleID inlinersModuleId,
3778 [in] ModuleID inlineeModuleId,
3779 [in] mdMethodDef inlineeMethodId,
3780 [out] BOOL *incompleteData,
3781 [out] ICorProfilerMethodEnum** ppEnum);
3786 uuid(9AEECC0D-63E0-4187-8C00-E312F503F663),
3787 pointer_default(unique),
3790 interface ICorProfilerInfo7 : ICorProfilerInfo6
3793 * Applies the newly emitted Metadata.
3795 * This method can be used to apply the newly defined metadata by IMetadataEmit::Define* methods
3798 * If metadata changes are made after ModuleLoadFinished callback,
3799 * it is required to call this method before using the new metadata
3801 HRESULT ApplyMetaData(
3802 [in] ModuleID moduleId);
3804 /* Returns the length of an in-memory symbol stream
3806 * If the module has in-memory symbols the length of the stream will
3807 * be placed in pCountSymbolBytes. If the module doesn't have in-memory
3808 * symbols, *pCountSymbolBytes = 0
3810 * Returns S_OK if the length could be determined (even if it is 0)
3812 * Note: The current implementation does not support reflection.emit.
3813 * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case.
3815 HRESULT GetInMemorySymbolsLength(
3816 [in] ModuleID moduleId,
3817 [out] DWORD* pCountSymbolBytes);
3819 /* Reads bytes from an in-memory symbol stream
3821 * This function attempts to read countSymbolBytes of data starting at offset
3822 * symbolsReadOffset within the in-memory stream. The data will be copied into
3823 * pSymbolBytes which is expected to have countSymbolBytes of space available.
3824 * pCountSymbolsBytesRead contains the actual number of bytes read which
3825 * may be less than countSymbolBytes if the end of the stream is reached.
3827 * Returns S_OK if a non-zero number of bytes were read.
3829 * Note: The current implementation does not support reflection.emit.
3830 * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case.
3832 HRESULT ReadInMemorySymbols(
3833 [in] ModuleID moduleId,
3834 [in] DWORD symbolsReadOffset,
3835 [out] BYTE* pSymbolBytes,
3836 [in] DWORD countSymbolBytes,
3837 [out] DWORD* pCountSymbolBytesRead);
3843 uuid(C5AC80A6-782E-4716-8044-39598C60CFBF),
3844 pointer_default(unique),
3847 interface ICorProfilerInfo8 : ICorProfilerInfo7
3850 * Determines if a function has associated metadata
3852 * Certain methods like IL Stubs or LCG Methods do not have
3853 * associated metadata that can be retrieved using the IMetaDataImport APIs.
3855 * Such methods can be encountered by profilers through instruction pointers
3856 * or by listening to ICorProfilerCallback::DynamicMethodJITCompilationStarted
3858 * This API can be used to determine whether a FunctionID is dynamic.
3860 HRESULT IsFunctionDynamic( [in] FunctionID functionId,
3861 [out] BOOL *isDynamic);
3864 * Maps a managed code instruction pointer to a FunctionID.
3866 * GetFunctionFromIP2 fails for dynamic methods, this method works for
3867 * both dynamic and non-dynamic methods. It is a superset of GetFunctionFromIP2
3869 HRESULT GetFunctionFromIP3([in] LPCBYTE ip,
3870 [out] FunctionID *functionId,
3871 [out] ReJITID * pReJitId);
3874 * Retrieves informaiton about dynamic methods
3876 * Certain methods like IL Stubs or LCG do not have
3877 * associated metadata that can be retrieved using the IMetaDataImport APIs.
3879 * Such methods can be encountered by profilers through instruction pointers
3880 * or by listening to ICorProfilerCallback::DynamicMethodJITCompilationStarted
3882 * This API can be used to retrieve information about dynamic methods
3883 * including a friendly name if available.
3885 HRESULT GetDynamicFunctionInfo( [in] FunctionID functionId,
3886 [out] ModuleID *moduleId,
3887 [out] PCCOR_SIGNATURE *ppvSig,
3890 [out] ULONG *pcchName,
3891 [out] WCHAR wszName[]);
3896 uuid(008170DB-F8CC-4796-9A51-DC8AA0B47012),
3897 pointer_default(unique),
3900 interface ICorProfilerInfo9 : ICorProfilerInfo8
3902 //Given functionId + rejitId, enumerate the native code start address of all jitted versions of this code that currently exist
3903 HRESULT GetNativeCodeStartAddresses(FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[]);
3905 //Given the native code start address, return the native->IL mapping information for this jitted version of the code
3906 HRESULT GetILToNativeMapping3(UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[]);
3908 //Given the native code start address, return the the blocks of virtual memory that store this code (method code is not necessarily stored in a single contiguous memory region)
3909 HRESULT GetCodeInfo4(UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32* pcCodeInfos, COR_PRF_CODE_INFO codeInfos[]);
3913 * This interface lets you iterate over methods in the runtime.
3918 uuid(FCCEE788-0088-454B-A811-C99F298D1942),
3919 pointer_default(unique),
3922 interface ICorProfilerMethodEnum : IUnknown
3924 HRESULT Skip([in] ULONG celt);
3928 HRESULT Clone([out] ICorProfilerMethodEnum **ppEnum);
3930 HRESULT GetCount([out] ULONG *pcelt);
3932 HRESULT Next([in] ULONG celt,
3933 [out, size_is(celt), length_is(*pceltFetched)]
3934 COR_PRF_METHOD elements[],
3935 [out] ULONG * pceltFetched);
3939 * This interface lets you iterate over threads in the runtime.
3944 uuid(571194f7-25ed-419f-aa8b-7016b3159701),
3945 pointer_default(unique),
3948 interface ICorProfilerThreadEnum : IUnknown
3950 HRESULT Skip([in] ULONG celt);
3954 HRESULT Clone([out] ICorProfilerThreadEnum **ppEnum);
3956 HRESULT GetCount([out] ULONG *pcelt);
3958 HRESULT Next([in] ULONG celt,
3959 [out, size_is(celt), length_is(*pceltFetched)]
3961 [out] ULONG * pceltFetched);
3966 * This interface is given to the profiler in the GetAssemblyReferences() callback, to
3967 * allow the profiler to inform the CLR of assembly references that the profiler plans to
3968 * add later on during ModuleLoadFinished. This improves the accuracy of the CLR assembly
3969 * reference closure walker, and its algorithms for determining whether assemblies may be shared
3971 * This interface is valid for use only within the GetAssemblyReferences callback that passed
3972 * this interface to the profiler
3976 uuid(66A78C24-2EEF-4F65-B45F-DD1D8038BF3C),
3977 pointer_default(unique),
3980 interface ICorProfilerAssemblyReferenceProvider : IUnknown
3982 // The profiler calls this for each target assembly it plans to reference from the
3983 // assembly specified in the wszAssemblyPath argument of the GetAssemblyReferences callback.
3984 HRESULT AddAssemblyReference(const COR_PRF_ASSEMBLY_REFERENCE_INFO * pAssemblyRefInfo);
3988 /***************************************************************************************
3990 ** Activated using mscoree!CLRCreateInstance. Export AttachProfiler API to profilers **
3991 ***************************************************************************************/
3993 uuid(B349ABE3-B56F-4689-BFCD-76BF39D888EA),
3995 helpstring("CoreCLR profiling interface for profiler attach"),
3998 interface ICLRProfiling : IUnknown
4000 HRESULT AttachProfiler(
4001 [in] DWORD dwProfileeProcessID,
4002 [in] DWORD dwMillisecondsMax, // optional
4003 [in] const CLSID * pClsidProfiler,
4004 [in] LPCWSTR wszProfilerPath, // optional
4005 [in, size_is(cbClientData)] void * pvClientData, // optional
4006 [in] UINT cbClientData); // optional