public static EditorWindow CreateWindow(PackedMemorySnapshot snapshot, AbstractMemoryReader memoryReader, System.UInt64 address, PackedManagedType type)
        {
            var visualizer = AbstractDataVisualizer.CreateVisualizer(type.name);

            if (visualizer == null)
            {
                Debug.LogWarningFormat("Could not create DataVisualizer for type '{0}'", type.name);
                return(null);
            }
            visualizer.Initialize(snapshot, memoryReader, address, type);

            var window = DataVisualizerWindow.CreateInstance <DataVisualizerWindow>();

            window.SetVisualizer(visualizer);
            window.ShowUtility();
            return(window);
        }
Example #2
0
            public void Initialize(ManagedHeapSectionsControl owner, PackedMemorySnapshot snapshot, int memorySegmentIndex)
            {
                m_Owner    = owner;
                m_Snapshot = snapshot;
                arrayIndex = memorySegmentIndex;

                displayName = "MemorySection";
                address     = m_Snapshot.managedHeapSections[arrayIndex].startAddress;
                if (m_Snapshot.managedHeapSections[arrayIndex].bytes != null)
                {
                    size = (ulong)m_Snapshot.managedHeapSections[arrayIndex].bytes.LongLength;

#if HEAPEXPLORER_DISPLAY_REFS
                    m_Snapshot.GetConnectionsCount(m_Snapshot.managedHeapSections[arrayIndex], out refs);
#endif
                }
            }
        // this method is a hack that excludes native object connections to workaround an unity bug.
        // https://forum.unity.com/threads/wip-heap-explorer-memory-profiler-debugger-and-analyzer-for-unity.527949/page-2#post-3615223
        static PackedConnection[] ConnectionsFromMemoryProfilerWithoutNativeHACK(PackedMemorySnapshot snapshot, UnityEditor.MemoryProfiler.PackedMemorySnapshot source)
        {
            var managedStart = 0;
            var managedEnd   = managedStart + source.gcHandles.Length;
            var nativeStart  = managedStart + managedEnd;
            var nativeEnd    = nativeStart + source.nativeObjects.Length;
            var output       = new List <PackedConnection>(1024 * 1024);

            for (int n = 0, nend = source.connections.Length; n < nend; ++n)
            {
                if ((n % (nend / 100)) == 0)
                {
                    var progress = ((n + 1.0f) / nend) * 100;
                    snapshot.busyString = string.Format("Analyzing GCHandle Connections\n{0}/{1}, {2:F0}% done", n + 1, source.connections.Length, progress);
                }

                var connection = new PackedConnection
                {
                    from = source.connections[n].from,
                    to   = source.connections[n].to,
                };

                connection.fromKind = PackedConnection.Kind.GCHandle;
                if (connection.from >= nativeStart && connection.from < nativeEnd)
                {
                    connection.from    -= nativeStart;
                    connection.fromKind = PackedConnection.Kind.Native;
                }

                connection.toKind = PackedConnection.Kind.GCHandle;
                if (connection.to >= nativeStart && connection.to < nativeEnd)
                {
                    connection.to    -= nativeStart;
                    connection.toKind = PackedConnection.Kind.Native;
                }

                if (connection.fromKind != PackedConnection.Kind.Native)
                {
                    output.Add(connection);
                }
            }

            snapshot.header.nativeObjectFromConnectionsExcluded = true;
            Debug.LogWarning("HeapExplorer: Native object 'from' connections are excluded due workaround an Unity bug. Thus the object connections in Heap Explorer show fewer connections than actually exist.\nhttps://forum.unity.com/threads/wip-heap-explorer-memory-profiler-debugger-and-analyzer-for-unity.527949/page-2#post-3615223");
            return(output.ToArray());
        }
