public override IEnumerable <ClrReference> EnumerateReferencesWithFields(ulong obj, ClrType type, bool carefully, bool considerDependantHandles) { if (type is null) { throw new ArgumentNullException(nameof(type)); } if (considerDependantHandles) { ImmutableArray <(ulong Source, ulong Target)> dependent = GetHeapData().GetDependentHandles(_helpers); if (dependent.Length > 0) { int index = dependent.Search(obj, (x, y) => x.Source.CompareTo(y)); if (index != -1) { while (index >= 1 && dependent[index - 1].Source == obj) { index--; } while (index < dependent.Length && dependent[index].Source == obj) { ulong dependantObj = dependent[index++].Target; ClrObject target = new ClrObject(dependantObj, GetObjectType(dependantObj)); yield return(ClrReference.CreateFromDependentHandle(target)); } } } } if (type.ContainsPointers) { GCDesc gcdesc = type.GCDesc; if (!gcdesc.IsEmpty) { ulong size = GetObjectSize(obj, type); if (carefully) { ClrSegment?seg = GetSegmentByAddress(obj); if (seg is null || obj + size > seg.End || (!seg.IsLargeObjectSegment && size > MaxGen2ObjectSize)) { yield break; } } foreach ((ulong reference, int offset) in gcdesc.WalkObject(obj, size, _helpers.DataReader)) { ClrObject target = new ClrObject(reference, GetObjectType(reference)); yield return(ClrReference.CreateFromFieldOrArray(target, type, offset)); } } } }
internal ClrGraphNode(ClrGraph owner, ClrReference startReference) { _owner = owner; this.Self = startReference.Object; this.SelfReference = startReference; if (_owner.Visited.Contains(startReference.Object.Address)) { IsAlreadyVisited = true; return; } PopulateChildren(startReference.Object); }
public void TestEnumerateRefsWithFields() { using DataTarget dataTarget = TestTargets.GCRoot.LoadFullDump(); using ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrObject singleRef = FindSingleRefPointingToTarget(heap); ClrReference fieldRef = singleRef.EnumerateReferencesWithFields(considerDependantHandles: true).Single(); Assert.True(fieldRef.IsDependentHandle); Assert.False(fieldRef.IsField); singleRef = FindSingleRefPointingToType(heap, "TripleRef"); fieldRef = singleRef.EnumerateReferencesWithFields(considerDependantHandles: false).Single(); Assert.False(fieldRef.IsDependentHandle); Assert.True(fieldRef.IsField); Assert.NotNull(fieldRef.Field); Assert.Equal("Item1", fieldRef.Field.Name); }