public static void Heap(object @object) { EnsureRuntime(); var address = (ulong)GetHeapPointer(@object); var objectType = _runtime.Heap.GetObjectType((ulong)GetHeapPointer(@object)); if (objectType == null) { throw new Exception($"Failed to find object type for address 0x{(ulong)GetHeapPointer(@object):X}."); } var objectSize = objectType.GetSize(address); // Move by one pointer size back -- Object Header, // see https://blogs.msdn.microsoft.com/seteplia/2017/05/26/managed-object-internals-part-1-layout/ // // Not sure if there is a better way to get this through ClrMD yet. // https://github.com/Microsoft/clrmd/issues/99 var objectStart = address - (uint)IntPtr.Size; var data = ReadMemory(objectStart, objectSize); var labels = CreateLabelsFromType(objectType, address, objectStart, first: (index: 2, offset: 2 * IntPtr.Size)); labels[0] = new MemoryInspectionLabel("header", 0, IntPtr.Size); labels[1] = new MemoryInspectionLabel("type handle", IntPtr.Size, IntPtr.Size); Output.Write(new MemoryInspection($"{objectType.Name} at 0x{address:X}", labels, data)); }
public MemoryInspection InspectHeap(object @object) { if (@object == null) { throw new ArgumentNullException(nameof(@object), $"Inspect.Heap can't inspect null, as it does not point to a valid location on the heap."); } using var runtimeLease = _runtimePool.GetOrCreate(); var runtime = runtimeLease.Object; runtime.FlushCachedData(); var address = (ulong)GetHeapPointer(@object); var objectType = runtime.Heap.GetObjectType(address); if (objectType == null) { throw new ClrInformationNotFoundException($"Failed to find object type for address 0x{address:X}."); } var objectSize = runtime.Heap.GetObjectSize(address, objectType); // Move by one pointer size back -- Object Header, // see https://blogs.msdn.microsoft.com/seteplia/2017/05/26/managed-object-internals-part-1-layout/ // // Not sure if there is a better way to get this through ClrMD yet. // https://github.com/Microsoft/clrmd/issues/99 var objectStart = address - (uint)IntPtr.Size; var data = ReadMemory(runtime, objectStart, objectSize); var labels = CreateLabelsFromType(objectType, address, objectStart, first: (index: 2, offset: 2 * IntPtr.Size)); labels[0] = new MemoryInspectionLabel("header", 0, IntPtr.Size); labels[1] = new MemoryInspectionLabel("type handle", IntPtr.Size, IntPtr.Size); return(new MemoryInspection($"{objectType.Name} at 0x{address:X}", labels, data)); }