Object Inspection in the Profiling API
This topic discusses how to use profiling methods to inspect objects.
FunctionEnter2 and FunctionLeave2 Callbacks
The FunctionEnter2 and FunctionLeave2 callbacks provide information about the arguments and return value of a function, as regions of memory. The arguments are stored from left to right in the given memory regions. A profiler can use the metadata signature of the function to interpret the arguments, as shown in the following table.
ELEMENT_TYPE |
Representation |
---|---|
Primitives (ELEMENT_TYPE <= R8, I, U) |
Primitive values. |
Value types (VALUETYPE) |
Depends on type. |
Reference types (CLASS, STRING, OBJECT, ARRAY, GENERICINST, SZARRAY) |
ObjectID (pointer into a garbage collection heap). |
BYREF |
Managed pointer (not an ObjectID, but may be pointing to a stack or garbage collection heap). |
PTR |
Unmanaged pointer (not movable by garbage collection). |
FNPTR |
Pointer-sized opaque value. |
TYPEDBYREF |
Managed pointer, followed by a pointer-sized opaque value. |
The differences between an ObjectID and a managed pointer are as follows:
ObjectIDs point only into the garbage collection heap or frozen object heap. Managed pointers may also point to the stack.
ObjectIDs always point to the beginning of an object. Managed pointers may point to one of the object's fields.
Managed pointers cannot be passed to functions that expect an ObjectID.
See the CorElementType enumeration for a list of the available CLR types.
Inspecting Complex Types
Inspecting reference types or non-primitive value types involves some advanced techniques.
For value types and reference types other than strings or arrays, the ICorProfilerInfo2::GetClassLayout method provides the offset for each field. The profiler can then use the metadata to determine the type of the field and recursively evaluate it.
Note
GetClassLayout returns only the fields that are defined by the class itself; fields that are defined by the parent class are not included. You can use the ICorProfilerInfo2::GetClassIDInfo2 method to find the ClassID of the parent class, and then use GetClassLayout to obtain information about the fields defined by the parent class.
For boxed value types, the ICorProfilerInfo2::GetBoxClassLayout method provides the offset of the value type within the box. The layout of the value type itself does not change. Therefore, as soon as the profiler has found the value type within the box, it can use GetClassLayout to understand its layout.
For strings, the ICorProfilerInfo2::GetStringLayout method provides the offsets of interesting pieces of data in the string object.
Arrays are somewhat special in that you must call a method for each array object instead of each array type. (This is because there are too many array formats to describe by using offsets.) The ICorProfilerInfo2::GetArrayObjectInfo method is provided to do the interpretation.
Inspecting Static Fields
There are four types of static fields. The following table describes what they are and how to identify them.
Static type |
Definition |
How it appears in metadata |
---|---|---|
AppDomain |
Your basic static field. It has a different value in each application domain. |
Static field that has no attached custom attributes. |
Thread |
Managed thread-local storage (TLS). This is a static field with a unique value for each thread and each application domain. |
Static field marked with ThreadStaticAttribute. |
RVA |
Process-scoped static field with a home in the module's data section. |
Static field with hasRVA flag. |
Context |
Static field with a different value in each COM+ context. |
Static field marked with ContextStaticAttribute. |
The ICorProfilerInfo2::GetThreadStaticAddress, ICorProfilerInfo2::GetAppDomainStaticAddress, ICorProfilerInfo2::GetContextStaticAddress, and ICorProfilerInfo2::GetRVAStaticAddress methods provide information about the location of static fields. Looking at the memory at that location, you interpret it as follows:
Reference types: ObjectID.
Value types: ObjectID of box that contains the actual value.
Primitive types: Primitive value.
Reference
ICorProfilerInfo2::GetClassLayout Method
ICorProfilerInfo2::GetBoxClassLayout Method
ICorProfilerInfo2::GetStringLayout Method
ICorProfilerInfo2::GetArrayObjectInfo Method
ICorProfilerInfo2::GetThreadStaticAddress Method
ICorProfilerInfo2::GetAppDomainStaticAddress Method
ICorProfilerInfo2::GetContextStaticAddress Method
ICorProfilerInfo2::GetRVAStaticAddress Method