Example #4
0
        public static GUIContent GetTypeContent(PackedMemorySnapshot snapshot, PackedManagedType type)
        {
            const string valueTypeLabel     = "Value types are either stack-allocated or allocated inline in a structure.";
            const string referenceTypeLabel = "Reference types are heap-allocated.";

            if (type.isValueType)
            {
                if (snapshot.IsSubclassOf(type, snapshot.coreTypes.systemEnum))
                {
                    return(new GUIContent(csEnumTypeImage, valueTypeLabel));
                }

                return(new GUIContent(csValueTypeImage, valueTypeLabel));
            }

            return(new GUIContent(csReferenceTypeImage, referenceTypeLabel));
        }
Example #5
0
        void ReceiveHeapThreaded(object userData)
        {
            var args = new MemorySnapshotProcessingArgs();

            args.source = userData as UnityEditor.Profiling.Memory.Experimental.PackedMemorySnapshot;

            try
            {
                m_Heap = PackedMemorySnapshot.FromMemoryProfiler(args);
                m_Heap.Initialize();
            }
            catch
            {
                m_CloseDueToError = true;
                throw;
            }
        }
Example #6
0
        void InspectInternal(PackedMemorySnapshot snapshot, PackedManagedObject managedObject)
        {
            m_Snapshot      = snapshot;
            m_ManagedObject = managedObject;
            if (m_ManagedObject.address == 0)
            {
                m_ErrorString = "Cannot inspect 'null' address.";
                return;
            }


            var type = m_Snapshot.managedTypes[managedObject.managedTypesArrayIndex];

            titleContent   = new GUIContent(string.Format("C# Object Inspector | {0} | {1:X}", type.name, managedObject.address));
            m_PropertyGrid = new PropertyGridControl(null, "ManagedObjectInspectorWindow.m_propertyGrid", new TreeViewState());
            m_PropertyGrid.Inspect(m_Snapshot, managedObject);
            m_ErrorString = "";
        }
Example #7
0
        void ReceiveHeapThreaded(object userData)
        {
            var args = new MemorySnapshotProcessingArgs();

            args.source = userData as UnityEditor.MemoryProfiler.PackedMemorySnapshot;
            args.excludeNativeFromConnections = excludeNativeFromConnections;

            try
            {
                m_Heap = PackedMemorySnapshot.FromMemoryProfiler(args);
                m_Heap.Initialize();
            }
            catch
            {
                m_CloseDueToError = true;
                throw;
            }
        }
Example #8
0
        public TreeViewItem BuildTree(PackedMemorySnapshot snapshot)
        {
            m_Snapshot           = snapshot;
            m_UniqueId           = 1;
            m_ManagedObjectCount = 0;
            m_ManagedObjectSize  = 0;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null || m_Snapshot.managedObjects == null || m_Snapshot.managedObjects.Length == 0)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            OnBeforeBuildTree();
            OnBuildTree(root);

            // remove groups if it contains one item only
            if (root.hasChildren)
            {
                for (int n = root.children.Count - 1; n >= 0; --n)
                {
                    var group = root.children[n];
                    if (group.children.Count == 1)
                    {
                        group.children[0].depth -= 1;
                        root.AddChild(group.children[0]);
                        root.children.RemoveAt(n);
                        continue;
                    }
                }
            }

            SortItemsRecursive(root, OnSortItem);

            return(root);
        }
        /// <summary>
        /// Converts an Unity PackedMemorySnapshot to our own format.
        /// </summary>
        public static PackedMemorySnapshot FromMemoryProfiler(MemorySnapshotProcessingArgs args)
        {
            var source = args.source;

            var value = new PackedMemorySnapshot();

            try
            {
                VerifyMemoryProfilerSnapshot(source);

                value.busyString = "Loading Header";
                value.header     = PackedMemorySnapshotHeader.FromMemoryProfiler();

                value.busyString  = string.Format("Loading {0} Native Types", source.nativeTypes.GetNumEntries());
                value.nativeTypes = PackedNativeType.FromMemoryProfiler(source);

                value.busyString    = string.Format("Loading {0} Native Objects", source.nativeObjects.GetNumEntries());
                value.nativeObjects = PackedNativeUnityEngineObject.FromMemoryProfiler(source);

                value.busyString = string.Format("Loading {0} GC Handles", source.gcHandles.GetNumEntries());
                value.gcHandles  = PackedGCHandle.FromMemoryProfiler(source);

                value.busyString  = string.Format("Loading {0} Object Connections", source.connections.GetNumEntries());
                value.connections = PackedConnection.FromMemoryProfiler(source);

                value.busyString          = string.Format("Loading {0} Managed Heap Sections", source.managedHeapSections.GetNumEntries());
                value.managedHeapSections = PackedMemorySection.FromMemoryProfiler(source);

                value.busyString   = string.Format("Loading {0} Managed Types", source.typeDescriptions.GetNumEntries());
                value.managedTypes = PackedManagedType.FromMemoryProfiler(source);

                value.busyString = "Loading VM Information";
                value.virtualMachineInformation = PackedVirtualMachineInformation.FromMemoryProfiler(source);
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);
                value = null;
                throw;
            }
            return(value);
        }
