private static IEnumerable<Tuple<ulong, ClrType>> EnumerateFromObjectSet(ClrHeap heap, IEnumerable<ulong> objects)
        {
            var toGoThrough = new Stack<ulong>(objects);
            var seen = new ObjectSet(heap);

            while (toGoThrough.Count > 0)
            {
                var obj = toGoThrough.Pop();
                if (seen.Contains(obj))
                    continue;

                seen.Add(obj);

                var type = heap.GetObjectType(obj);
                if (type == null || type.IsFree || String.IsNullOrEmpty(type.Name))
                    continue;

                yield return new Tuple<ulong, ClrType>(obj, type);

                type.EnumerateRefsOfObject(obj, (child, _) =>
                {
                    if (child != 0 && !seen.Contains(child))
                    {
                        toGoThrough.Push(child);
                    }
                });
            }
        }
Exemple #2
0
        public void Execute(CommandExecutionContext context)
        {
            _context = context;

            if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress))
                return;

            _heap = context.Heap;
            if (!_heap.CanWalkHeap)
            {
                context.WriteErrorLine("The heap is not in a walkable state.");
                return;
            }

            var type = _heap.GetObjectType(ObjectAddress);

            _visitedObjects = new ObjectSet(_heap);
            _targets[ObjectAddress] = new Node(ObjectAddress, type);
            FillRootDictionary();

            foreach (var root in _roots)
            {
                if (_visitedRoots.Contains(root) || _visitedObjects.Contains(root.Object))
                    continue;

                Node path = TryFindPathToTarget(root);
                if (path != null)
                    PrintOnePath(path);
            }
        }
Exemple #3
0
 protected RootPathFinder(HeapIndex index, ulong targetObject)
 {
     Index = index;
     TargetObject = targetObject;
     Visited = new ObjectSet(Index._heap);
 }
Exemple #4
0
        private void BuildChunkIndex()
        {
            var seen = new ObjectSet(_heap);
            var evalStack = new Stack<ulong>();
            foreach (var root in _heap.EnumerateRoots(enumerateStatics: false))
            {
                evalStack.Push(root.Object);
                _directlyRooted.Add(root.Object);
            }
            while (evalStack.Count > 0)
            {
                ulong parent = evalStack.Pop();
                if (seen.Contains(parent))
                    continue;

                seen.Add(parent);

                var type = _heap.GetObjectType(parent);
                if (type == null || type.IsFree || String.IsNullOrEmpty(type.Name))
                    continue;

                type.EnumerateRefsOfObject(parent, (child, _) =>
                {
                    // Due to possibly a corruption or a bug in ClrMD, the inner fields might
                    // occasionally fall outside of the heap, or point to objects whose type
                    // cannot be obtained. We don't have a choice but to ignore these.
                    if (_heap.GetObjectType(child) == null)
                        return;

                    int childChunk = ChunkIdForObject(child);
                    int parentChunk = ChunkIdForObject(parent);
                    HashSet<int> referencingChunks;
                    if (!_tempChunkToReferencingChunks.TryGetValue(childChunk, out referencingChunks))
                    {
                        referencingChunks = new HashSet<int>();
                        _tempChunkToReferencingChunks.Add(childChunk, referencingChunks);
                    }
                    referencingChunks.Add(parentChunk);

                    if (child != 0 && !seen.Contains(child))
                    {
                        evalStack.Push(child);
                    }
                });
            }

            _context.WriteLine("Average referencing chunks per chunk: {0:N}",
                (from list in _tempChunkToReferencingChunks.Values select list.Count).Average());
            _context.WriteLine("Max referencing chunks per chunk:     {0}",
                (from list in _tempChunkToReferencingChunks.Values select list.Count).Max());
            _context.WriteLine("Min referencing chunks per chunk:     {0}",
                (from list in _tempChunkToReferencingChunks.Values select list.Count).Min());
            _context.WriteLine("Objects with missing chunk ids:       {0}", _objectsWithMissingChunkIds);

            // Convert to a more compact representation for in-memory use and serialization.
            foreach (var kvp in _tempChunkToReferencingChunks)
            {
                _chunkToReferencingChunks.Add(kvp.Key, kvp.Value.ToArray());
            }
            _tempChunkToReferencingChunks.Clear();
        }
Exemple #5
0
        private void BuildChunkIndex()
        {
            var seen      = new ObjectSet(_heap);
            var evalStack = new Stack <ulong>();

            foreach (var root in _heap.EnumerateRoots(enumerateStatics: false))
            {
                evalStack.Push(root.Object);
                _directlyRooted.Add(root.Object);
            }
            while (evalStack.Count > 0)
            {
                ulong parent = evalStack.Pop();
                if (seen.Contains(parent))
                {
                    continue;
                }

                seen.Add(parent);

                var type = _heap.GetObjectType(parent);
                if (type == null || type.IsFree || String.IsNullOrEmpty(type.Name))
                {
                    continue;
                }

                type.EnumerateRefsOfObject(parent, (child, _) =>
                {
                    // Due to possibly a corruption or a bug in ClrMD, the inner fields might
                    // occasionally fall outside of the heap, or point to objects whose type
                    // cannot be obtained. We don't have a choice but to ignore these.
                    if (_heap.GetObjectType(child) == null)
                    {
                        return;
                    }

                    int childChunk  = ChunkIdForObject(child);
                    int parentChunk = ChunkIdForObject(parent);
                    HashSet <int> referencingChunks;
                    if (!_tempChunkToReferencingChunks.TryGetValue(childChunk, out referencingChunks))
                    {
                        referencingChunks = new HashSet <int>();
                        _tempChunkToReferencingChunks.Add(childChunk, referencingChunks);
                    }
                    referencingChunks.Add(parentChunk);

                    if (child != 0 && !seen.Contains(child))
                    {
                        evalStack.Push(child);
                    }
                });
            }

            _context.WriteLine("Average referencing chunks per chunk: {0:N}",
                               (from list in _tempChunkToReferencingChunks.Values select list.Count).Average());
            _context.WriteLine("Max referencing chunks per chunk:     {0}",
                               (from list in _tempChunkToReferencingChunks.Values select list.Count).Max());
            _context.WriteLine("Min referencing chunks per chunk:     {0}",
                               (from list in _tempChunkToReferencingChunks.Values select list.Count).Min());
            _context.WriteLine("Objects with missing chunk ids:       {0}", _objectsWithMissingChunkIds);

            // Convert to a more compact representation for in-memory use and serialization.
            foreach (var kvp in _tempChunkToReferencingChunks)
            {
                _chunkToReferencingChunks.Add(kvp.Key, kvp.Value.ToArray());
            }
            _tempChunkToReferencingChunks.Clear();
        }
Exemple #6
0
 protected RootPathFinder(HeapIndex index, ulong targetObject)
 {
     Index        = index;
     TargetObject = targetObject;
     Visited      = new ObjectSet(Index._heap);
 }