public static IEnumerator Crawl(CachedSnapshot snapshot) { const int stepCount = 5; var status = new EnumerationUtilities.EnumerationStatus(stepCount); IntermediateCrawlData crawlData = new IntermediateCrawlData(snapshot); crawlData.ManagedObjectInfos.Capacity = (int)snapshot.gcHandles.Count * 3; crawlData.ManagedConnections.Capacity = (int)snapshot.gcHandles.Count * 6; //Gather handles and duplicates status.StepStatus = "Gathering snapshot managed data."; yield return(status); GatherIntermediateCrawlData(snapshot, crawlData); //crawl handle data status.IncrementStep(); status.StepStatus = "Crawling GC handles."; yield return(status); while (crawlData.CrawlDataStack.Count > 0) { CrawlPointer(crawlData); } //crawl data pertaining to types with static fields and enqueue any heap objects status.IncrementStep(); status.StepStatus = "Crawling data types with static fields"; yield return(status); for (int i = 0; i < crawlData.TypesWithStaticFields.Count; i++) { var iTypeDescription = crawlData.TypesWithStaticFields[i]; var bytesOffset = new BytesAndOffset { bytes = snapshot.typeDescriptions.staticFieldBytes[iTypeDescription], offset = 0, pointerSize = snapshot.virtualMachineInformation.pointerSize }; CrawlRawObjectData(crawlData, bytesOffset, iTypeDescription, true, 0, -1); } //crawl handles belonging to static instances status.IncrementStep(); status.StepStatus = "Crawling static instances heap data."; yield return(status); while (crawlData.CrawlDataStack.Count > 0) { CrawlPointer(crawlData); } //copy crawled object source data for duplicate objects foreach (var i in crawlData.DuplicatedGCHandlesStack) { var ptr = snapshot.CrawledData.ManagedObjects[i].PtrObject; snapshot.CrawledData.ManagedObjects[i] = snapshot.CrawledData.ManagedObjectByAddress[ptr]; } //crawl connection data status.IncrementStep(); status.StepStatus = "Crawling connection data"; yield return(status); ConnectNativeToManageObject(crawlData); AddupRawRefCount(crawlData.CachedMemorySnapshot); }
string IObjectDataTypeFormatter.Format(CachedSnapshot snapshot, ObjectData od, IDataFormatter formatter) { return(formatter.Format(od.managedObjectData.ReadUInt32())); }
public ObjectListTable(Database.Schema schema, SnapshotObjectDataFormatter formatter, CachedSnapshot snapshot, ManagedData crawledData, ObjectMetaType metaType) : base(schema, metaType) { Formatter = formatter; Snapshot = snapshot; CrawledData = crawledData; var col = new List <Database.Column>(); switch (metaType) { case ObjectMetaType.All: case ObjectMetaType.Managed: col.Add(new ObjectListUnifiedIndexColumn(this)); col.Add(new ObjectListNameColumn(this)); col.Add(new ObjectListValueColumn(this)); col.Add(new ObjectListTypeColumn(this)); col.Add(new ObjectListObjectTypeColumn(this)); col.Add(new ObjectListNativeObjectNameLinkColumn(this)); col.Add(new ObjectListLengthColumn(this)); col.Add(new ObjectListStaticColumn(this)); col.Add(new ObjectListRefCountColumn(this)); col.Add(new ObjectListOwnedSizeColumn(this)); col.Add(new ObjectListTargetSizeColumn(this)); col.Add(new ObjectListNativeObjectSizeColumn(this)); col.Add(new ObjectListNativeInstanceIdLinkColumn(this)); col.Add(new ObjectListAddressColumn(this)); col.Add(new ObjectListUniqueStringColumn(this)); break; case ObjectMetaType.Native: col.Add(new ObjectListUnifiedIndexColumn(this)); col.Add(new ObjectListNameColumn(this)); col.Add(new ObjectListValueColumn(this)); col.Add(new ObjectListTypeColumn(this)); col.Add(new ObjectListNativeObjectNameColumn(this)); col.Add(new ObjectListObjectTypeColumn(this)); col.Add(new ObjectListRefCountColumn(this)); col.Add(new ObjectListOwnedSizeColumn(this)); col.Add(new ObjectListTargetSizeColumn(this)); col.Add(new ObjectListNativeInstanceIdColumn(this)); col.Add(new ObjectListAddressColumn(this)); col.Add(new ObjectListUniqueStringColumn(this)); break; } InitExpandColumn(col); }
public SortedNativeAllocationsCache(CachedSnapshot snapshot) { m_Snapshot = snapshot; }
public SortedNativeObjectsCache(CachedSnapshot snapshot) { m_Snapshot = snapshot; }
public SortedNativeMemoryRegionEntriesCache(CachedSnapshot snapshot) { m_Snapshot = snapshot; }
public SortedManagedObjectsCache(CachedSnapshot snapshot) { m_Snapshot = snapshot; }
private void SetManagedType(CachedSnapshot snapshot, int iType) { m_data.managed.iType = iType; }
public static ObjectData[] GetAllObjectConnectingTo(CachedSnapshot snapshot, ObjectData obj) { var o = new List <ObjectData>(); int objIndex = -1; switch (obj.dataType) { case ObjectDataType.Array: case ObjectDataType.BoxedValue: case ObjectDataType.Object: { ManagedObjectInfo moi; if (snapshot.CrawledData.ManagedObjectByAddress.TryGetValue(obj.hostManagedObjectPtr, out moi)) { objIndex = snapshot.ManagedObjectIndexToUnifiedObjectIndex(moi.ManagedObjectIndex); //add crawled connections for (int i = 0; i != snapshot.CrawledData.Connections.Count; ++i) { var c = snapshot.CrawledData.Connections[i]; switch (c.connectionType) { case ManagedConnection.ConnectionType.Global_To_ManagedObject: if (c.toManagedObjectIndex == moi.ManagedObjectIndex) { o.Add(ObjectData.global); } break; case ManagedConnection.ConnectionType.ManagedObject_To_ManagedObject: if (c.toManagedObjectIndex == moi.ManagedObjectIndex) { var objParent = ObjectData.FromManagedObjectIndex(snapshot, c.fromManagedObjectIndex); if (c.fieldFrom >= 0) { if (objParent.dataType == ObjectDataType.Array || objParent.dataType == ObjectDataType.ReferenceArray) { o.Add(objParent); } else { o.Add(objParent.GetInstanceFieldBySnapshotFieldIndex(snapshot, c.fieldFrom, false)); } } else if (c.arrayIndexFrom >= 0) { o.Add(objParent.GetArrayElement(snapshot, c.arrayIndexFrom, false)); } else { o.Add(objParent); } } break; case ManagedConnection.ConnectionType.ManagedType_To_ManagedObject: if (c.toManagedObjectIndex == moi.ManagedObjectIndex) { var objType = ObjectData.FromManagedType(snapshot, c.fromManagedType); if (c.fieldFrom >= 0) { o.Add(objType.GetInstanceFieldBySnapshotFieldIndex(snapshot, c.fieldFrom, false)); } else if (c.arrayIndexFrom >= 0) { o.Add(objType.GetArrayElement(snapshot, c.arrayIndexFrom, false)); } else { o.Add(objType); } } break; case ManagedConnection.ConnectionType.UnityEngineObject: if (c.UnityEngineManagedObjectIndex == moi.ManagedObjectIndex) { o.Add(ObjectData.FromNativeObjectIndex(snapshot, c.UnityEngineNativeObjectIndex)); } break; } } } break; } case ObjectDataType.NativeObject: objIndex = snapshot.NativeObjectIndexToUnifiedObjectIndex(obj.nativeObjectIndex); //add crawled connection for (int i = 0; i != snapshot.CrawledData.Connections.Count; ++i) { switch (snapshot.CrawledData.Connections[i].connectionType) { case ManagedConnection.ConnectionType.Global_To_ManagedObject: case ManagedConnection.ConnectionType.ManagedObject_To_ManagedObject: case ManagedConnection.ConnectionType.ManagedType_To_ManagedObject: break; case ManagedConnection.ConnectionType.UnityEngineObject: if (snapshot.CrawledData.Connections[i].UnityEngineNativeObjectIndex == obj.nativeObjectIndex) { o.Add(ObjectData.FromManagedObjectIndex(snapshot, snapshot.CrawledData.Connections[i].UnityEngineManagedObjectIndex)); } break; } } break; default: return(null); } //add connections from the raw snapshot if (objIndex >= 0) { for (int i = 0; i != snapshot.connections.Count; ++i) { if (snapshot.connections.to[i] == objIndex) { o.Add(ObjectData.FromUnifiedObjectIndex(snapshot, snapshot.connections.from[i])); } } } return(o.ToArray()); }
// Returns a new ObjectData pointing to the object's (that this ObjectData is currently pointing at) field // using a field index from snapshot.fieldDescriptions public ObjectData GetInstanceFieldBySnapshotFieldIndex(CachedSnapshot snapshot, int iField, bool expandToTarget) { ObjectData obj; ulong objectPtr; switch (m_dataType) { case ObjectDataType.ReferenceObject: objectPtr = GetReferencePointer(); obj = FromManagedPointer(snapshot, objectPtr); break; case ObjectDataType.BoxedValue: case ObjectDataType.Object: case ObjectDataType.Value: case ObjectDataType.Type: objectPtr = m_data.managed.objectPtr; obj = this; break; //case ObjectDataType.ReferenceArray: default: //TODO: add proper handling for missing types //DebugUtility.LogError("Requesting a field on an invalid data type"); return(new ObjectData()); } var fieldOffset = snapshot.fieldDescriptions.offset[iField]; var fieldType = snapshot.fieldDescriptions.typeIndex[iField]; bool isStatic = snapshot.fieldDescriptions.isStatic[iField]; switch (m_dataType) { case ObjectDataType.Value: if (!isStatic) { fieldOffset -= snapshot.virtualMachineInformation.objectHeaderSize; } break; case ObjectDataType.Object: case ObjectDataType.BoxedValue: break; case ObjectDataType.Type: if (!isStatic) { Debug.LogError("Requesting a non-static field on a type"); return(invalid); } break; default: break; } ObjectData o = new ObjectData(); o.m_Parent = new ObjectDataParent(obj, iField, -1, expandToTarget); o.SetManagedType(snapshot, fieldType); o.m_dataType = TypeToSubDataType(snapshot, fieldType); if (isStatic) { //the field requested might come from a base class. make sure we are using the right staticFieldBytes. var iOwningType = obj.m_data.managed.iType; while (iOwningType >= 0) { var fieldIndex = System.Array.FindIndex(snapshot.typeDescriptions.fieldIndicesOwned_static[iOwningType], x => x == iField); if (fieldIndex >= 0) { //field iField is owned by type iCurrentBase break; } iOwningType = snapshot.typeDescriptions.baseOrElementTypeIndex[iOwningType]; } if (iOwningType < 0) { Debug.LogError("Field requested is not owned by the type not any of its bases"); return(invalid); } o.m_data.managed.objectPtr = 0; var typeStaticData = new BytesAndOffset(snapshot.typeDescriptions.staticFieldBytes[iOwningType], snapshot.virtualMachineInformation.pointerSize); o.managedObjectData = typeStaticData.Add(fieldOffset); } else { o.m_data.managed.objectPtr = objectPtr;// m_data.managed.objectPtr; o.managedObjectData = obj.managedObjectData.Add(fieldOffset); } return(o); }
// Returns a new ObjectData pointing to the object's (that this ObjectData is currently pointing at) field // using the field index from [0, GetInstanceFieldCount()[ public ObjectData GetInstanceFieldByIndex(CachedSnapshot snapshot, int i) { int iField = snapshot.typeDescriptions.fieldIndices_instance[managedTypeIndex][i]; return(GetInstanceFieldBySnapshotFieldIndex(snapshot, iField, true)); }
// Returns the name of the field this ObjectData is pointing at. // should be called only when IsField() return true public string GetFieldName(CachedSnapshot snapshot) { return(snapshot.fieldDescriptions.fieldDescriptionName[m_Parent.iField]); }
public ObjectData GetArrayElement(CachedSnapshot snapshot, int index, bool expandToTarget) { return(GetArrayElement(snapshot, GetArrayInfo(snapshot), index, expandToTarget)); }
public void Clear() { m_Snapshot = null; BaseFormatter.Clear(); }