public virtual string GetObjectName(long row) { var obj = GetObjectData(row); switch (obj.dataType) { case ObjectDataType.Array: case ObjectDataType.ReferenceArray: case ObjectDataType.BoxedValue: case ObjectDataType.Value: return(string.Empty); case ObjectDataType.Object: case ObjectDataType.ReferenceObject: ManagedObjectInfo moi = GetMoiFromObjectData(obj); if (moi.IsValid() && moi.NativeObjectIndex >= 0) { return(Snapshot.nativeObjects.objectName[moi.NativeObjectIndex]); } return(string.Empty); case ObjectDataType.NativeObject: case ObjectDataType.NativeObjectReference: return(Snapshot.nativeObjects.objectName[obj.nativeObjectIndex]); case ObjectDataType.Global: case ObjectDataType.Type: case ObjectDataType.Unknown: default: return(Formatter.Format(obj, DefaultDataFormatter.Instance)); } }
public static ObjectData FromManagedPointer(CachedSnapshot snapshot, ulong ptr, int asTypeIndex = -1) { if (ptr == 0) { return(Invalid); } int idx; if (snapshot.CrawledData.MangedObjectIndexByAddress.TryGetValue(ptr, out idx)) { return(FromManagedObjectInfo(snapshot, snapshot.CrawledData.ManagedObjects[idx])); } else { ObjectData o = new ObjectData(); o.m_data.managed.objectPtr = ptr; o.managedObjectData = snapshot.managedHeapSections.Find(ptr, snapshot.virtualMachineInformation); ManagedObjectInfo info = default(ManagedObjectInfo); if (Crawler.TryParseObjectHeader(snapshot, ptr, out info)) { if (asTypeIndex >= 0) { o.SetManagedType(snapshot, asTypeIndex); } else { o.SetManagedType(snapshot, info.ITypeDescription); } o.m_dataType = TypeToDataType(snapshot, info.ITypeDescription); return(o); } } return(Invalid); }
public override long GetRowValue(long row) { var obj = m_Table.GetObjectData(row).displayObject; ManagedObjectInfo moi = GetInfo(obj); if (moi.IsValid() && moi.NativeObjectIndex >= 0) { return((long)m_Table.Snapshot.nativeObjects.size[moi.NativeObjectIndex]); } return(-1); }
public static ManagedObjectInfo ParseObjectHeader(CachedSnapshot snapshot, BytesAndOffset byteOffset, bool ignoreBadHeaderError) { var heap = snapshot.managedHeapSections; ManagedObjectInfo objectInfo; objectInfo = new ManagedObjectInfo(); objectInfo.PtrObject = 0; objectInfo.ManagedObjectIndex = -1; var boHeader = byteOffset; ulong ptrIdentity; boHeader.TryReadPointer(out ptrIdentity); objectInfo.PtrTypeInfo = ptrIdentity; objectInfo.ITypeDescription = snapshot.typeDescriptions.TypeInfo2ArrayIndex(objectInfo.PtrTypeInfo); bool error = false; if (objectInfo.ITypeDescription < 0) { var boIdentity = heap.Find(ptrIdentity, snapshot.virtualMachineInformation); if (boIdentity.IsValid) { ulong ptrTypeInfo; boIdentity.TryReadPointer(out ptrTypeInfo); objectInfo.PtrTypeInfo = ptrTypeInfo; objectInfo.ITypeDescription = snapshot.typeDescriptions.TypeInfo2ArrayIndex(objectInfo.PtrTypeInfo); error = objectInfo.ITypeDescription < 0; } else { error = true; } } if (!error) { objectInfo.Size = SizeOfObjectInBytes(snapshot, objectInfo.ITypeDescription, boHeader, heap); objectInfo.data = boHeader; } else { if (!ignoreBadHeaderError) { #if DEBUG_VALIDATION UnityEngine.Debug.LogError("Bad object header at address: " + ptrIdentity); #endif } objectInfo.PtrTypeInfo = 0; objectInfo.ITypeDescription = -1; objectInfo.Size = 0; } return(objectInfo); }
static void GatherIntermediateCrawlData(CachedSnapshot snapshot, IntermediateCrawlData crawlData) { unsafe { var uniqueHandlesPtr = (ulong *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ulong>() * snapshot.gcHandles.Count, UnsafeUtility.AlignOf <ulong>(), Collections.Allocator.Temp); ulong *uniqueHandlesBegin = uniqueHandlesPtr; ulong *uniqueHandlesEnd = uniqueHandlesPtr + snapshot.gcHandles.Count; // Parse all handles for (int i = 0; i != snapshot.gcHandles.Count; i++) { var moi = new ManagedObjectInfo(); var target = snapshot.gcHandles.target[i]; if (target == 0) { #if SNAPSHOT_CRAWLER_DIAG Debuging.DebugUtility.LogWarning("null object in gc handles " + i); #endif moi.ManagedObjectIndex = i; crawlData.ManagedObjectInfos.Add(moi); } else if (snapshot.CrawledData.ManagedObjectByAddress.ContainsKey(target)) { #if SNAPSHOT_CRAWLER_DIAG Debuging.DebugUtility.LogWarning("Duplicate gc handles " + i + " addr:" + snapshot.gcHandles.target[i]); #endif moi.ManagedObjectIndex = i; moi.PtrObject = target; crawlData.ManagedObjectInfos.Add(moi); crawlData.DuplicatedGCHandlesStack.Push(i); } else { moi.ManagedObjectIndex = i; crawlData.ManagedObjectInfos.Add(moi); snapshot.CrawledData.ManagedObjectByAddress.Add(target, moi); UnsafeUtility.CopyStructureToPtr(ref target, uniqueHandlesBegin++); } } uniqueHandlesBegin = uniqueHandlesPtr; //reset iterator //add handles for processing while (uniqueHandlesBegin != uniqueHandlesEnd) { crawlData.CrawlDataStack.Push(new StackCrawlData { ptr = UnsafeUtility.ReadArrayElement <ulong>(uniqueHandlesBegin++, 0), ptrFrom = 0, typeFrom = -1, indexOfFrom = -1, fieldFrom = -1, fromArrayIndex = -1 }); } UnsafeUtility.Free(uniqueHandlesPtr, Collections.Allocator.Temp); } }
public static ObjectData FromManagedObjectInfo(CachedSnapshot snapshot, ManagedObjectInfo moi) { if (moi.ITypeDescription < 0) { return(ObjectData.invalid); } ObjectData o = new ObjectData(); o.m_dataType = TypeToDataType(snapshot, moi.ITypeDescription);// ObjectDataType.Object; o.m_data.managed.objectPtr = moi.PtrObject; o.SetManagedType(snapshot, moi.ITypeDescription); o.managedObjectData = moi.data; return(o); }
static void GatherIntermediateCrawlData(CachedSnapshot snapshot, IntermediateCrawlData crawlData) { unsafe { var uniqueHandlesPtr = (ulong *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ulong>() * snapshot.gcHandles.Count, UnsafeUtility.AlignOf <ulong>(), Collections.Allocator.Temp); ulong *uniqueHandlesBegin = uniqueHandlesPtr; int writtenRange = 0; // Parse all handles for (int i = 0; i != snapshot.gcHandles.Count; i++) { var moi = new ManagedObjectInfo(); var target = snapshot.gcHandles.target[i]; moi.ManagedObjectIndex = i; //this can only happen pre 19.3 scripting snapshot implementations where we dumped all handle targets but not the handles. //Eg: multiple handles can have the same target. Future facing we need to start adding that as we move forward if (snapshot.CrawledData.MangedObjectIndexByAddress.ContainsKey(target)) { moi.PtrObject = target; crawlData.DuplicatedGCHandleTargetsStack.Push(i); } else { snapshot.CrawledData.MangedObjectIndexByAddress.Add(target, moi.ManagedObjectIndex); *(uniqueHandlesBegin++) = target; ++writtenRange; } crawlData.ManagedObjectInfos.Add(moi); } uniqueHandlesBegin = uniqueHandlesPtr; //reset iterator ulong *uniqueHandlesEnd = uniqueHandlesPtr + writtenRange; //add handles for processing while (uniqueHandlesBegin != uniqueHandlesEnd) { crawlData.CrawlDataStack.Push(new StackCrawlData { ptr = UnsafeUtility.ReadArrayElement <ulong>(uniqueHandlesBegin++, 0), ptrFrom = 0, typeFrom = -1, indexOfFrom = -1, fieldFrom = -1, fromArrayIndex = -1 }); } UnsafeUtility.Free(uniqueHandlesPtr, Collections.Allocator.Temp); } }
public override string GetRowValue(long row) { var obj = m_Table.GetObjectData(row).displayObject; switch (obj.dataType) { case ObjectDataType.NativeObject: case ObjectDataType.NativeObjectReference: return(m_Table.Snapshot.nativeObjects.objectName[obj.nativeObjectIndex]); } ManagedObjectInfo moi = GetInfo(obj); if (moi.IsValid() && moi.NativeObjectIndex >= 0) { return(m_Table.Snapshot.nativeObjects.objectName[moi.NativeObjectIndex]); } return(""); }
public override int GetRowValue(long row) { var obj = m_Table.GetObjectData(row).displayObject; switch (obj.dataType) { case ObjectDataType.NativeObject: case ObjectDataType.NativeObjectReference: return(m_Table.Snapshot.nativeObjects.instanceId[obj.nativeObjectIndex]); case ObjectDataType.Object: case ObjectDataType.ReferenceObject: ManagedObjectInfo moi = GetInfo(obj); if (moi.IsValid() && moi.NativeObjectIndex >= 0) { return(m_Table.Snapshot.nativeObjects.instanceId[moi.NativeObjectIndex]); } break; } return(CachedSnapshot.NativeObjectEntriesCache.InstanceID_None); }
static ManagedObjectInfo ParseObjectHeader(CachedSnapshot snapshot, ulong ptrObjectHeader, out bool wasAlreadyCrawled, bool ignoreBadHeaderError) { var objectList = snapshot.CrawledData.ManagedObjects; var objectsByAddress = snapshot.CrawledData.MangedObjectIndexByAddress; ManagedObjectInfo objectInfo = default(ManagedObjectInfo); int idx = 0; if (!snapshot.CrawledData.MangedObjectIndexByAddress.TryGetValue(ptrObjectHeader, out idx)) { if (TryParseObjectHeader(snapshot, ptrObjectHeader, out objectInfo)) { objectInfo.ManagedObjectIndex = (int)objectList.Count; objectList.Add(objectInfo); objectsByAddress.Add(ptrObjectHeader, objectInfo.ManagedObjectIndex); } wasAlreadyCrawled = false; return(objectInfo); } objectInfo = snapshot.CrawledData.ManagedObjects[idx]; // this happens on objects from gcHandles, they are added before any other crawled object but have their ptr set to 0. if (objectInfo.PtrObject == 0) { idx = objectInfo.ManagedObjectIndex; if (TryParseObjectHeader(snapshot, ptrObjectHeader, out objectInfo)) { objectInfo.ManagedObjectIndex = idx; objectList[idx] = objectInfo; objectsByAddress[ptrObjectHeader] = idx; } wasAlreadyCrawled = false; return(objectInfo); } wasAlreadyCrawled = true; return(objectInfo); }
public override Database.LinkRequest GetRowLink(long row) { var obj = m_Table.GetObjectData(row).displayObject; if (obj.isManaged) { ManagedObjectInfo moi = GetInfo(obj); if (moi.IsValid() && moi.NativeObjectIndex >= 0) { var instanceId = m_Table.Snapshot.nativeObjects.instanceId[moi.NativeObjectIndex]; if (instanceId == CachedSnapshot.NativeObjectEntriesCache.InstanceID_None) { return(null); } return(MakeLink(ObjectAllNativeTable.TableName, instanceId, row)); } } // we are linking native objects to themselves currently as that allows us // to jump from a native object to the native object's table. (eg: MemoryMap / TreeMap spreadsheets to tables) // TODO: Improve column link API so it supports all 3 cases ( native - native , managed - native, native - managed) else if (obj.isNative) { int index = obj.GetNativeObjectIndex(m_Table.Snapshot); if (index < 0) { return(null); } var instanceId = m_Table.Snapshot.nativeObjects.instanceId[index]; if (instanceId == CachedSnapshot.NativeObjectEntriesCache.InstanceID_None) { return(null); } return(MakeLink(ObjectAllNativeTable.TableName, instanceId, row)); } return(null); }
public static ManagedObjectInfo ParseObjectHeader(CachedSnapshot snapshot, BytesAndOffset byteOffset, bool ignoreBadHeaderError) { var heap = snapshot.managedHeapSections; ManagedObjectInfo objectInfo; objectInfo = new ManagedObjectInfo(); objectInfo.PtrObject = 0; objectInfo.ManagedObjectIndex = -1; var boHeader = byteOffset; var ptrIdentity = boHeader.ReadPointer(); objectInfo.PtrTypeInfo = ptrIdentity; objectInfo.ITypeDescription = snapshot.typeDescriptions.TypeInfo2ArrayIndex(objectInfo.PtrTypeInfo); bool error = false; if (objectInfo.ITypeDescription < 0) { var boIdentity = heap.Find(ptrIdentity, snapshot.virtualMachineInformation); if (boIdentity.IsValid) { var ptrTypeInfo = boIdentity.ReadPointer(); objectInfo.PtrTypeInfo = ptrTypeInfo; objectInfo.ITypeDescription = snapshot.typeDescriptions.TypeInfo2ArrayIndex(objectInfo.PtrTypeInfo); error = objectInfo.ITypeDescription < 0; } else { error = true; } } if (!error) { objectInfo.Size = SizeOfObjectInBytes(snapshot, objectInfo.ITypeDescription, boHeader, heap); objectInfo.data = boHeader; } else { if (!ignoreBadHeaderError) { var cursor = boHeader; string str = ""; for (int j = 0; j != 4; ++j) { for (int i = 0; i != 8; ++i) { var b = cursor.bytes[cursor.offset + i]; str += string.Format(" {0:X2}", b); } var d = cursor.ReadInt64(); str += string.Format(" : 0x{0:X}, {1}", d, d); str += "\n"; cursor = cursor.Add(8); } #if DEBUG_VALIDATION var ptrIdentityTypeIndex = snapshot.typeDescriptions.TypeInfo2ArrayIndex(ptrIdentity); UnityEngine.Debug.LogWarning("Unknown object header or type. " + " header: \n" + str + " First pointer as type index = " + ptrIdentityTypeIndex ); #endif } objectInfo.PtrTypeInfo = 0; objectInfo.ITypeDescription = -1; objectInfo.Size = 0; } return(objectInfo); }
public static bool TryParseObjectHeader(CachedSnapshot snapshot, ulong ptrObjectHeader, out ManagedObjectInfo info) { bool resolveFailed = false; var heap = snapshot.managedHeapSections; info = new ManagedObjectInfo(); info.ManagedObjectIndex = -1; ulong ptrIdentity = 0; var boHeader = heap.Find(ptrObjectHeader, snapshot.virtualMachineInformation); if (!boHeader.IsValid) { resolveFailed = true; } else { boHeader.TryReadPointer(out ptrIdentity); info.PtrTypeInfo = ptrIdentity; info.ITypeDescription = snapshot.typeDescriptions.TypeInfo2ArrayIndex(info.PtrTypeInfo); if (info.ITypeDescription < 0) { var boIdentity = heap.Find(ptrIdentity, snapshot.virtualMachineInformation); if (boIdentity.IsValid) { ulong ptrTypeInfo; boIdentity.TryReadPointer(out ptrTypeInfo); info.PtrTypeInfo = ptrTypeInfo; info.ITypeDescription = snapshot.typeDescriptions.TypeInfo2ArrayIndex(info.PtrTypeInfo); resolveFailed = info.ITypeDescription < 0; } else { resolveFailed = true; } } } if (resolveFailed) { #if DEBUG_VALIDATION UnityEngine.Debug.LogError("Bad object header at address: " + ptrIdentity); #endif info.PtrTypeInfo = 0; info.ITypeDescription = -1; info.Size = 0; info.PtrObject = 0; info.data = default(BytesAndOffset); return(false); } info.Size = SizeOfObjectInBytes(snapshot, info.ITypeDescription, boHeader, heap); info.data = boHeader; info.PtrObject = ptrObjectHeader; return(true); }