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)); }
private void SerializeMemoryInspectionLabel(IFastJsonWriter writer, MemoryInspectionLabel label) { writer.WriteStartObject(); writer.WriteProperty("name", label.Name); writer.WriteProperty("offset", label.Offset); writer.WriteProperty("length", label.Length); if (label.Nested.Count > 0) { writer.WritePropertyStartArray("nested"); foreach (var nested in label.Nested) { SerializeMemoryInspectionLabel(writer, nested); } writer.WriteEndArray(); } writer.WriteEndObject(); }
private void WriteMemoryLabel(Utf8JsonWriter writer, MemoryInspectionLabel label) { writer.WriteStartObject(); writer.WriteString(Name, label.Name); writer.WriteNumber(Offset, label.Offset); writer.WriteNumber(Length, label.Length); if (label.Nested.Count > 0) { writer.WriteStartArray(Nested); foreach (var nested in label.Nested) { WriteMemoryLabel(writer, nested); } writer.WriteEndArray(); } writer.WriteEndObject(); }
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)); }