Example #10
0
        public void Inspect(PackedMemorySnapshot memory, System.UInt64 address, System.UInt64 size)
        {
            m_Segment = new ArraySegment64 <byte>();
            if (address == 0)
            {
                return;
            }

            var heapIndex = memory.FindHeapOfAddress(address);

            if (heapIndex < 0)
            {
                return;
            }

            var heap    = memory.managedHeapSections[heapIndex];
            var segment = new ArraySegment64 <byte>(heap.bytes, address - heap.startAddress, size);

            Inspect(memory, address, segment);
        }
Example #11
0
        public void Inspect(PackedMemorySnapshot snapshot, PackedManagedObject managedObject)
        {
            m_Snapshot = snapshot;
            var m_type    = snapshot.managedTypes[managedObject.managedTypesArrayIndex];
            var m_address = managedObject.address;

            if (m_type.isValueType)
            {
                m_address -= (ulong)m_Snapshot.virtualMachineInformation.objectHeaderSize;
            }

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return;
            }

            var args = new PropertyGridItem.BuildChildrenArgs();

            args.parent       = root;
            args.type         = m_type;
            args.address      = m_address;
            args.memoryReader = new MemoryReader(snapshot);

            AddType(args);

            // add at least one item to the tree, otherwise it outputs an error
            if (!root.hasChildren)
            {
                root.AddChild(new TreeViewItem(1, 0, ""));
            }

            SetTree(root);
            TryCreateDataVisualizer(args.memoryReader, args.type, args.address, false);
        }
        public TreeViewItem BuildTree(PackedMemorySnapshot snapshot)
        {
            m_Snapshot = snapshot;
            m_UniqueId = 1;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            for (int n = 0, nend = m_Snapshot.managedStaticTypes.Length; n < nend; ++n)
            {
                if (window.isClosing) // the window is closing
                {
                    break;
                }

                var type = m_Snapshot.managedTypes[m_Snapshot.managedStaticTypes[n]];

                var group = new StaticTypeItem
                {
                    id          = m_UniqueId++,
                    depth       = 0,
                    displayName = ""
                };
                group.Initialize(this, m_Snapshot, type);

                root.AddChild(group);
            }

            return(root);
        }
        public static void GetInheritanceAsString(PackedMemorySnapshot snapshot, int managedTypesArrayIndex, System.Text.StringBuilder target)
        {
            var depth     = 0;
            var loopguard = 0;

            while (managedTypesArrayIndex != -1)
            {
                for (var n = 0; n < depth; ++n)
                {
                    target.Append("  ");
                }

                target.AppendFormat("{0}\n", snapshot.managedTypes[managedTypesArrayIndex].name);
                depth++;

                managedTypesArrayIndex = snapshot.managedTypes[managedTypesArrayIndex].baseOrElementTypeIndex;
                if (++loopguard > 64)
                {
                    break;
                }
            }
        }
        //public TreeViewItem BuildTree(PackedMemorySnapshot snapshot, bool removeUnalignedSections = false)
        public TreeViewItem BuildTree(PackedMemorySnapshot snapshot, PackedMemorySection[] sections)
        {
            m_Snapshot = snapshot;
            m_UniqueId = 1;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            for (int n = 0, nend = sections.Length; n < nend; ++n)
            {
                if (window.isClosing) // the window is closing
                {
                    break;
                }

                var section = sections[n];

                var item = new HeapSectionItem()
                {
                    id    = m_UniqueId++,
                    depth = root.depth + 1,
                };

                item.Initialize(this, m_Snapshot, section.arrayIndex);
                root.AddChild(item);
            }

            return(root);
        }
