public static int ReadStringObjectSizeInBytes(BytesAndOffset bo, VirtualMachineInformation virtualMachineInformation) { var lengthPointer = bo.Add(virtualMachineInformation.objectHeaderSize); var length = lengthPointer.ReadInt32(); return(virtualMachineInformation.objectHeaderSize + /*lengthfield*/ 1 + (length * /*utf16=2bytes per char*/ 2) + /*2 zero terminators*/ 2); }
static void CrawlRawObjectData(IntermediateCrawlData crawlData, BytesAndOffset bytesAndOffset, int iTypeDescription, bool useStaticFields, ulong ptrFrom, int indexOfFrom) { var snapshot = crawlData.CachedMemorySnapshot; var fields = useStaticFields ? snapshot.typeDescriptions.fieldIndicesOwned_static[iTypeDescription] : snapshot.typeDescriptions.fieldIndices_instance[iTypeDescription]; foreach (var iField in fields) { int iField_TypeDescription_TypeIndex = snapshot.fieldDescriptions.typeIndex[iField]; int iField_TypeDescription_ArrayIndex = snapshot.typeDescriptions.TypeIndex2ArrayIndex(iField_TypeDescription_TypeIndex); var fieldLocation = bytesAndOffset.Add(snapshot.fieldDescriptions.offset[iField] - (useStaticFields ? 0 : snapshot.virtualMachineInformation.objectHeaderSize)); if (snapshot.typeDescriptions.HasFlag(iField_TypeDescription_ArrayIndex, TypeFlags.kValueType)) { CrawlRawObjectData(crawlData, fieldLocation, iField_TypeDescription_ArrayIndex, useStaticFields, ptrFrom, indexOfFrom); continue; } ulong fieldAddr; if (fieldLocation.TryReadPointer(out fieldAddr) == BytesAndOffset.PtrReadError.Success) { crawlData.CrawlDataStack.Push(new StackCrawlData() { ptr = fieldAddr, ptrFrom = ptrFrom, typeFrom = iTypeDescription, indexOfFrom = indexOfFrom, fieldFrom = iField, fromArrayIndex = -1 }); } } }
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)); }
static void CrawlRawObjectData(IntermediateCrawlData crawlData, BytesAndOffset bytesAndOffset, int iTypeDescription, bool useStaticFields, ulong ptrFrom, int indexOfFrom) { var snapshot = crawlData.CachedMemorySnapshot; var fields = useStaticFields ? snapshot.typeDescriptions.fieldIndicesOwned_static[iTypeDescription] : snapshot.typeDescriptions.fieldIndices_instance[iTypeDescription]; foreach (var iField in fields) { int iField_TypeDescription_TypeIndex = snapshot.fieldDescriptions.typeIndex[iField]; int iField_TypeDescription_ArrayIndex = snapshot.typeDescriptions.TypeIndex2ArrayIndex(iField_TypeDescription_TypeIndex); var fieldLocation = bytesAndOffset.Add(snapshot.fieldDescriptions.offset[iField] - (useStaticFields ? 0 : snapshot.virtualMachineInformation.objectHeaderSize)); if (snapshot.typeDescriptions.HasFlag(iField_TypeDescription_ArrayIndex, TypeFlags.kValueType)) { CrawlRawObjectData(crawlData, fieldLocation, iField_TypeDescription_ArrayIndex, useStaticFields, ptrFrom, indexOfFrom); continue; } //Workaround that was done to not error out when trying to read an array where the remaining length is less than that pointer size. bool gotException = false; try { fieldLocation.ReadPointer(); } catch (ArgumentException) { gotException = true; } if (!gotException) { crawlData.CrawlDataStack.Push(new StackCrawlData() { ptr = fieldLocation.ReadPointer(), ptrFrom = ptrFrom, typeFrom = iTypeDescription, indexOfFrom = indexOfFrom, fieldFrom = iField, fromArrayIndex = -1 }); } } }
public BytesAndOffset GetArrayElement(int index) { return(data.Add(elementSize * index)); }
// 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); }