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: { int idx; if (snapshot.CrawledData.MangedObjectIndexByAddress.TryGetValue(obj.hostManagedObjectPtr, out idx)) { objIndex = snapshot.ManagedObjectIndexToUnifiedObjectIndex(idx); //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 == idx) { o.Add(ObjectData.global); } break; case ManagedConnection.ConnectionType.ManagedObject_To_ManagedObject: if (c.toManagedObjectIndex == idx) { var objParent = ObjectData.FromManagedObjectIndex(snapshot, c.fromManagedObjectIndex); if (c.fieldFrom >= 0) { 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 == idx) { 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 == idx) { 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: 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); }