Example #15
0
        public void LoadFromFile(string path)
        {
            SaveView();
            FreeMem();
            HeMruFiles.AddPath(path);
            Reset();
            m_Heap = null;

            if (useThreads)
            {
                var job = new LoadThreadJob
                {
                    path       = path,
                    threadFunc = LoadFromFileThreaded
                };

                ScheduleJob(job);
            }
            else
            {
                LoadFromFileThreaded(path);
            }
        }
Example #16
0
        public void Show(PackedMemorySnapshot heap)
        {
            if (snapshot != heap)
            {
                if (snapshot != null && isVisible)
                {
                    Hide(); // Hide normally implements to save the layout of various UI elements
                }
                snapshot = heap;
                OnCreate();
            }

            OnShow();

            // Show any views that might have been added during OnShow()
            foreach (var v in m_Views)
            {
                v.Show(heap);
            }

            isVisible = true;
            Repaint();
        }
        public TreeViewItem BuildTree(PackedMemorySnapshot snapshotA, PackedMemorySnapshot snapshotB)
        {
            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (snapshotA == null || snapshotB == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            var uniqueId  = 1;
            var snapshots = new[] { snapshotA, snapshotB };

            BuildNativeTree(snapshots, ref uniqueId, root);
            BuildManagedTree(snapshots, ref uniqueId, root);
            BuildMemoryTree(snapshots, ref uniqueId, root);
            BuildGCHandleTree(snapshots, ref uniqueId, root);

            return(root);
        }
Example #18
0
        public TreeViewItem BuildTree(PackedMemorySnapshot snapshot)
        {
            m_Snapshot = snapshot;
            m_UniqueId = 1;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            for (int n = 0, nend = m_Snapshot.managedStaticTypes.Length; n < nend; ++n)
            {
                var type = m_Snapshot.managedTypes[m_Snapshot.managedStaticTypes[n]];

                var group = new StaticTypeItem
                {
                    id          = m_UniqueId++,
                    depth       = 0,
                    displayName = ""
                };
                group.Initialize(this, m_Snapshot, type);

                root.AddChild(group);
            }

            SortItemsRecursive(root, OnSortItem);

            return(root);
        }
Example #19
0
        public void InspectStaticType(PackedMemorySnapshot snapshot, PackedManagedType managedType)
        {
            m_Snapshot = snapshot;
            var m_type    = managedType;
            var m_address = 0ul;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return;
            }

            var args = new PropertyGridItem.BuildChildrenArgs();

            args.parent       = root;
            args.type         = m_type;
            args.address      = m_address;
            args.memoryReader = new StaticMemoryReader(snapshot, managedType.staticFieldBytes);

            AddType(args);

            // add at least one item to the tree, otherwise it outputs an error
            if (!root.hasChildren)
            {
                root.AddChild(new TreeViewItem(1, 0, ""));
            }

            SetTree(root);
            TryCreateDataVisualizer(args.memoryReader, args.type, args.address, false);
        }
