public static string ReadString(BytesAndOffset bo, VirtualMachineInformation virtualMachineInformation) { var lengthPointer = bo.Add(virtualMachineInformation.objectHeaderSize); var length = lengthPointer.ReadInt32(); var firstChar = lengthPointer.Add(4); return(System.Text.Encoding.Unicode.GetString(firstChar.bytes, firstChar.offset, length * 2)); }
public PackedCrawlerData Crawl(PackedMemorySnapshot input) { _typeInfoToTypeDescription = input.typeDescriptions.ToDictionary(td => td.typeInfoAddress, td => td); _virtualMachineInformation = input.virtualMachineInformation; _typeDescriptions = input.typeDescriptions; _instanceFields = new FieldDescription[_typeDescriptions.Length][]; _staticFields = new FieldDescription[_typeDescriptions.Length][]; foreach (var type in _typeDescriptions) { _instanceFields[type.typeIndex] = TypeTools.AllFieldsOf(type, _typeDescriptions, TypeTools.FieldFindOptions.OnlyInstance).ToArray(); _staticFields[type.typeIndex] = TypeTools.AllFieldsOf(type, _typeDescriptions, TypeTools.FieldFindOptions.OnlyStatic).ToArray(); } var result = new PackedCrawlerData(input); var managedObjects = new List <PackedManagedObject>(result.startIndices.OfFirstManagedObject * 3); var connections = new List <Connection>(managedObjects.Capacity * 3); //we will be adding a lot of connections, but the input format also already had connections. (nativeobject->nativeobject and nativeobject->gchandle). we'll add ours to the ones already there. connections.AddRange(input.connections); Stack <ThingToProfile> thingsToProfile = new Stack <ThingToProfile>(); for (int i = 0; i < input.gcHandles.Length; ++i) { thingsToProfile.Push(new ThingToProfile(input.gcHandles[i].target, result.startIndices.OfFirstGCHandle + i)); } for (int i = 0; i < result.typesWithStaticFields.Length; i++) { var typeDescription = result.typesWithStaticFields[i]; thingsToProfile.Push(new ThingToProfile(typeDescription, new BytesAndOffset { bytes = typeDescription.staticFieldBytes, offset = 0, pointerSize = _virtualMachineInformation.pointerSize }, true, result.startIndices.OfFirstStaticFields + i)); } while (thingsToProfile.Count > 0) { var thingToProfile = thingsToProfile.Pop(); if (thingToProfile.type == PointerType.Reference) { CrawlPointerNonRecursive(input, result.startIndices, thingToProfile.object_offset, thingToProfile.indexOfFrom, connections, managedObjects, thingsToProfile); } else { CrawlRawObjectDataNonRecursive(input, result.startIndices, thingToProfile.bytesAndOffset, thingToProfile.typeDescription, thingToProfile.useStaticFields, thingToProfile.indexOfFrom, connections, managedObjects, thingsToProfile); } } result.managedObjects = managedObjects.ToArray(); connections.AddRange(AddManagedToNativeConnectionsAndRestoreObjectHeaders(input, result.startIndices, result)); result.connections = connections.ToArray(); return(result); }
public PackedCrawlerData Crawl(PackedMemorySnapshot input) { _typeInfoToTypeDescription = input.typeDescriptions.ToDictionary(td => td.typeInfoAddress, td => td); _virtualMachineInformation = input.virtualMachineInformation; _typeDescriptions = input.typeDescriptions; MemUtil.LoadSnapshotProgress(0.1f, "adding connections"); var result = new PackedCrawlerData(input); var managedObjects = new List <PackedManagedObject>(result.startIndices.OfFirstManagedObject * 3); var connections = new List <Connection>(managedObjects.Count * 3); //we will be adding a lot of connections, but the input format also already had connections. (nativeobject->nativeobject and nativeobject->gchandle). we'll add ours to the ones already there. connections.AddRange(input.connections); MemUtil.LoadSnapshotProgress(0.2f, "CrawlPointer"); for (int i = 0; i != input.gcHandles.Length; i++) { try { CrawlPointer(input, result.startIndices, input.gcHandles[i].target, result.startIndices.OfFirstGCHandle + i, connections, managedObjects); } catch (ArgumentException) { UnityEngine.Debug.LogWarningFormat("Skipping CrawlPointer {0}/{1}", i, input.gcHandles.Length); } if (i % 5 == 0) { MemUtil.LoadSnapshotProgress(0.2f + 0.2f * ((float)i / (float)input.gcHandles.Length), string.Format("CrawlPointer({0}/{1})", i, input.gcHandles.Length)); } } MemUtil.LoadSnapshotProgress(0.4f, "CrawlRawObjectData"); for (int i = 0; i < result.typesWithStaticFields.Length; i++) { var typeDescription = result.typesWithStaticFields[i]; try { CrawlRawObjectData(input, result.startIndices, new BytesAndOffset { bytes = typeDescription.staticFieldBytes, offset = 0, pointerSize = _virtualMachineInformation.pointerSize }, typeDescription, true, result.startIndices.OfFirstStaticFields + i, connections, managedObjects); } catch (ArgumentException) { UnityEngine.Debug.LogWarningFormat("Skipping CrawlRawObjectData {0}/{1}", i, result.typesWithStaticFields.Length); } if (i % 5 == 0) { MemUtil.LoadSnapshotProgress(0.4f + 0.2f * ((float)i / (float)result.typesWithStaticFields.Length), string.Format("CrawlRawObjectData({0}/{1})", i, result.typesWithStaticFields.Length)); } } MemUtil.LoadSnapshotProgress(0.6f, "composing result"); result.managedObjects = managedObjects.ToArray(); connections.AddRange(AddManagedToNativeConnectionsAndRestoreObjectHeaders(input, result.startIndices, result)); result.connections = connections.ToArray(); return(result); }
public static bool ValidateVirtualMachineInfo(VirtualMachineInformation vmInfo) { bool ok = vmInfo.pointerSize == x64ArchPtrSize || vmInfo.pointerSize == x86ArchPtrSize; if (ok) { //partial checks to validate computations based on pointer size int expectedObjHeaderSize = 2 * vmInfo.pointerSize; ok |= expectedObjHeaderSize == vmInfo.objectHeaderSize; ok |= expectedObjHeaderSize == vmInfo.allocationGranularity; } return(ok); }
public BytesAndOffset Find(UInt64 address, VirtualMachineInformation virtualMachineInformation) { for (int i = 0; i != Count; ++i) { if (address >= startAddress[i] && address < (startAddress[i] + (ulong)bytes[i].Length)) { return new BytesAndOffset() { bytes = bytes[i], offset = (int)(address - startAddress[i]), pointerSize = virtualMachineInformation.pointerSize } } ; } return(new BytesAndOffset()); }
public static BytesAndOffset Find(this MemorySection[] heap, UInt64 address, VirtualMachineInformation virtualMachineInformation) { foreach (var segment in heap) { if (address >= segment.startAddress && address < (segment.startAddress + (ulong)segment.bytes.Length)) { return new BytesAndOffset() { bytes = segment.bytes, offset = (int)(address - segment.startAddress), pointerSize = virtualMachineInformation.pointerSize } } } ; return(new BytesAndOffset()); }
public CachedSnapshot(PackedMemorySnapshot s) { var vmInfo = s.virtualMachineInformation; if (!VMTools.ValidateVirtualMachineInfo(vmInfo)) { throw new UnityException("Invalid VM info. Snapshot file is corrupted."); } virtualMachineInformation = vmInfo; packedMemorySnapshot = s; m_SnapshotVersion = s.version; nativeAllocationSites = new NativeAllocationSiteEntriesCache(s.nativeAllocationSites); typeDescriptions = new TypeDescriptionEntriesCache(s.typeDescriptions); nativeTypes = new NativeTypeEntriesCache(s.nativeTypes); nativeRootReferences = new NativeRootReferenceEntriesCache(s.nativeRootReferences); nativeObjects = new NativeObjectEntriesCache(s.nativeObjects); nativeMemoryRegions = new NativeMemoryRegionEntriesCache(s.nativeMemoryRegions); nativeMemoryLabels = new NativeMemoryLabelEntriesCache(s.nativeMemoryLabels); nativeCallstackSymbols = new NativeCallstackSymbolEntriesCache(s.nativeCallstackSymbols); nativeAllocations = new NativeAllocationEntriesCache(s.nativeAllocations); managedStacks = new ManagedMemorySectionEntriesCache(s.managedStacks); managedHeapSections = new ManagedMemorySectionEntriesCache(s.managedHeapSections); gcHandles = new GCHandleEntriesCache(s.gcHandles); fieldDescriptions = new FieldDescriptionEntriesCache(s.fieldDescriptions); connections = new ConnectionEntriesCache(s, HasConnectionOverhaul); SortedNativeRegionsEntries = new SortedNativeMemoryRegionEntriesCache(this); SortedManagedStacksEntries = new SortedManagedMemorySectionEntriesCache(managedStacks); SortedManagedHeapEntries = new SortedManagedMemorySectionEntriesCache(managedHeapSections); SortedManagedObjects = new SortedManagedObjectsCache(this); SortedNativeAllocations = new SortedNativeAllocationsCache(this); SortedNativeObjects = new SortedNativeObjectsCache(this); CrawledData = new ManagedData(); typeDescriptions.InitSecondaryItems(this); nativeObjects.InitSecondaryItems(); nativeObjects.InitSecondaryItems(this); }
public static bool ValidateVirtualMachineInfo(VirtualMachineInformation vmInfo) { if (!(vmInfo.pointerSize == x64ArchPtrSize || vmInfo.pointerSize == x86ArchPtrSize)) { return(false); } //partial checks to validate computations based on pointer size int expectedObjHeaderSize = 2 * vmInfo.pointerSize; if (expectedObjHeaderSize != vmInfo.objectHeaderSize) { return(false); } if (expectedObjHeaderSize != vmInfo.allocationGranularity) { return(false); } return(true); }
public static int[] ReadArrayRankLength(CachedSnapshot data, CachedSnapshot.ManagedMemorySectionEntriesCache heap, UInt64 address, int iTypeDescriptionArrayType, VirtualMachineInformation virtualMachineInformation) { if (iTypeDescriptionArrayType < 0) { return(null); } var bo = heap.Find(address, virtualMachineInformation); var bounds = bo.Add(virtualMachineInformation.arrayBoundsOffsetInHeader).ReadPointer(); if (bounds == 0) { return(new int[1] { bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadInt32() }); } var cursor = heap.Find(bounds, virtualMachineInformation); int rank = data.typeDescriptions.GetRank(iTypeDescriptionArrayType); int[] l = new int[rank]; for (int i = 0; i != rank; i++) { l[i] = cursor.ReadInt32(); cursor = cursor.Add(8); } return(l); }
public static int ReadArrayLength(MemorySection[] heap, UInt64 address, TypeDescription arrayType, VirtualMachineInformation virtualMachineInformation) { var bo = heap.Find(address, virtualMachineInformation); var bounds = bo.Add(virtualMachineInformation.arrayBoundsOffsetInHeader).ReadPointer(); if (bounds == 0) #if UNITY_2017_2_OR_NEWER { return((int)bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadPointer()); } #else { return(bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadInt32()); } #endif var cursor = heap.Find(bounds, virtualMachineInformation); int length = 1; for (int i = 0; i != arrayType.arrayRank; i++) { #if UNITY_2017_2_OR_NEWER length *= (int)cursor.ReadPointer(); cursor = cursor.Add(virtualMachineInformation.pointerSize == 4 ? 8 : 16); #else length *= cursor.ReadInt32(); cursor = cursor.Add(8); #endif } return(length); }
public static int ReadArrayObjectSizeInBytes(MemorySection[] heap, UInt64 address, TypeDescription arrayType, TypeDescription[] typeDescriptions, VirtualMachineInformation virtualMachineInformation) { var arrayLength = ArrayTools.ReadArrayLength(heap, address, arrayType, virtualMachineInformation); var elementType = typeDescriptions[arrayType.baseOrElementTypeIndex]; var elementSize = elementType.isValueType ? elementType.size : virtualMachineInformation.pointerSize; return(virtualMachineInformation.arrayHeaderSize + elementSize * arrayLength); }
public PackedCrawlerData Crawl(PackedMemorySnapshot input) { UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "init", 0); _typeInfoToTypeDescription = input.typeDescriptions.ToDictionary(td => td.typeInfoAddress, td => td); _virtualMachineInformation = input.virtualMachineInformation; _typeDescriptions = input.typeDescriptions; _instanceFields = new FieldDescription[_typeDescriptions.Length][]; _staticFields = new FieldDescription[_typeDescriptions.Length][]; foreach (var type in _typeDescriptions) { _instanceFields[type.typeIndex] = TypeTools.AllFieldsOf(type, _typeDescriptions, TypeTools.FieldFindOptions.OnlyInstance).ToArray(); _staticFields[type.typeIndex] = TypeTools.AllFieldsOf(type, _typeDescriptions, TypeTools.FieldFindOptions.OnlyStatic).ToArray(); } UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "adding connections", 0.1f); var result = new PackedCrawlerData(input); var managedObjects = new List <PackedManagedObject>(result.startIndices.OfFirstManagedObject * 3); var connections = new List <Connection>(managedObjects.Capacity * 3); //we will be adding a lot of connections, but the input format also already had connections. (nativeobject->nativeobject and nativeobject->gchandle). we'll add ours to the ones already there. connections.AddRange(input.connections); UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "adding thing to profile", 0.2f); Stack <ThingToProfile> thingsToProfile = new Stack <ThingToProfile>(); for (int i = 0; i < input.gcHandles.Length; ++i) { thingsToProfile.Push(new ThingToProfile(input.gcHandles[i].target, result.startIndices.OfFirstGCHandle + i)); } for (int i = 0; i < result.typesWithStaticFields.Length; i++) { var typeDescription = result.typesWithStaticFields[i]; thingsToProfile.Push(new ThingToProfile(typeDescription, new BytesAndOffset { bytes = typeDescription.staticFieldBytes, offset = 0, pointerSize = _virtualMachineInformation.pointerSize }, true, result.startIndices.OfFirstStaticFields + i)); } UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "crawlpointer and crawlrawobjectdata", 0.3f); int totalCount = thingsToProfile.Count; while (thingsToProfile.Count > 0) { var thingToProfile = thingsToProfile.Pop(); if (thingToProfile.type == PointerType.Reference) { CrawlPointerNonRecursive(input, result.startIndices, thingToProfile.objectPointer, thingToProfile.indexOfFrom, connections, managedObjects, thingsToProfile); } else { CrawlRawObjectDataNonRecursive(input, result.startIndices, thingToProfile.bytesAndOffset, thingToProfile.typeDescription, thingToProfile.useStaticFields, thingToProfile.indexOfFrom, connections, managedObjects, thingsToProfile); } int leftCount = thingsToProfile.Count; if (leftCount % 5 == 0 && UnityEditor.EditorUtility.DisplayCancelableProgressBar("Crawl", string.Format("crawlpointer and crawlrawobjectdata (left:{0}/initial:{1})", leftCount, totalCount), 0.3f + 0.5f * (totalCount - (leftCount > 0 ? leftCount : 0)) / totalCount)) { break; } } UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "composing result", 0.8f); result.managedObjects = managedObjects.ToArray(); connections.AddRange(AddManagedToNativeConnectionsAndRestoreObjectHeaders(input, result.startIndices, result)); result.connections = connections.ToArray(); UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "finish.", 1.0f); UnityEditor.EditorUtility.ClearProgressBar(); return(result); }
public static PackedMemorySnapshot LoadSnapshotBin(Stream stream) { System.Reflection.ConstructorInfo ci = typeof(PackedMemorySnapshot).GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, null, new Type[0], new System.Reflection.ParameterModifier[0]); PackedMemorySnapshot packed = ci.Invoke(null) as PackedMemorySnapshot; BinaryReader br = new BinaryReader(stream); stream.Position += 8; MemUtil.LoadSnapshotProgress(0, "Loading Connection"); float prog = 0; float lastProg = 0; var len = br.ReadInt32(); var connctions = new Connection[len]; System.Reflection.FieldInfo fi = typeof(PackedMemorySnapshot).GetField("m_Connections", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(packed, connctions); for (int i = 0; i < len; i++) { Connection c = new Connection(); c.from = br.ReadInt32(); c.to = br.ReadInt32(); prog = ((float)i / len) * 0.15f; if (prog - lastProg > 0.01) { MemUtil.LoadSnapshotProgress(prog, string.Format("Loading Connction {0}/{1}", i + 1, len)); lastProg = prog; } connctions[i] = c; } len = br.ReadInt32(); PackedGCHandle[] handles = new PackedGCHandle[len]; fi = typeof(PackedMemorySnapshot).GetField("m_GcHandles", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(packed, handles); System.Reflection.FieldInfo[] fis = new System.Reflection.FieldInfo[] { typeof(PackedGCHandle).GetField("m_Target", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) }; for (int i = 0; i < len; i++) { object h = new PackedGCHandle(); var target = br.ReadUInt64(); fi = fis[0]; fi.SetValue(h, target); prog = 0.15f + ((float)i / len) * 0.15f; if (prog - lastProg > 0.01) { MemUtil.LoadSnapshotProgress(prog, string.Format("Loading GCHandles {0}/{1}", i + 1, len)); lastProg = prog; } handles[i] = (PackedGCHandle)h; } len = br.ReadInt32(); MemorySection[] managedHeap = new MemorySection[len]; fi = typeof(PackedMemorySnapshot).GetField("m_ManagedHeapSections", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(packed, managedHeap); fis = new System.Reflection.FieldInfo[] { typeof(MemorySection).GetField("m_Bytes", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(MemorySection).GetField("m_StartAddress", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) }; for (int i = 0; i < len; i++) { object h = new MemorySection(); var bLen = br.ReadInt32(); var bytes = br.ReadBytes(bLen); var startAddress = br.ReadUInt64(); fi = fis[0]; fi.SetValue(h, bytes); fi = fis[1]; fi.SetValue(h, startAddress); prog = 0.3f + ((float)i / len) * 0.15f; if (prog - lastProg > 0.01) { MemUtil.LoadSnapshotProgress(prog, string.Format("Loading Managed Heap {0}/{1}", i + 1, len)); lastProg = prog; } managedHeap[i] = (MemorySection)h; if (managedHeap[i].bytes == null) { UnityEngine.Debug.Log("ff"); } } len = br.ReadInt32(); PackedNativeUnityEngineObject[] nativeObj = new PackedNativeUnityEngineObject[len]; fi = typeof(PackedMemorySnapshot).GetField("m_NativeObjects", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(packed, nativeObj); fis = new System.Reflection.FieldInfo[] { typeof(PackedNativeUnityEngineObject).GetField("m_ClassId", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(PackedNativeUnityEngineObject).GetField("m_HideFlags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(PackedNativeUnityEngineObject).GetField("m_InstanceId", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(PackedNativeUnityEngineObject).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(PackedNativeUnityEngineObject).GetField("m_Name", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(PackedNativeUnityEngineObject).GetField("m_NativeObjectAddress", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(PackedNativeUnityEngineObject).GetField("m_Size", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) }; for (int i = 0; i < len; i++) { object obj = new PackedNativeUnityEngineObject(); int clsID = br.ReadInt32(); HideFlags hideFlags = (HideFlags)br.ReadByte(); int instanceID = br.ReadInt32(); var ft = typeof(PackedNativeUnityEngineObject).GetNestedType("ObjectFlags", System.Reflection.BindingFlags.NonPublic); int flags = 0; if (br.ReadBoolean()) { flags |= 1; } if (br.ReadBoolean()) { flags |= 4; } if (br.ReadBoolean()) { flags |= 2; } object flag = Enum.ToObject(ft, flags); string name = null; if (br.ReadBoolean()) { name = br.ReadString(); } long nativeAddress = br.ReadInt64(); int size = br.ReadInt32(); fi = fis[0]; fi.SetValue(obj, clsID); fi = fis[1]; fi.SetValue(obj, hideFlags); fi = fis[2]; fi.SetValue(obj, instanceID); fi = fis[3]; fi.SetValue(obj, flag); fi = fis[4]; fi.SetValue(obj, name); fi = fis[5]; fi.SetValue(obj, nativeAddress); fi = fis[6]; fi.SetValue(obj, size); prog = 0.45f + ((float)i / len) * 0.15f; if (prog - lastProg > 0.01) { MemUtil.LoadSnapshotProgress(prog, string.Format("Loading Native Objects {0}/{1}", i + 1, len)); lastProg = prog; } nativeObj[i] = (PackedNativeUnityEngineObject)obj; } len = br.ReadInt32(); PackedNativeType[] nativeTypes = new PackedNativeType[len]; fi = typeof(PackedMemorySnapshot).GetField("m_NativeTypes", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(packed, nativeTypes); fis = new System.Reflection.FieldInfo[] { typeof(PackedNativeType).GetField("m_BaseClassId", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(PackedNativeType).GetField("m_Name", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) }; for (int i = 0; i < len; i++) { object t = new PackedNativeType(); int baseClassId = br.ReadInt32(); string name = null; if (br.ReadBoolean()) { name = br.ReadString(); } fi = fis[0]; fi.SetValue(t, baseClassId); fi = fis[1]; fi.SetValue(t, name); prog = 0.6f + ((float)i / len) * 0.15f; if (prog - lastProg > 0.01) { MemUtil.LoadSnapshotProgress(prog, string.Format("Loading Native Types {0}/{1}", i + 1, len)); lastProg = prog; } nativeTypes[i] = (PackedNativeType)t; } len = br.ReadInt32(); TypeDescription[] typeDesc = new TypeDescription[len]; fi = typeof(PackedMemorySnapshot).GetField("m_TypeDescriptions", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(packed, typeDesc); fis = new System.Reflection.FieldInfo[] { typeof(TypeDescription).GetField("m_Assembly", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_BaseOrElementTypeIndex", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_Fields", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_Name", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_Size", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_StaticFieldBytes", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_TypeIndex", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(TypeDescription).GetField("m_TypeInfoAddress", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), }; var fis2 = new System.Reflection.FieldInfo[] { typeof(FieldDescription).GetField("m_IsStatic", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(FieldDescription).GetField("m_Name", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(FieldDescription).GetField("m_Offset", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(FieldDescription).GetField("m_TypeIndex", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), }; for (int i = 0; i < len; i++) { object t = new TypeDescription(); int flags = br.ReadInt32() << 0x10; string assembly = br.ReadString(); int baseOrElementTypeIndex = br.ReadInt32(); int fLen = br.ReadInt32(); FieldDescription[] fields = new FieldDescription[fLen]; for (int j = 0; j < fLen; j++) { object f = new FieldDescription(); bool isStatic = br.ReadBoolean(); string fname = br.ReadString(); int offset = br.ReadInt32(); int ftypeIndex = br.ReadInt32(); fi = fis2[0]; fi.SetValue(f, isStatic); fi = fis2[1]; fi.SetValue(f, fname); fi = fis2[2]; fi.SetValue(f, offset); fi = fis2[3]; fi.SetValue(f, ftypeIndex); fields[j] = (FieldDescription)f; } if (br.ReadBoolean()) { flags |= 2; } if (br.ReadBoolean()) { flags |= 1; } string name = br.ReadString(); int size = br.ReadInt32(); byte[] staticField = br.ReadBytes(br.ReadInt32()); int typeIndex = br.ReadInt32(); ulong typeAddress = br.ReadUInt64(); fi = fis[0]; fi.SetValue(t, assembly); fi = fis[1]; fi.SetValue(t, baseOrElementTypeIndex); fi = fis[2]; fi.SetValue(t, fields); fi = fis[3]; fi.SetValue(t, Enum.ToObject(typeof(TypeDescription).GetNestedType("TypeFlags", System.Reflection.BindingFlags.NonPublic), flags)); fi = fis[4]; fi.SetValue(t, name); fi = fis[5]; fi.SetValue(t, size); fi = fis[6]; fi.SetValue(t, staticField); fi = fis[7]; fi.SetValue(t, typeIndex); fi = fis[8]; fi.SetValue(t, typeAddress); prog = 0.75f + ((float)i / len) * 0.15f; if (prog - lastProg > 0.01) { MemUtil.LoadSnapshotProgress(prog, string.Format("Loading Type Definitions {0}/{1}", i + 1, len)); lastProg = prog; } typeDesc[i] = (TypeDescription)t; } object vminfo = new VirtualMachineInformation(); fis = new System.Reflection.FieldInfo[] { typeof(VirtualMachineInformation).GetField("m_AllocationGranularity", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(VirtualMachineInformation).GetField("m_ArrayBoundsOffsetInHeader", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(VirtualMachineInformation).GetField("m_ArrayHeaderSize", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(VirtualMachineInformation).GetField("m_ArraySizeOffsetInHeader", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(VirtualMachineInformation).GetField("m_ObjectHeaderSize", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), typeof(VirtualMachineInformation).GetField("m_PointerSize", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic), }; fis[0].SetValue(vminfo, br.ReadInt32()); fis[1].SetValue(vminfo, br.ReadInt32()); fis[2].SetValue(vminfo, br.ReadInt32()); fis[3].SetValue(vminfo, br.ReadInt32()); int version = br.ReadInt32(); fis[4].SetValue(vminfo, br.ReadInt32()); fis[5].SetValue(vminfo, br.ReadInt32()); fi = typeof(PackedMemorySnapshot).GetField("m_VirtualMachineInformation", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); fi.SetValue(packed, vminfo); MemUtil.LoadSnapshotProgress(1f, "done"); return(packed); }
public PrimitiveValueReader(VirtualMachineInformation virtualMachineInformation, MemorySection[] heapSections) { _virtualMachineInformation = virtualMachineInformation; _heapSections = heapSections; }
public static int ReadArrayLength(MemorySection[] heap, UInt64 address, TypeDescription arrayType, VirtualMachineInformation virtualMachineInformation) { var bo = heap.Find(address, virtualMachineInformation); var bounds = bo.Add(virtualMachineInformation.arrayBoundsOffsetInHeader).ReadPointer(); if (bounds == 0) { return(bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadInt32()); } var cursor = heap.Find(bounds, virtualMachineInformation); int length = 1; for (int i = 0; i != arrayType.arrayRank; i++) { length *= cursor.ReadInt32(); cursor = cursor.Add(8); } return(length); }