private ReferrerTreeNode CreateGCRootNode(RootGraphNode node)
        {
            return(new ReferrerTreeNode(this, new[] { node }, null, node.ClrRoot.Name, null, null, -1, null, false, true, GetNodeType()));

            ReferrerTreeNodeType GetNodeType()
            {
                switch (node.ClrRoot.Kind)
                {
                case GCRootKind.StaticVar:       return(ReferrerTreeNodeType.StaticVar);          // "static var StringTheory.SampleApp.Program.E"

                case GCRootKind.ThreadStaticVar: return(ReferrerTreeNodeType.ThreadStaticVar);

                case GCRootKind.Pinning:         return(ReferrerTreeNodeType.Pinning);            // "Pinned handle"

                case GCRootKind.AsyncPinning:    return(ReferrerTreeNodeType.AsyncPinning);

                case GCRootKind.LocalVar:        return(ReferrerTreeNodeType.LocalVar);

                case GCRootKind.Strong:          return(ReferrerTreeNodeType.StrongHandle);       // "Strong handle"

                case GCRootKind.Weak:            return(ReferrerTreeNodeType.WeakHandle);

                case GCRootKind.Finalizer:       return(ReferrerTreeNodeType.Finalizer);

                default: throw new ArgumentOutOfRangeException();
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Traverse the canvas and evaluate it
        /// </summary>
        public override void TraverseAll()
        {
            RootGraphNode rootNode = Canvas.rootNode;

            rootNode.Calculate();
            //Debug.Log ("RootNode is " + rootNode);
        }
Exemplo n.º 3
0
        public static ReferenceGraph Build(ClrHeap heap, HashSet <ulong> targetAddresses, CancellationToken token = default)
        {
            var graph = new ReferenceGraph();

            var seen = new ObjectSet(heap);

            var stack = new HeapWalkStack();

            var nodeByAddress = new Dictionary <ulong, ReferenceGraphNode>();

            var chainCache = new Dictionary <(uint metadataToken, int fieldOffset), List <FieldReference> >();

            // For each root
            foreach (var root in heap.EnumerateRoots(enumerateStatics: true))
            {
                stack.Clear();

                if (root.Type == null)
                {
                    // This happens, though not sure why
                    continue;
                }

                stack.Push(new ClrObjectReference(-1, root.Object, root.Type));

                while (!stack.IsEmpty)
                {
                    token.ThrowIfCancellationRequested();

                    ref var top = ref stack.Peek();

                    if (top.Enumerator.MoveNext())
                    {
                        var o = top.Enumerator.Current;

                        if (targetAddresses.Contains(o.Address))
                        {
                            // Found a match
                            stack.Push(o);

                            // Ensure our stack's root is registered with the graph
                            ref var rootLevel = ref stack[0];
                            if (rootLevel.GraphNode == null)
                            {
                                var rootNode = new RootGraphNode(root);
                                nodeByAddress[root.Object] = rootNode;
                                rootLevel.GraphNode        = rootNode;
                                graph.Roots.Add(rootNode);
                            }

                            // Build path through graph for the current stack
                            // Skip the first node as it's always non-null
                            for (var i = 1; i < stack.Count; i++)
                            {
                                ref var level = ref stack[i];

                                // Ensure all levels have a graph node object
                                if (level.GraphNode == null)
                                {
                                    if (!nodeByAddress.TryGetValue(level.Reference.Address, out var node))
                                    {
                                        node = new ReferenceGraphNode(level.Reference.Object);
                                        nodeByAddress[level.Reference.Address] = node;

                                        if (i == stack.Count - 1)
                                        {
                                            graph.TargetSet.Add(node);
                                        }
                                    }

                                    level.GraphNode = node;

                                    ref var levelBefore = ref stack[i - 1];

                                    var referenceChain = GetChain(levelBefore.GraphNode.Object.Type, level.Reference);

                                    level.GraphNode.Referrers.Add((node: levelBefore.GraphNode, referenceChain, fieldOffset: level.Reference.FieldOffset));
//                                    levelBefore.GraphNode.References.Add((node: level.GraphNode, referenceChain));
                                }
                            }

                            stack.Pop();
                        }