Example #20
0
        public static Texture2D GetTypeImage(PackedMemorySnapshot snapshot, PackedManagedType type)
        {
            if (type.isArray)
            {
                return(csReferenceTypeImage);
            }

            if (type.isValueType)
            {
                if (snapshot.IsSubclassOf(type, snapshot.coreTypes.systemEnum))
                {
                    return(csEnumTypeImage);
                }

                return(csValueTypeImage);
            }

            if (snapshot.IsSubclassOf(type, snapshot.coreTypes.systemDelegate))
            {
                return(csDelegateTypeImage);
            }

            return(csReferenceTypeImage);
        }
Example #21
0
            public void Initialize(ConnectionsControl owner, PackedMemorySnapshot snapshot, PackedNativeUnityEngineObject nativeObject)
            {
                m_Owner        = owner;
                m_Snapshot     = snapshot;
                m_NativeObject = new RichNativeObject(snapshot, nativeObject.nativeObjectsArrayIndex);

                m_Value     = m_NativeObject.name;
                address     = m_NativeObject.address;
                displayName = m_NativeObject.type.name;

                // If it's a MonoBehaviour or ScriptableObject, use the C# typename instead
                // It makes it easier to understand what it is, otherwise everything displays 'MonoBehaviour' only.
                if (m_NativeObject.type.IsSubclassOf(m_Snapshot.coreTypes.nativeMonoBehaviour) || m_NativeObject.type.IsSubclassOf(m_Snapshot.coreTypes.nativeScriptableObject))
                {
                    string monoScriptName;
                    if (m_Snapshot.FindNativeMonoScriptType(m_NativeObject.packed.nativeObjectsArrayIndex, out monoScriptName) != -1)
                    {
                        if (!string.IsNullOrEmpty(monoScriptName))
                        {
                            displayName = monoScriptName;
                        }
                    }
                }
            }
Example #22
0
 public void Initialize(PackedMemorySnapshot snapshot, int managedTypesArrayIndex)
 {
     m_Type = new RichManagedType(snapshot, managedTypesArrayIndex);
 }
Example #23
0
 public void Initialize(GCHandlesControl owner, PackedMemorySnapshot snapshot, int gcHandlesArrayIndex)
 {
     m_Owner    = owner;
     m_GCHandle = new RichGCHandle(snapshot, gcHandlesArrayIndex);
 }
Example #24
0
        public TreeViewItem BuildTree(PackedMemorySnapshot snapshot)
        {
            m_Snapshot = snapshot;
            m_UniqueId = 1;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            // int=typeIndex
            var groupLookup = new Dictionary <int, GroupItem>();

            for (int n = 0, nend = m_Snapshot.gcHandles.Length; n < nend; ++n)
            {
                var gcHandle         = m_Snapshot.gcHandles[n];
                var managedTypeIndex = -1;
                if (gcHandle.managedObjectsArrayIndex >= 0)
                {
                    managedTypeIndex = m_Snapshot.managedObjects[gcHandle.managedObjectsArrayIndex].managedTypesArrayIndex;
                }

                var targetItem = root;
                if (managedTypeIndex >= 0)
                {
                    GroupItem group;
                    if (!groupLookup.TryGetValue(managedTypeIndex, out group))
                    {
                        group = new GroupItem
                        {
                            id          = m_UniqueId++,
                            depth       = 0,
                            displayName = ""
                        };
                        group.Initialize(m_Snapshot, managedTypeIndex);

                        groupLookup[managedTypeIndex] = group;
                        root.AddChild(group);
                    }

                    targetItem = group;
                }

                var item = new GCHandleItem
                {
                    id          = m_UniqueId++,
                    depth       = targetItem.depth + 1,
                    displayName = ""
                };
                item.Initialize(this, m_Snapshot, gcHandle.gcHandlesArrayIndex);

                targetItem.AddChild(item);
            }

            // remove groups if it contains one item only
            for (int n = root.children.Count - 1; n >= 0; --n)
            {
                var group = root.children[n];
                if (group.hasChildren && group.children.Count == 1)
                {
                    group.children[0].depth -= 1;
                    root.AddChild(group.children[0]);
                    root.children.RemoveAt(n);
                }
            }

            return(root);
        }
