// Formats a string that *should* uniquely identify an object through multiple snapshots and multiple sessions public string FormatUniqueString(ObjectData od) { switch (od.dataType) { case ObjectDataType.Type: return(m_Snapshot.typeDescriptions.typeDescriptionName[od.managedTypeIndex]); case ObjectDataType.Global: return("<global>"); case ObjectDataType.NativeObject: return(FormatInstanceId(od.codeType, m_Snapshot.nativeObjects.instanceId[od.nativeObjectIndex])); case ObjectDataType.Object: { int index = od.GetManagedObjectIndex(m_Snapshot); if (index >= 0) { int nativeIndex = m_Snapshot.CrawledData.ManagedObjects[index].NativeObjectIndex; if (nativeIndex >= 0) { return(FormatInstanceId(CodeType.Managed, m_Snapshot.nativeObjects.instanceId[nativeIndex])); } ulong ptr; if (od.TryGetObjectPointer(out ptr)) { return(FormatPointer(ptr)); } } goto default; } case ObjectDataType.Unknown: return("<uninitialized type>"); default: { if (od.IsField()) { int offset = m_Snapshot.fieldDescriptions.offset[od.fieldIndex]; ulong objPtr = od.GetObjectPointer(m_Snapshot); return(FormatPointerAndOffset(objPtr, offset)); } else if (od.IsArrayItem()) { ulong objPtr = od.GetObjectPointer(m_Snapshot); return(FormatterPointerAndIndex(objPtr, od.arrayIndex)); } else { ulong ptr; if (od.TryGetObjectPointer(out ptr)) { return(FormatPointer(ptr)); } return(od.GetUnifiedObjectIndex(m_Snapshot).ToString()); } } } }