public static StructFields GetStructDescription(StructFieldsInfo sfi) { if (sfi == null) { return(null); } int cnt = sfi._fields.Length; StructFields[] structFields = null; var names = new string[cnt]; var typeNames = new string[cnt]; var kinds = new ClrElementKind[cnt]; for (int i = 0, icnt = sfi._fields.Length; i < icnt; ++i) { if (sfi._structFlds != null && sfi._structFlds[i] != null) { if (structFields == null) { structFields = new StructFields[cnt]; } structFields[i] = GetStructDescription(sfi._structFlds[i]); continue; } var fld = sfi._fields[i]; var fldKind = sfi._fldKinds[i]; var typ = sfi._types[i]; var typKind = sfi._typeKinds[i]; names[i] = fld.Name; typeNames[i] = typ.Name; kinds[i] = typKind; } return(new StructFields(sfi._type.Name, kinds, names, typeNames, structFields)); }
public static StructValues GetStructValues(StructFieldsInfo sfi, ClrHeap heap, ulong addr) { if (!sfi.IsTotalFldCountSet) { sfi.SetTotalFldCount(); } var values = new object[sfi._fields.Length]; StructValues[] structs = null; for (int i = 0, icnt = sfi._fields.Length; i < icnt; ++i) { if (sfi._structFlds != null && sfi._structFlds[i] != null) { if (structs == null) { structs = new StructValues[sfi._fields.Length]; } var faddr = sfi._fields[i].GetAddress(addr, true); structs[i] = GetStructValues(sfi._structFlds[i], heap, faddr); } else { values[i] = GetValue(sfi._types[i], sfi._typeKinds[i], sfi._fields[i], sfi._fldKinds[i], heap, addr, false); } } return(new StructValues(values, structs)); }
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)); }
public static void Description(StructFieldsInfo sfi, StringBuilder sb, string indent) { sb.Append(indent).Append(sfi._type.Name); indent = indent + " "; for (int i = 0, icnt = sfi._fields.Length; i < icnt; ++i) { sb.AppendLine(); sb.Append(indent).Append(sfi._fields[i].Name).Append(" : ").Append(sfi._types[i].Name); if (sfi._structFlds != null && sfi._structFlds[i] != null) { sb.AppendLine(); Description(sfi._structFlds[i], sb, indent + " "); } } }
private void SetTotalFldCount(StructFieldsInfo sfi) { Debug.Assert(sfi != null); _totalFldCount += sfi._fields.Length; if (sfi._structFlds != null) { for (int i = 0, icnt = sfi._structFlds.Length; i < icnt; ++i) { if (sfi._structFlds[i] != null) { SetTotalFldCount(sfi._structFlds[i]); } } } }
public static ValueTuple <bool, ClrType, ClrInstanceField, ClrElementKind, StructFieldsInfo> GetTypeOrFieldForValueExtraction(StructFieldsInfo sfi, string fldName) { if (sfi == null) { return(false, null, null, ClrElementKind.Unknown, null); } for (int i = 0, icnt = sfi._fields.Length; i < icnt; ++i) { if (Utils.SameStrings(sfi._fields[i].Name, fldName)) { var fsfi = sfi._structFlds == null ? null : sfi._structFlds[i]; if (TypeExtractor.IsAmbiguousKind(sfi._fldKinds[i])) { return(true, sfi._types[i], sfi._fields[i], sfi._typeKinds[i], fsfi); } else { return(false, sfi._types[i], sfi._fields[i], sfi._fldKinds[i], fsfi); } } } return(false, null, null, ClrElementKind.Unknown, 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)); } }