Skip to content

Commit d511dd9

Browse files
author
fremag
committed
Instance details module: display the fieldname referencing the instance
Closes #86
1 parent 2d44ba6 commit d511dd9

File tree

2 files changed

+74
-13
lines changed

2 files changed

+74
-13
lines changed

MemoScope/Core/ClrDump.cs

+62-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class ClrDump
2929

3030
public List<ClrHandle> Handles => Runtime.EnumerateHandles().ToList();
3131
public List<ulong> FinalizerQueueObjectAddresses => Runtime.EnumerateFinalizerQueueObjectAddresses().ToList();
32-
public IEnumerable<IGrouping<ClrType, ulong>> FinalizerQueueObjectAddressesByType => Runtime.EnumerateFinalizerQueueObjectAddresses().GroupBy( address => GetObjectType(address));
32+
public IEnumerable<IGrouping<ClrType, ulong>> FinalizerQueueObjectAddressesByType => Runtime.EnumerateFinalizerQueueObjectAddresses().GroupBy(address => GetObjectType(address));
3333
public IEnumerable<ClrRoot> ClrRoots => Runtime.GetHeap().EnumerateRoots();
3434
public List<BlockingObject> BlockingObjects => Runtime.GetHeap().EnumerateBlockingObjects().ToList();
3535
public IList<ClrThread> Threads => Runtime.Threads;
@@ -52,7 +52,7 @@ public Dictionary<int, ThreadProperty> ThreadProperties
5252
Dictionary<int, ThreadProperty> threadProperties;
5353
private readonly SingleThreadWorker worker;
5454
private ClrDumpCache cache;
55-
55+
5656
public ClrDump(DataTarget target, string dumpPath, MessageBus msgBus)
5757
{
5858
Id = n++;
@@ -85,7 +85,7 @@ private void InitRuntime()
8585

8686
public List<ClrType> GetTypes()
8787
{
88-
List<ClrType> t = worker.Eval( () => t = AllTypes);
88+
List<ClrType> t = worker.Eval(() => t = AllTypes);
8989
return t;
9090
}
9191

@@ -98,7 +98,7 @@ internal void Destroy()
9898
internal void Dispose()
9999
{
100100
cache.Dispose();
101-
Run( () => Runtime.DataTarget.Dispose());
101+
Run(() => Runtime.DataTarget.Dispose());
102102
}
103103

104104
public ClrType GetClrType(string typeName)
@@ -125,7 +125,7 @@ public IEnumerable<ulong> EnumerateInstances(ClrType type)
125125
return cache.EnumerateInstances(typeId);
126126
}
127127

128-
public List<ulong> GetInstances(int typeId, int max=int.MaxValue)
128+
public List<ulong> GetInstances(int typeId, int max = int.MaxValue)
129129
{
130130
var instances = cache.LoadInstances(typeId, max);
131131
return instances;
@@ -177,7 +177,7 @@ private object GetSimpleValueImpl(ulong address, ClrType type)
177177
var value = SimpleValueHelper.GetSimpleValue(address, type, false);
178178
return value;
179179
}
180-
180+
181181
return address;
182182
}
183183

@@ -200,7 +200,7 @@ public object GetFieldValueImpl(ulong address, ClrType type, List<ClrInstanceFie
200200
{
201201
var field = fields[i];
202202
obj = obj[field];
203-
if( obj.IsNull )
203+
if (obj.IsNull)
204204
{
205205
return null;
206206
}
@@ -235,7 +235,7 @@ public bool HasReferences(ulong address)
235235

236236
public int CountReferences(ulong address)
237237
{
238-
var count = cache.CountReferences(address) ;
238+
var count = cache.CountReferences(address);
239239
return count;
240240
}
241241

@@ -251,7 +251,13 @@ public string GetObjectTypeName(ulong address)
251251

252252
public ClrType GetObjectType(ulong address)
253253
{
254-
var clrType = worker.Eval(() => Heap.GetObjectType(address));
254+
var clrType = worker.Eval(() => GetObjectTypeImpl(address));
255+
return clrType;
256+
}
257+
258+
public ClrType GetObjectTypeImpl(ulong address)
259+
{
260+
var clrType = Heap.GetObjectType(address);
255261
return clrType;
256262
}
257263

@@ -298,6 +304,53 @@ public ClrMethod GetMethodByHandle(ulong methodDescriptorPtr)
298304
var meth = Runtime.GetMethodByHandle(methodDescriptorPtr);
299305
return meth;
300306
}
307+
308+
// Find the field in instance at address that references refAddress
309+
public string GetFieldNameReference(ulong refAddress, ulong address)
310+
{
311+
return Eval(() => GetFieldNameReferenceImpl(refAddress, address));
312+
}
313+
public string GetFieldNameReferenceImpl(ulong refAddress, ulong address)
314+
{
315+
ClrType type = GetObjectTypeImpl(address);
316+
if (type == null)
317+
{
318+
return "Unknown";
319+
}
320+
ClrObject obj = new ClrObject(address, type);
321+
if (type.IsArray)
322+
{
323+
var length = type.GetArrayLength(address);
324+
for (int i = 0; i < length; i++)
325+
{
326+
if (obj[i].Address == refAddress)
327+
{
328+
return $"[ {i} ]";
329+
}
330+
}
331+
return "[ ? ]";
332+
}
333+
foreach (var field in type.Fields)
334+
{
335+
switch (field.ElementType)
336+
{
337+
case ClrElementType.Struct:
338+
case ClrElementType.String:
339+
case ClrElementType.Array:
340+
case ClrElementType.SZArray:
341+
case ClrElementType.Object:
342+
var fieldValue = obj[field];
343+
if (fieldValue.Address == refAddress)
344+
{
345+
return field.Name;
346+
}
347+
break;
348+
}
349+
}
350+
return "???";
351+
}
352+
353+
301354
}
302355

303356
public class ThreadProperty

MemoScope/Modules/InstanceDetails/ReferenceInformation.cs

+12-4
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,26 @@ public class ReferenceInformation : ITreeNodeInformation<ReferenceInformation>,
1515
[OLVColumn(Title = "Address")]
1616
public ulong Address { get; }
1717

18+
[OLVColumn]
19+
public string FieldName { get; }
20+
1821
[OLVColumn(Title = "Type")]
1922
public string TypeName => ClrDump.GetObjectTypeName(Address);
2023

2124
public ClrType ClrType => ClrDump.GetObjectType(Address);
2225

23-
public ReferenceInformation(ClrDump dump, ulong address)
26+
public ReferenceInformation(ClrDump clrDump, ulong address, ulong refAddress) : this(clrDump, address)
27+
{
28+
FieldName = ClrDump.GetFieldNameReference(refAddress, address);
29+
}
30+
31+
public ReferenceInformation(ClrDump clrDump, ulong address)
2432
{
25-
ClrDump = dump;
33+
ClrDump = clrDump;
2634
Address = address;
27-
}
35+
}
2836

2937
public bool CanExpand => ClrDump.HasReferences(Address);
30-
public List<ReferenceInformation> Children => ClrDump.GetReferences(Address).Select(address => new ReferenceInformation(ClrDump, address)).ToList();
38+
public List<ReferenceInformation> Children => ClrDump.GetReferences(Address).Select(address => new ReferenceInformation(ClrDump, address, Address)).ToList();
3139
}
3240
}

0 commit comments

Comments
 (0)