public NativeStackRootWalker(ClrHeap heap, ClrAppDomain domain, ClrThread thread) { _heap = heap; _domain = domain; _thread = thread; Roots = new List<ClrRoot>(); }
public RhStackRootWalker(ClrHeap heap, ClrAppDomain domain, ClrThread thread) { m_heap = heap; m_domain = domain; m_thread = thread; Roots = new List<ClrRoot>(); }
/// <summary> /// Gets all object references /// </summary> /// <param name="currentObjPoi">Objects whose references are checked</param> /// <param name="visitedObjects">Already checked objects</param> /// <param name="objCountByType">Keeping track of type distribution</param> /// <param name="heap"></param> private void EnumerateRootReferences( ulong currentObjPoi, HashSet <ulong> visitedObjects, IDictionary <string, HashSet <ulong> > objCountByType, ClrHeap heap) { // Empty pointer is passed or we have already checked the object if ((currentObjPoi == 0) || visitedObjects.Contains(currentObjPoi)) { return; } // Mark that we have processed the node visitedObjects.Add(currentObjPoi); // Get object type ClrType type = heap.GetObjectType(currentObjPoi); if (type == null) { return; // Cannot do anything } if (objCountByType.ContainsKey(type.Name)) { objCountByType[type.Name].Add(currentObjPoi); } else { objCountByType[type.Name] = new HashSet <ulong> { currentObjPoi }; } type.EnumerateRefsOfObject(currentObjPoi, delegate(ulong arg1, int i) { if (visitedObjects.Contains(arg1)) { return; } this.EnumerateRootReferences(arg1, visitedObjects, objCountByType, heap); }); }
private static void CheckSegments(ClrHeap heap) { foreach (ClrSegment seg in heap.Segments) { Assert.NotEqual(0ul, seg.Start); Assert.NotEqual(0ul, seg.End); Assert.True(seg.Start <= seg.End); Assert.True(seg.Start < seg.CommittedMemory.End); Assert.True(seg.CommittedMemory.End < seg.ReservedMemory.End); Assert.False(seg.CommittedMemory.Overlaps(seg.ReservedMemory)); Assert.True(seg.CommittedMemory.Contains(seg.ObjectRange)); if (seg.Generation0.Length > 0) { Assert.True(seg.ObjectRange.Contains(seg.Generation0)); } if (seg.Generation1.Length > 0) { Assert.True(seg.ObjectRange.Contains(seg.Generation1)); } if (seg.Generation2.Length > 0) { Assert.True(seg.ObjectRange.Contains(seg.Generation2)); } if (!seg.IsEphemeralSegment) { Assert.Equal(0ul, seg.Generation0.Length); Assert.Equal(0ul, seg.Generation1.Length); } int count = 0; foreach (ulong obj in seg.EnumerateObjects()) { ClrSegment curr = heap.GetSegmentByAddress(obj); Assert.Same(seg, curr); count++; } Assert.True(count >= 1); } }
public void HeapEnumeration() { // Simply test that we can enumerate the heap. using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); int count = 0; foreach (ulong obj in heap.EnumerateObjectAddresses()) { Assert.IsNotNull(heap.GetObjectType(obj)); count++; } Assert.IsTrue(count > 0); } }
public HeapSnapshot(ClrHeap heap, int topTypes) { var query = from address in heap.EnumerateObjectAddresses() let type = heap.GetObjectType(address) where type != null && !type.IsFree let size = type.GetSize(address) group size by type.Name into g let totalSize = g.Sum(v => (long)v) let count = g.Count() orderby totalSize descending select new { Type = g.Key, Size = totalSize, Count = count }; foreach (var typeStats in query.Take(topTypes)) { SizeByType.Add(typeStats.Type, typeStats.Size); CountByType.Add(typeStats.Type, typeStats.Count); } }
public HexView(int id, ConcurrentDictionary <int, Window> wndDct, ClrtDump clrtDump, ulong addr) { _id = id; _wndDct = wndDct; _clrtDump = clrtDump; _currentAddr = Utils.RealAddress(addr); // round down to 8 boundary _currentAddr = (_currentAddr / 8UL) * 8UL; InitializeComponent(); WordSizeLabel.Content = "word size: " + _wordLenght; ColumnCountLabel.Content = "col count: " + _colCount; _heap = _clrtDump.Heap; _bytes = new byte[_byteBufSize]; _wndDct.TryAdd(id, this); }
public static IEnumerable <ClrObject> EnumerateClrObjects(this ClrHeap heap, string typeName) { if (typeName.Contains("*")) { string typeNameRegex = "^" + Regex.Escape(typeName).Replace("\\*", ".*") + "$"; Regex regex = new Regex(typeNameRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase); return(from address in heap.EnumerateObjects() let type = heap.GetSafeObjectType(address) where type != null && regex.IsMatch(type.Name) select new ClrObject(address, type)); } return(from address in heap.EnumerateObjects() let type = heap.GetSafeObjectType(address) where type != null && type.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase) select new ClrObject(address, type)); }
public void StringEmptyIsObtainableTest() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrType stringType = heap.StringType; Assert.NotNull(stringType); ClrStaticField empty = stringType.GetStaticFieldByName("Empty"); Assert.NotNull(empty); string value = empty.ReadString(runtime.AppDomains.Single()); Assert.Equal(string.Empty, value); }
public void Execute(DebuggerContext context, string args) { ClrHeap heap = context.Runtime.Heap; var allStateMachines = new List <AsyncStateMachine>(); var knownStateMachines = new Dictionary <ulong, AsyncStateMachine>(); GetAllStateMachines(context, heap, allStateMachines, knownStateMachines); ChainStateMachinesBasedOnTaskContinuations(context, knownStateMachines); ChainStateMachinesBasedOnJointableTasks(context, allStateMachines); MarkThreadingBlockTasks(context, allStateMachines); MarkUIThreadDependingTasks(context, allStateMachines); FixBrokenDependencies(allStateMachines); PrintOutStateMachines(allStateMachines, context.Output); this.LoadCodePages(context, allStateMachines); }
public void InstanceFieldProperties() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrType foo = runtime.GetModule("sharedlibrary.dll").GetTypeByName("Foo"); Assert.NotNull(foo); CheckField(foo, "i", ClrElementType.Int32, "System.Int32", 4); CheckField(foo, "s", ClrElementType.String, "System.String", IntPtr.Size); CheckField(foo, "b", ClrElementType.Boolean, "System.Boolean", 1); CheckField(foo, "f", ClrElementType.Float, "System.Single", 4); CheckField(foo, "d", ClrElementType.Double, "System.Double", 8); CheckField(foo, "o", ClrElementType.Object, "System.Object", IntPtr.Size); }
/// <summary> /// Gets the static field value. /// <para> WARN - resolves value for single domain only.</para> /// </summary> /// <param name="runtime">The runtime.</param> /// <param name="typeName">Name of the type.</param> /// <param name="fieldName">Name of the field.</param> /// <returns></returns> /// <exception cref="ClrTypeNotFound"></exception> public static ClrObject GetStaticFldValue(this ClrRuntime runtime, [NotNull] string typeName, [NotNull] string fieldName) { Assert.ArgumentNotNullOrEmpty(typeName, "typeName"); Assert.ArgumentNotNullOrEmpty(fieldName, "fieldName"); ClrHeap heap = runtime.GetHeap(); Assert.ResultNotNull(heap, "Could not fetch heap from runtime"); ClrType type = heap.GetTypeByName(typeName); if (type == null) { throw new ClrTypeNotFound(typeName); } return(runtime.GetStaticFldValue(type, fieldName)); }
public void ArrayLengthTest() { using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrAppDomain domain = runtime.AppDomains.Single(); ClrModule typesModule = runtime.GetModule("types.exe"); ClrType type = heap.GetTypeByName("Types"); ulong s_array = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain); ClrType arrayType = heap.GetObjectType(s_array); Assert.Equal(3, arrayType.GetArrayLength(s_array)); } }
public void GCRootsIndirectHandles() { using DataTarget dataTarget = TestTargets.GCRoot2.LoadFullDump(); using ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; GCRoot gcroot = new GCRoot(heap); ulong target = heap.GetObjectsOfType("IndirectTarget").Single(); _ = Assert.Single(gcroot.EnumerateGCRoots(target, unique: true, 8, CancellationToken.None)); GCRootPath path = Assert.Single(gcroot.EnumerateGCRoots(target, unique: true, 1, CancellationToken.None)); var paths = gcroot.EnumerateGCRoots(target, unique: false, 1, CancellationToken.None).ToArray(); Assert.Equal(2, gcroot.EnumerateGCRoots(target, unique: false, 1, CancellationToken.None).Count()); Assert.Equal(2, gcroot.EnumerateGCRoots(target, unique: false, 8, CancellationToken.None).Count()); }
public void GetFieldFrom_WhenFieldFound_ReturnsField([Frozen] ClrHeap heap, ClrValueClass target, [Frozen] ClrType clrObjectType, ClrObject rawClrObject, ClrInstanceField clrObjValueField) { // Arrange IAddressableTypedEntity entity = rawClrObject; clrObjValueField.IsValueClass.Returns(true); clrObjValueField.Type.Returns(target.Type); clrObjValueField .GetAddress(rawClrObject.Address) .Returns(target.Address); // Act var structRefFieldTarget = rawClrObject.GetFieldFrom(clrObjValueField.Name); // Assert structRefFieldTarget.Equals(target).Should().BeTrue(); }
public void ObjectSetTryAdd() { using (DataTarget dataTarget = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ObjectSet hash = new ObjectSet(heap); foreach (ulong obj in heap.EnumerateObjectAddresses()) { Assert.IsFalse(hash.Contains(obj)); Assert.IsTrue(hash.Add(obj)); Assert.IsTrue(hash.Contains(obj)); Assert.IsFalse(hash.Add(obj)); Assert.IsTrue(hash.Contains(obj)); } } }
private Dictionary <string, int> ComputeDuplicatedStrings(ClrHeap heap) { // do nothing if in the middle of a gargabe collection if (!heap.CanWalkHeap) { return(null); } Dictionary <string, int> strings = new Dictionary <string, int>(); foreach (var address in heap.EnumerateObjectAddresses()) { try { var objType = heap.GetObjectType(address); if (objType == null) // in case of memory corruption { continue; } // count only strings if (objType.Name != "System.String") { continue; } var obj = objType.GetValue(address); string s = obj as string; if (!strings.ContainsKey(s)) { strings[s] = 0; } strings[s] = strings[s] + 1; } catch (Exception x) { WriteLine(x.ToString()); // some InvalidOperationException might occur sometimes } } return(strings); }
public void GetObjectMethodTableTest() { using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; int i = 0; foreach (ulong obj in heap.EnumerateObjectAddresses()) { i++; ClrType type = heap.GetObjectType(obj); if (type.IsArray) { ulong mt, cmt; bool result = heap.TryGetMethodTable(obj, out mt, out cmt); Assert.True(result); Assert.NotEqual(0ul, mt); Assert.Equal(type.MethodTable, mt); Assert.Same(type, heap.GetTypeByMethodTable(mt, cmt)); } else { ulong mt = heap.GetMethodTable(obj); Assert.NotEqual(0ul, mt); Assert.Contains(mt, type.EnumerateMethodTables()); Assert.Same(type, heap.GetTypeByMethodTable(mt)); Assert.Same(type, heap.GetTypeByMethodTable(mt, 0)); ulong mt2, cmt; bool res = heap.TryGetMethodTable(obj, out mt2, out cmt); Assert.True(res); Assert.Equal(mt, mt2); Assert.Equal(0ul, cmt); } } } }
private void GetObjSize(ClrHeap heap, ulong obj, out uint count, out ulong size) { // Evaluation stack var eval = new Stack <ulong>(); // To make sure we don't count the same object twice, we'll keep a set of all objects // we've seen before. var considered = new HashSet <ulong>(); count = 0; size = 0; eval.Push(obj); while (eval.Count > 0) { // Pop an object, ignore it if we've seen it before. obj = eval.Pop(); if (!considered.Add(obj)) { continue; } // Grab the type. We will only get null here in the case of heap corruption. ClrType type = heap.GetObjectType(obj); if (type == null) { continue; } count++; size += type.GetSize(obj); // Now enumerate all objects that this object points to, add them to the // evaluation stack if we haven't seen them before. type.EnumerateRefsOfObject(obj, (child, offset) => { if (child != 0 && !considered.Contains(child)) { eval.Push(child); } }); } }
public static void Print(ClrHeap heap, IClrObjectPrinter[] printers) { foreach (var clrObject in heap.EnumerateObjects()) { if (clrObject.Type == null) { continue; } var printer = printers.FirstOrDefault(x => x.Supports(clrObject.Type)); if (printer == null) { continue; } Console.WriteLine($"** {clrObject.Type.Name} at {clrObject.HexAddress}"); printer.Print(clrObject); } }
public ObjectSet(ClrHeap heap) { m_shift = IntPtr.Size == 4 ? 3 : 4; int count = heap.Segments.Count; m_data = new BitArray[count]; m_entries = new Entry[count]; for (int i = 0; i < count; ++i) { var seg = heap.Segments[i]; m_data[i] = new BitArray(GetBitOffset(seg.Length)); m_entries[i].Low = seg.Start; m_entries[i].High = seg.End; m_entries[i].Index = i; } }
public void PrevObject() { using DataTarget dt = TestTargets.Types.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; foreach (ClrSegment seg in heap.Segments) { ClrObject prev = heap.GetObject(seg.FirstObjectAddress); Assert.Equal(0ul, seg.GetPreviousObjectAddress(prev)); foreach (ClrObject curr in seg.EnumerateObjects().Skip(1)) { Assert.Equal(prev.Address, seg.GetPreviousObjectAddress(curr)); prev = curr; } } }
public void FindAllPaths() { using DataTarget dataTarget = TestTargets.GCRoot.LoadFullDump(); using ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; GCRoot gcroot = new GCRoot(heap); GetKnownSourceAndTarget(heap, out ulong source, out ulong target); LinkedList <ClrObject>[] paths = gcroot.EnumerateAllPaths(source, target, false, CancellationToken.None).ToArray(); // There are exactly three paths to the object in the test target Assert.Equal(3, paths.Length); foreach (LinkedList <ClrObject> path in paths) { AssertPathIsCorrect(heap, path.ToImmutableArray(), source, target); } }
public void GetObjectField_WhenFieldFound_ReturnsField([Frozen] ClrHeap heap, ClrObject target, [Frozen] ClrType structType, ClrValueClass someStruct, ClrInstanceField structReferenceField, ulong fieldAddress) { // Arrange structReferenceField.IsObjectReference.Returns(true); structReferenceField.GetAddress(someStruct.Address, Arg.Any <bool>()).Returns(fieldAddress); heap.ReadPointer(fieldAddress, out var whatever) .Returns(call => { call[1] = target.Address; return(true); }); // Act var structRefFieldTarget = someStruct.GetObjectField(structReferenceField.Name); // Assert structRefFieldTarget.Should().Be(target); }
public void FieldNameAndValueTests() { using DataTarget dt = TestTargets.Types.LoadFullDump(); ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrAppDomain domain = runtime.AppDomains.Single(); ClrType fooType = runtime.GetModule("sharedlibrary.dll").GetTypeByName("Foo"); ulong obj = (ulong)runtime.GetModule("types.exe").GetTypeByName("Types").GetStaticFieldByName("s_foo").GetValue(runtime.AppDomains.Single()); Assert.Same(fooType, heap.GetObjectType(obj)); TestFieldNameAndValue(fooType, obj, "i", 42); TestFieldNameAndValue(fooType, obj, "s", "string"); TestFieldNameAndValue(fooType, obj, "b", true); TestFieldNameAndValue(fooType, obj, "f", 4.2f); TestFieldNameAndValue(fooType, obj, "d", 8.4); }
public void EnumerateGCRefsArray() { using DataTarget dataTarget = TestTargets.GCRoot.LoadFullDump(); using ClrRuntime runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; ClrModule module = heap.Runtime.GetMainModule(); ClrType mainType = module.GetTypeByName("GCRootTarget"); ClrObject obj = mainType.GetStaticObjectValue("TheRoot"); obj = obj.GetObjectField("Item1"); Assert.Equal("System.Object[]", obj.Type.Name); ClrObject[] refs = obj.EnumerateReferences(false).ToArray(); Assert.Single(refs); Assert.Equal("DoubleRef", refs[0].Type.Name); }
public static Dictionary <string, int> ComputeDuplicatedStrings(ClrHeap heap) { var strings = new Dictionary <string, int>(1024 * 1024); // never forget to check if it is possible to walk the heap if (!heap.CanWalkHeap) { return(null); } foreach (var address in heap.EnumerateObjectAddresses()) { try { var objType = heap.GetObjectType(address); if (objType == null) { continue; } if (objType.Name != "System.String") { continue; } var obj = objType.GetValue(address); var s = obj as string; if (!strings.ContainsKey(s)) { strings[s] = 0; } strings[s] = strings[s] + 1; } catch (Exception x) { Console.WriteLine(x); // some InvalidOperationException seems to occur :^( } } return(strings); }
public void GetObjectField_WhenTypeHasFieldWithName_FindsField([Frozen] ClrHeap heap, [Frozen] ClrType objectType, ClrObject source, ClrInstanceField clrField, ulong fieldAddress, ClrObject target) { // Arrange clrField.IsObjectReference.Returns(true); clrField.GetAddress(source.Address).Returns(fieldAddress); heap.ReadPointer(fieldAddress, out var whatever) .Returns(call => { call[1] = target.Address; return(true); }); // Act var fieldFoundByName = source.GetObjectField(clrField.Name); // Assert fieldFoundByName.Address.Should().Be(target); }
private static void PrintOffsets(ClrHeap heap, List <ulong> addresses) { if (addresses.Count == 0) { return; } var segments = new HashSet <ulong>(); var offsetCounts = new Dictionary <long, int>(); var previous = addresses[0]; segments.Add(heap.GetSegmentByAddress(previous).Start); foreach (var address in addresses.Skip(1)) { var offset = address > previous ? (long)(address - previous) : -(long)(previous - address); segments.Add(heap.GetSegmentByAddress(address).Start); offsetCounts[offset] = offsetCounts.TryGetValue(offset, out var count) ? count + 1 : 1; previous = address; } Console.WriteLine($"Segments count: {segments.Count}"); var sortedOffsetCounts = offsetCounts.Select(x => (offset: x.Key, count: x.Value, absOffset: Math.Abs(x.Key))).OrderBy(x => x.absOffset).ToList(); foreach (var offsetCount in sortedOffsetCounts.Take(5)) { Console.WriteLine($"Offset: {offsetCount.offset} Count: {offsetCount.count}"); } var remainingOffsets = sortedOffsetCounts.Skip(5).ToList(); if (remainingOffsets.Count != 0) { var eventsCount = remainingOffsets.Sum(x => x.count); var maxOffset = remainingOffsets.Max(x => x.absOffset); var averageOffset = (long)remainingOffsets.Average(x => x.absOffset); Console.WriteLine($"{remainingOffsets.Count} remaining offsets for {eventsCount} events, max: {maxOffset}, avg: {averageOffset}"); } }
public static object GetSimpleValue(ClrObject obj) { ClrType type = obj.Type; ClrHeap heap = type.Heap; if (type.IsPrimitive || type.IsString) { return(type.GetValue(obj.Address)); } ulong address = obj.IsInterior ? obj.Address : obj.Address + (ulong)heap.PointerSize; switch (type.Name) { case GuidTypeName: { byte[] buffer = ReadBuffer(heap, address, 16); return(new Guid(buffer)); } case TimeSpanTypeName: { byte[] buffer = ReadBuffer(heap, address, 8); long ticks = BitConverter.ToInt64(buffer, 0); return(new TimeSpan(ticks)); } case DateTimeTypeName: { byte[] buffer = ReadBuffer(heap, address, 8); ulong dateData = BitConverter.ToUInt64(buffer, 0); return(GetDateTime(dateData)); } case IPAddressTypeName: { return(GetIPAddress(obj)); } } throw new InvalidOperationException(string.Format("SimpleValue not available for type '{0}'", type.Name)); }
private static void OnGetMethodName(IntPtr client, string args) { // Must be the first thing in our extension. if (!InitApi(client)) { return; } // Use ClrMD as normal, but ONLY cache the copy of ClrRuntime (this.Runtime). All other // types you get out of ClrMD (such as ClrHeap, ClrTypes, etc) should be discarded and // reobtained every run. ClrHeap heap = Runtime.Heap; // Console.WriteLine now writes to the debugger. ClrMDHelper helper = new ClrMDHelper(Runtime); try { ulong methodPtr; if (!ulong.TryParse(args.Trim(), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out methodPtr)) { Console.WriteLine("numeric value expected as method pointer"); return; } ClrMethod method = Runtime.GetMethodByAddress(methodPtr); if (method != null) { Console.WriteLine($"{method.Type.Name}.{method.Name}"); } else { Console.WriteLine("invalid method pointer."); } } catch (Exception x) { Console.WriteLine(x.Message); } }
public void VariableRootTest() { // Test to make sure that a specific static and local variable exist. using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.Heap; heap.StackwalkPolicy = ClrRootStackwalkPolicy.Exact; var fooRoots = from root in heap.EnumerateRoots() where root.Type.Name == "Foo" select root; ClrRoot staticRoot = fooRoots.Where(r => r.Kind == GCRootKind.StaticVar).Single(); Assert.Contains("s_foo", staticRoot.Name); var arr = fooRoots.Where(r => r.Kind == GCRootKind.LocalVar).ToArray(); ClrRoot[] localVarRoots = fooRoots.Where(r => r.Kind == GCRootKind.LocalVar).ToArray(); ClrThread thread = runtime.GetMainThread(); ClrStackFrame main = thread.GetFrame("Main"); ClrStackFrame inner = thread.GetFrame("Inner"); ulong low = thread.StackBase; ulong high = thread.StackLimit; // Account for different platform stack direction. if (low > high) { ulong tmp = low; low = high; high = tmp; } foreach (ClrRoot localVarRoot in localVarRoots) { Assert.True(low <= localVarRoot.Address && localVarRoot.Address <= high); } } }
private static void CheckSegments(ClrHeap heap) { foreach (ClrSegment seg in heap.Segments) { Assert.AreNotEqual(0ul, seg.Start); Assert.AreNotEqual(0ul, seg.End); Assert.IsTrue(seg.Start <= seg.End); Assert.IsTrue(seg.Start < seg.CommittedEnd); Assert.IsTrue(seg.CommittedEnd < seg.ReservedEnd); if (!seg.IsEphemeral) { Assert.AreEqual(0ul, seg.Gen0Length); Assert.AreEqual(0ul, seg.Gen1Length); } foreach (ulong obj in seg.EnumerateObjectAddresses()) { ClrSegment curr = heap.GetSegmentByAddress(obj); Assert.AreSame(seg, curr); } } }
public NativeStaticRootWalker(NativeRuntime runtime, bool resolveStatics) { Roots = new List<ClrRoot>(128); _runtime = resolveStatics ? runtime : null; _heap = _runtime.GetHeap(); }
public NativeHandleRootWalker(NativeRuntime runtime, bool dependentHandleSupport) { _heap = runtime.GetHeap(); _domain = runtime.GetRhAppDomain(); _dependentSupport = dependentHandleSupport; }
public RhHandleRootWalker(RhRuntime runtime, bool dependentHandleSupport) { m_heap = runtime.GetHeap(); m_domain = runtime.GetRhAppDomain(); m_dependentSupport = dependentHandleSupport; }
public RhStaticRootWalker(RhRuntime runtime, bool resolveStatics) { Roots = new List<ClrRoot>(128); m_runtime = resolveStatics ? runtime : null; m_heap = m_runtime.GetHeap(); }
public HandleTableWalker(DesktopRuntimeBase dac) { m_runtime = dac; m_heap = dac.GetHeap(); Handles = new List<ClrHandle>(); }
private IEnumerable<ulong> EnumerateManagedThreadpoolObjects() { m_heap = m_runtime.GetHeap(); ClrModule mscorlib = GetMscorlib(); if (mscorlib != null) { ClrType queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolGlobals"); if (queueType != null) { ClrStaticField workQueueField = queueType.GetStaticFieldByName("workQueue"); if (workQueueField != null) { foreach (var appDomain in m_runtime.AppDomains) { ulong workQueue = (ulong)workQueueField.GetValue(appDomain); ClrType workQueueType = m_heap.GetObjectType(workQueue); if (workQueue == 0 || workQueueType == null) continue; ulong queueHead; ClrType queueHeadType; do { if (!GetFieldObject(workQueueType, workQueue, "queueHead", out queueHeadType, out queueHead)) break; ulong nodes; ClrType nodesType; if (GetFieldObject(queueHeadType, queueHead, "nodes", out nodesType, out nodes) && nodesType.IsArray) { int len = nodesType.GetArrayLength(nodes); for (int i = 0; i < len; ++i) { ulong addr = (ulong)nodesType.GetArrayElementValue(nodes, i); if (addr != 0) yield return addr; } } if (!GetFieldObject(queueHeadType, queueHead, "Next", out queueHeadType, out queueHead)) break; } while (queueHead != 0); } } } queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolWorkQueue"); if (queueType != null) { ClrStaticField threadQueuesField = queueType.GetStaticFieldByName("allThreadQueues"); if (threadQueuesField != null) { foreach (ClrAppDomain domain in m_runtime.AppDomains) { ulong threadQueue = (ulong)threadQueuesField.GetValue(domain); if (threadQueue == 0) continue; ClrType threadQueueType = m_heap.GetObjectType(threadQueue); if (threadQueueType == null) continue; ulong outerArray = 0; ClrType outerArrayType = null; if (!GetFieldObject(threadQueueType, threadQueue, "m_array", out outerArrayType, out outerArray) || !outerArrayType.IsArray) continue; int outerLen = outerArrayType.GetArrayLength(outerArray); for (int i = 0; i < outerLen; ++i) { ulong entry = (ulong)outerArrayType.GetArrayElementValue(outerArray, i); if (entry == 0) continue; ClrType entryType = m_heap.GetObjectType(entry); if (entryType == null) continue; ulong array; ClrType arrayType; if (!GetFieldObject(entryType, entry, "m_array", out arrayType, out array) || !arrayType.IsArray) continue; int len = arrayType.GetArrayLength(array); for (int j = 0; j < len; ++j) { ulong addr = (ulong)arrayType.GetArrayElementValue(array, i); if (addr != 0) yield return addr; } } } } } } }
private ClrType TryBuildType(ClrHeap heap) { var runtime = heap.GetRuntime(); var domains = runtime.AppDomains; ClrType[] types = new ClrType[domains.Count]; ClrElementType elType = ElementType; if (ClrRuntime.IsPrimitive(elType) || elType == ClrElementType.String) return ((DesktopGCHeap)heap).GetBasicType(elType); int count = 0; foreach (var domain in domains) { object value = GetValue(domain); if (value != null && value is ulong && ((ulong)value != 0)) { types[count++] = heap.GetObjectType((ulong)value); } } int depth = int.MaxValue; ClrType result = null; for (int i = 0; i < count; ++i) { ClrType curr = types[i]; if (curr == result || curr == null) continue; int nextDepth = GetDepth(curr); if (nextDepth < depth) { result = curr; depth = nextDepth; } } return result; }
private Dictionary<int, string> GetManagedThreadNames(ClrHeap heap) { var result = new Dictionary<int, string>(); if (!heap.CanWalkHeap) return result; var threadObjects = from obj in heap.EnumerateObjectAddresses() let type = heap.GetObjectType(obj) where type != null && type.Name == "System.Threading.Thread" select obj; var threadType = heap.GetTypeByName("System.Threading.Thread"); var nameField = threadType.GetFieldByName("m_Name"); var managedIdField = threadType.GetFieldByName("m_ManagedThreadId"); foreach (var threadObject in threadObjects) { string name = (string)nameField.GetValue(threadObject); int id = (int)managedIdField.GetValue(threadObject); result.Add(id, name); } return result; }