Example #25
0
 public RichNativeType(PackedMemorySnapshot snapshot, int nativeTypesArrayIndex)
     : this()
 {
     m_Snapshot = snapshot;
     m_NativeTypesArrayIndex = nativeTypesArrayIndex;
 }
 public RichStaticField(PackedMemorySnapshot snapshot, int staticFieldsArrayIndex)
     : this()
 {
     m_Snapshot = snapshot;
     m_ManagedStaticFieldsArrayIndex = staticFieldsArrayIndex;
 }
Example #27
0
 public RichNativeObject(PackedMemorySnapshot snapshot, int nativeObjectsArrayIndex)
     : this()
 {
     m_Snapshot = snapshot;
     m_NativeObjectArrayIndex = nativeObjectsArrayIndex;
 }
Example #28
0
        public TreeViewItem BuildTree(PackedMemorySnapshot snapshot, PackedConnection[] connections, bool addFrom, bool addTo)
        {
            m_Snapshot    = snapshot;
            m_Connections = connections;
            m_AddFrom     = addFrom;
            m_AddTo       = addTo;

            m_UniqueId = 1;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null || m_Connections == null || m_Connections.Length < 1)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            for (int n = 0, nend = m_Connections.Length; n < nend; ++n)
            {
                var connection = m_Connections[n];

                if (m_AddTo)
                {
                    switch (connection.toKind)
                    {
                    case PackedConnection.Kind.GCHandle:
                        AddGCHandle(root, m_Snapshot.gcHandles[connection.to]);
                        break;

                    case PackedConnection.Kind.Managed:
                        AddManagedObject(root, m_Snapshot.managedObjects[connection.to]);
                        break;

                    case PackedConnection.Kind.Native:
                        AddNativeUnityObject(root, m_Snapshot.nativeObjects[connection.to]);
                        break;

                    case PackedConnection.Kind.StaticField:
                        AddStaticField(root, m_Snapshot.managedStaticFields[connection.to]);
                        break;
                    }
                }

                if (m_AddFrom)
                {
                    switch (connection.fromKind)
                    {
                    case PackedConnection.Kind.GCHandle:
                        AddGCHandle(root, m_Snapshot.gcHandles[connection.from]);
                        break;

                    case PackedConnection.Kind.Managed:
                        AddManagedObject(root, m_Snapshot.managedObjects[connection.from]);
                        break;

                    case PackedConnection.Kind.Native:
                        AddNativeUnityObject(root, m_Snapshot.nativeObjects[connection.from]);
                        break;

                    case PackedConnection.Kind.StaticField:
                        AddStaticField(root, m_Snapshot.managedStaticFields[connection.from]);
                        break;
                    }
                }
            }

            //if (root.hasChildren)
            //{
            //    root.children.Sort(delegate (TreeViewItem x, TreeViewItem y)
            //    {
            //        var xx = x as Item;
            //        var yy = y as Item;

            //        return xx.m_address.CompareTo(yy.m_address);
            //    });
            //}

            return(root);
        }
Example #29
0
 public ArrayPropertyGridItem(PropertyGridControl owner, PackedMemorySnapshot snapshot, System.UInt64 address, AbstractMemoryReader memoryReader)
     : base(owner, snapshot, address, memoryReader)
 {
 }
Example #30
0
 public ObjectProxy(PackedMemorySnapshot snp, PackedManagedStaticField packed)
 {
     snapshot    = snp;
     staticField = new RichStaticField(snp, packed.staticFieldsArrayIndex);
 }