Example #1
0
    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();
 }
Example #3
0
 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();
 }
Example #4
0
        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));
        }