public static StructFieldsEx GetStructFields(StructFields sf, ClrType type) { Debug.Assert(type.IsValueClass); var flds = type.Fields; var cnt = flds.Count; StructFieldsEx[] structFields = null; var types = new ClrType[cnt]; var fields = new ClrInstanceField[cnt]; for (int i = 0; i < cnt; ++i) { var fld = flds[i]; var kind = TypeExtractor.GetElementKind(fld.Type); if (TypeExtractor.IsUnknownStruct(kind)) { fields[i] = fld; types[i] = fld.Type; if (structFields == null) { structFields = new StructFieldsEx[cnt]; } Debug.Assert(sf.Structs[i] != null); structFields[i] = GetStructFields(sf.Structs[i], fld.Type); } else { fields[i] = fld; types[i] = fld.Type; } } return(new StructFieldsEx(sf, types, fields, structFields)); }
public static StructFields GetStructFields(ClrType type) { Debug.Assert(type.IsValueClass); var flds = type.Fields.ToArray(); // enumeration seems off when this is not done var cnt = flds.Length; var kinds = new ClrElementKind[cnt]; var names = new string[cnt]; var typeNames = new string[cnt]; StructFields[] structFields = null; for (int i = 0; i < cnt; ++i) { var fld = flds[i]; kinds[i] = TypeExtractor.GetElementKind(fld.Type); names[i] = fld.Name; typeNames[i] = fld.Type == null ? Constants.UnknownName : fld.Type.Name; if (TypeExtractor.IsUnknownStruct(kinds[i])) { if (structFields == null) { structFields = new StructFields[cnt]; } structFields[i] = GetStructFields(fld.Type); } } return(new StructFields(type.Name, kinds, names, typeNames, structFields)); }
public void SetField(ClrType parent) { if (parent.Fields != null && _fldIndex >= 0 && _fldIndex < parent.Fields.Count) { _field = parent.Fields[_fldIndex]; _kind = TypeExtractor.GetElementKind(_field.Type); } }
public static StructValueStrings GetStructValueStrings(StructFieldsEx structFld, ClrHeap heap, ulong addr) { var cnt = structFld._fields.Length; var structInfo = structFld._structFields; var vals = new string[cnt]; StructValueStrings[] structVals = null; for (int i = 0; i < cnt; ++i) { if (structInfo.IsAmbiguousKind(i)) { var fobj = structFld._fields[i].GetValue(addr, true); var faddr = (ulong)fobj; var ftype = heap.GetObjectType(faddr); if (ftype != null) { structFld._types[i] = ftype; structInfo.SetKind(TypeExtractor.GetElementKind(ftype), i); } } var fldType = structFld._types[i]; var fld = structFld._fields[i]; var kind = structFld._structFields.Kinds[i]; Debug.Assert(fld != null); if (structFld._ex?[i] != null) { if (structVals == null) { structVals = new StructValueStrings[cnt]; } structVals[i] = GetStructValueStrings(structFld._ex[i], heap, fld.GetAddress(addr, true)); } else if (fldType != null) { var fobj = fld.GetValue(addr, true); var faddr = (ulong)fobj; vals[i] = ValueExtractor.GetTypeValueString(heap, faddr, fldType, true, kind); } else { if (TypeExtractor.IsKnownPrimitive(kind)) { vals[i] = ValueExtractor.GetFieldValueString(heap, addr, true, fld, kind); } else { var fobj = fld.GetAddress(addr, true); var faddr = (ulong)fobj; vals[i] = ValueExtractor.GetFieldValueString(heap, faddr, true, fld, kind); } } } return(new StructValueStrings(vals, structVals)); }
public static StructFieldsInfo GetStructFields(ClrType type, ClrHeap heap, ulong addr) { Debug.Assert(type.IsValueClass); var flds = type.Fields; var cnt = flds.Count; StructFieldsInfo[] structFields = null; var types = new ClrType[cnt]; var typeKinds = new ClrElementKind[cnt]; var fields = new ClrInstanceField[cnt]; var fldKinds = new ClrElementKind[cnt]; for (int i = 0; i < cnt; ++i) { var fld = flds[i]; var ftype = fld.Type; fields[i] = fld; fldKinds[i] = TypeExtractor.GetElementKind(fld.Type); types[i] = fld.Type; typeKinds[i] = fldKinds[i]; if (TypeExtractor.IsAmbiguousKind(fldKinds[i])) { ClrType fType = null; ClrElementKind fKind = ClrElementKind.Unknown; ClrType rType = null; ClrElementKind rKind = ClrElementKind.Unknown; //object obj = fld.GetValue(addr, false, false); object obj = fld.GetValue(addr, true, false); // TODO JRD if (obj is ulong) { (fType, fKind, rType, rKind) = TypeExtractor.GetRealType(heap, (ulong)obj); } if (fType != null) { types[i] = fType; typeKinds[i] = fKind; ftype = fType; } } if (TypeExtractor.IsUnknownStruct(fldKinds[i]) || TypeExtractor.IsUnknownStruct(typeKinds[i])) { if (structFields == null) { structFields = new StructFieldsInfo[cnt]; } var faddr = fld.GetAddress(addr, false); structFields[i] = GetStructFields(types[i], heap, faddr); } } return(new StructFieldsInfo(type, types, typeKinds, fields, fldKinds, structFields)); }
GetClassTypeInfo(ClrHeap heap, ulong addr) { try { addr = Utils.RealAddress(addr); var type = heap.GetObjectType(addr); if (type == null) { return("Object Value Error" + Constants.HeavyGreekCrossPadded + "Cannot find an instance." + Constants.HeavyGreekCrossPadded + "Heap cannot get object type at address: " + Utils.RealAddressString(addr), null, ClrElementKind.Unknown, null, null); } var kind = TypeExtractor.GetElementKind(type); var fldCnt = type.Fields.Count; var fldTypes = fldCnt == 0 ? Utils.EmptyArray <ClrType> .Value : new ClrType[fldCnt]; var fldKinds = fldCnt == 0 ? Utils.EmptyArray <ClrElementKind> .Value : new ClrElementKind[fldCnt]; var strings = fldCnt == 0 ? Utils.EmptyArray <string> .Value : new string[fldCnt]; for (int i = 0; i < fldCnt; ++i) { var fld = type.Fields[i]; var fldType = fld.Type; // returns ClrElementKind.Unknown if fld.Type is null fldTypes[i] = fldType; var fldKind = TypeExtractor.GetElementKind(fldType); fldKinds[i] = fldKind; if (fldKind == ClrElementKind.Unknown) { continue; // nothing to do here, from MDR lib: There is } // a bug in several versions of our debugging layer which causes this. if (TypeExtractor.IsAmbiguousKind(fldKind)) { (ClrType aType, ClrElementKind aKind) = TypeExtractor.GetReferenceFieldRealTypeAndKind(heap, addr, fld); if (aType != null) { fldType = aType; fldTypes[i] = fldType; fldKind = aKind; fldKinds[i] = fldKind; } } } return(null, type, kind, fldTypes, fldKinds); } catch (Exception ex) { return(Utils.GetExceptionErrorString(ex), null, ClrElementKind.Unknown, null, null); } }
public static ValueTuple <StructFields, StructFieldsEx> GetStructInfo(ClrType structType, ClrHeap heap, ulong addr, out string error) { Debug.Assert(structType.IsValueClass); error = null; try { ClrType type = null; object val = structType.Fields[0].GetValue(addr, true, false); if (val is ulong) { type = heap.GetObjectType((ulong)val); } if (type == null) { error = "StructValues.GetStructInfo" + Constants.HeavyGreekCrossPadded + "Expected structure at address: " + Utils.RealAddressString(addr) + Constants.HeavyGreekCrossPadded + "ClrHeap.GetObjectType return null. Field name: " + structType.Fields[0].Name + Constants.HeavyGreekCrossPadded; return(null, null); } ClrElementKind kind = TypeExtractor.GetElementKind(type); if (TypeExtractor.IsUnknownStruct(kind)) { error = "StructValues.GetStructInfo" + Constants.HeavyGreekCrossPadded + "Expected structure at address: " + Utils.RealAddressString(addr) + Constants.HeavyGreekCrossPadded + "Found: " + type.Name + Constants.HeavyGreekCrossPadded; return(null, null); } StructFields sf = StructFields.GetStructFields(type); StructFieldsEx sfx = StructFieldsEx.GetStructFields(sf, type, heap, addr); return(sf, sfx); } catch (Exception ex) { error = Utils.GetExceptionErrorString(ex); return(null, null); } }
public static StructFieldsEx GetStructFields(StructFields sf, ClrType type, ClrHeap heap, ulong addr) { Debug.Assert(type.IsValueClass); var flds = type.Fields; var cnt = flds.Count; StructFieldsEx[] structFields = null; var types = new ClrType[cnt]; var fields = new ClrInstanceField[cnt]; for (int i = 0; i < cnt; ++i) { var fld = flds[i]; var kind = TypeExtractor.GetElementKind(fld.Type); ClrType fType = null; if (TypeExtractor.IsAmbiguousKind(kind)) { object obj = fld.GetValue(addr, false, false); if (obj is ulong) { fType = heap.GetObjectType((ulong)obj); } } fields[i] = fld; types[i] = fType ?? fld.Type; if (TypeExtractor.IsUnknownStruct(kind)) { if (structFields == null) { structFields = new StructFieldsEx[cnt]; } Debug.Assert(sf.Structs[i] != null); structFields[i] = GetStructFields(sf.Structs[i], fld.Type); } } return(new StructFieldsEx(sf, types, fields, structFields)); }
public void SetField(ClrInstanceField fld) { _field = fld; _kind = TypeExtractor.GetElementKind(_field.Type); }
GetClassValueStrings(ClrHeap heap, ulong addr) { try { addr = Utils.RealAddress(addr); (ClrType type, ClrElementKind kind, ClrType rtype, ClrElementKind rkind) = TypeExtractor.GetRealType(heap, addr); if (type == null) { return("Object Value Error" + Constants.HeavyGreekCrossPadded + "Cannot find an instance." + Constants.HeavyGreekCrossPadded + "Heap cannot get object type at address: " + Utils.RealAddressString(addr), null, ClrElementKind.Unknown, (null, null, null, null)); } var fldCnt = type.Fields.Count; var fldTypes = fldCnt == 0 ? Utils.EmptyArray <ClrType> .Value : new ClrType[fldCnt]; var fldKinds = fldCnt == 0 ? Utils.EmptyArray <ClrElementKind> .Value : new ClrElementKind[fldCnt]; var strings = fldCnt == 0 ? Utils.EmptyArray <string> .Value : new string[fldCnt]; StructValueStrings[] structVals = null; for (int i = 0; i < fldCnt; ++i) { var fld = type.Fields[i]; var fldType = fld.Type; // returns ClrElementKind.Unknown if fld.Type is null fldTypes[i] = fldType; var fldKind = TypeExtractor.GetElementKind(fldType); fldKinds[i] = fldKind; if (fldKind == ClrElementKind.Unknown) { strings[i] = Constants.UnknownValue; continue; // nothing to do here, from MDR lib: There is // a bug in several versions of our debugging layer which causes this. } if (TypeExtractor.IsAmbiguousKind(fldKind)) { (ClrType aType, ClrElementKind aKind) = TypeExtractor.GetReferenceFieldRealTypeAndKind(heap, addr, fld); if (aType != null) { fldType = aType; fldTypes[i] = fldType; fldKind = aKind; fldKinds[i] = fldKind; } } if (TypeExtractor.IsString(fldKind)) { var o = fld.GetValue(addr, false, true); strings[i] = o == null ? Constants.NullValue : o.ToString(); } else if (TypeExtractor.IsObjectReference(fldKind)) { var obj = fld.GetValue(addr, false, false); strings[i] = obj == null ? Constants.InvalidAddressStr : Utils.RealAddressString((ulong)obj); } else if (TypeExtractor.IsEnum(fldKind)) { strings[i] = ValueExtractor.GetEnumString(addr, fld, false); } else if (fldType.IsPrimitive) { strings[i] = ValueExtractor.PrimitiveValue(addr, fld, false); } else if (TypeExtractor.IsKnownStruct(fldKind)) { switch (TypeExtractor.GetSpecialKind(fldKind)) { case ClrElementKind.DateTime: strings[i] = ValueExtractor.GetDateTimeString(addr, fld, false); break; case ClrElementKind.Guid: strings[i] = ValueExtractor.GuidValueAsString(addr, fldType, false); break; case ClrElementKind.Decimal: strings[i] = ValueExtractor.DecimalStringPAF(addr, fld, false); break; case ClrElementKind.TimeSpan: strings[i] = ValueExtractor.TimeSpanValueAsString(addr, fldType); break; } } else if (TypeExtractor.IsUnknownStruct(fldKind)) { StructFields sf = StructFields.GetStructFields(fldType); StructFieldsEx sfx = StructFieldsEx.GetStructFields(sf, fldType); sfx.ResetTypes(); if (structVals == null) { structVals = new StructValueStrings[fldCnt]; } ulong structAddr = fld.GetAddress(addr, false); structVals[i] = StructFieldsEx.GetStructValueStrings(sfx, heap, structAddr); } } //if (!Utils.SameStrings(fld.Type.Name,fldType.Name)) // { // ulong fldAddr = fld.GetAddress(addr, type.IsValueClass); // if (TypeExtractor.IsString(fldKind)) // { // var obj = ValueExtractor.GetStringValue(fldType, fldAddr); // strings[i] = obj == null ? Constants.NullValue : (string)obj; // } // else if (TypeExtractor.IsObjectReference(fldKind)) // { // var obj = fld.GetValue(addr, false, false); // strings[i] = obj == null ? Constants.InvalidAddressStr : Utils.RealAddressString((ulong)obj); // } // else if (TypeExtractor.IsEnum(fldKind)) // { // long intVal; // strings[i] = ValueExtractor.GetEnumValueString(fldAddr, fldType, out intVal); // } // else if (fldType.IsPrimitive) // { // var obj = fld.Type.GetValue(fldAddr); // strings[i] = ValueExtractor.PrimitiveValue(obj, fldKind); // } // else if (TypeExtractor.IsKnownStruct(fldKind)) // { // switch (TypeExtractor.GetSpecialKind(fldKind)) // { // case ClrElementKind.DateTime: // strings[i] = ValueExtractor.DateTimeValueString(fldAddr, fldType, null); // break; // case ClrElementKind.Guid: // strings[i] = ValueExtractor.GuidValueAsString(fldAddr, fldType); // break; // case ClrElementKind.Decimal: // strings[i] = ValueExtractor.DecimalValueAsString(fldAddr, fldType,null); // break; // case ClrElementKind.TimeSpan: // strings[i] = ValueExtractor.TimeSpanValueAsString(fldAddr, fldType); // break; // } // } // else if (TypeExtractor.IsUnknownStruct(fldKind)) // { // StructFields sf = StructFields.GetStructFields(fldType); // StructFieldsEx sfx = StructFieldsEx.GetStructFields(sf, fldType); // sfx.ResetTypes(); // if (structVals == null) structVals = new StructValueStrings[fldCnt]; // ulong structAddr = fld.GetAddress(addr, false); // structVals[i] = StructFieldsEx.GetStructValueStrings(sfx, heap, structAddr); // } // continue; return(null, type, kind, (fldTypes, fldKinds, strings, structVals)); } catch (Exception ex) { return(Utils.GetExceptionErrorString(ex), null, ClrElementKind.Unknown, (null, null, null, null)); } }
GetClassValues(ClrHeap heap, ulong addr) { try { addr = Utils.RealAddress(addr); (ClrType type, ClrElementKind kind, ClrType rtType, ClrElementKind rtKind) = TypeExtractor.GetRealType(heap, addr); if (type == null) { return("Object Value Error" + Constants.HeavyGreekCrossPadded + "Cannot find an instance." + Constants.HeavyGreekCrossPadded + "Heap cannot get object type at address: " + Utils.RealAddressString(addr), null, ClrElementKind.Unknown, (null, null, null, null, null)); } var fldCnt = type.Fields.Count; var fldTypes = fldCnt == 0 ? Utils.EmptyArray <ClrType> .Value : new ClrType[fldCnt]; var fldKinds = fldCnt == 0 ? Utils.EmptyArray <ClrElementKind> .Value : new ClrElementKind[fldCnt]; var objects = fldCnt == 0 ? Utils.EmptyArray <object> .Value : new object[fldCnt]; StructValues[] structVals = null; StructFieldsInfo[] structFldInfos = null; for (int i = 0; i < fldCnt; ++i) { var fld = type.Fields[i]; var fldType = fld.Type; // returns ClrElementKind.Unknown if fld.Type is null var fldKind = TypeExtractor.GetElementKind(fldType); if (fldKind == ClrElementKind.Unknown) { objects[i] = null; continue; // nothing to do here, from MDR lib: There is // a bug in several versions of our debugging layer which causes this. } if (fldType == null || TypeExtractor.IsAmbiguousKind(fldKind)) { var fldValObj = fld.GetValue(addr, type.IsValueClass, false); if (fldValObj != null && fldValObj is ulong) { var t = heap.GetObjectType((ulong)fldValObj); if (t != null) { fldType = t; fldKind = TypeExtractor.GetElementKind(t); } } } fldTypes[i] = fldType; fldKinds[i] = fldKind; if (fldKind == ClrElementKind.Unknown) { continue; // nothing to do here, from MDR lib: There is } // a bug in several versions of our debugging layer which causes this. if (TypeExtractor.IsString(fldKind)) { objects[i] = fld.GetValue(addr, false, true); } else if (TypeExtractor.IsObjectReference(fldKind)) { object obj = fld.GetValue(addr, false, false); if (obj != null && (ulong)obj != Constants.InvalidAddress) { var t = heap.GetObjectType((ulong)obj); if (t != null) { var k = TypeExtractor.GetElementKind(t); fldTypes[i] = t; fldKinds[i] = k; } } objects[i] = obj; } else if (TypeExtractor.IsEnum(fldKind)) { objects[i] = ValueExtractor.GetEnumValueObject(addr, fld, false); } else if (fldType.IsPrimitive) { objects[i] = ValueExtractor.GetPrimitiveValueObject(addr, fld, false); } else if (TypeExtractor.IsKnownStruct(fldKind)) { switch (TypeExtractor.GetSpecialKind(fldKind)) { case ClrElementKind.DateTime: objects[i] = ValueExtractor.GetDateTimePAF(addr, fld, false); break; case ClrElementKind.Guid: objects[i] = ValueExtractor.GetGuid(addr, fld, false); break; case ClrElementKind.Decimal: objects[i] = ValueExtractor.GetDecimalPAF(addr, fld, false); break; case ClrElementKind.TimeSpan: objects[i] = ValueExtractor.TimeSpanValue(addr, fldType); break; } } else if (TypeExtractor.IsUnknownStruct(fldKind)) { //StructFields sf = StructFields.GetStructFields(fldType); //StructFieldsEx sfx = StructFieldsEx.GetStructFields(sf, fldType); if (structFldInfos == null) { structFldInfos = new StructFieldsInfo[fldCnt]; } ulong saddr = fld.GetAddress(addr, true); StructFieldsInfo sfi = StructFieldsInfo.GetStructFields(fldType, heap, saddr); structFldInfos[i] = sfi; if (sfi != null) { if (structVals == null) { structVals = new StructValues[fldCnt]; } structVals[i] = StructFieldsInfo.GetStructValues(sfi, heap, saddr); } } } return(null, type, kind, (fldTypes, fldKinds, objects, structFldInfos, structVals)); } catch (Exception ex) { return(Utils.GetExceptionErrorString(ex), null, ClrElementKind.Unknown, (null, null, null, null, null)); } }
public void GetValue(ClrHeap heap, ulong address, Queue <ValueTuple <TypeValue, ulong> > que) { que.Clear(); que.Enqueue((this, address)); while (que.Count > 0) { (TypeValue val, ulong addr) = que.Dequeue(); if (val._type == null) { ClrType clrType = heap.GetObjectType(addr); if (clrType == null) { continue; } val._type = clrType; val._kind = TypeExtractor.GetElementKind(clrType); val.SetValue(addr); } if (val._children != null) { for (int i = 0, icnt = val._children.Length; i < icnt; ++i) { TypeValue fldVal = val._children[i]; if (fldVal._fieldName != null && fldVal._field == null) { ClrInstanceField f = val._type.GetFieldByName(fldVal._fieldName); if (f == null) { continue; } fldVal._field = f; fldVal._type = f.Type; fldVal._kind = TypeExtractor.GetElementKind(f.Type); } object v = ValueExtractor.GetFieldValue(heap, addr, fldVal._type.IsValueClass, fldVal._field, fldVal._kind); ulong a = (v is ulong) ? (ulong)v : Constants.InvalidAddress; fldVal.SetValue(v); que.Enqueue((val._children[i], (ulong)val._value)); } } else { if (val._fieldName != null && val._field == null) { ClrInstanceField f = val._type.GetFieldByName(val._fieldName); val._field = f; val._type = f.Type; val._kind = TypeExtractor.GetElementKind(f.Type); } object v = ValueExtractor.GetFieldValue(heap, addr, val._type.IsValueClass, val._field, val._kind); val.SetValue(v); } } }