public ArrayInstanceInformation(ClrDump clrDump, ClrType clrType, ulong address, int length, float? nullRatio, float? uniqueRatio) { Address = address; Length = length; NullRatio = nullRatio; UniqueRatio = uniqueRatio; }
public static ClrObject GetInnerObject(ulong pointer, ClrType type) { ulong fieldAddress; ClrType actualType = type; if (type.IsObjectReference) { type.Heap.ReadPointer(pointer, out fieldAddress); if (!type.IsSealed && fieldAddress != 0) actualType = type.Heap.GetObjectType(fieldAddress); } else if (type.IsPrimitive) { // Unfortunately, ClrType.GetValue for primitives assumes that the value is boxed, // we decrement PointerSize because it will be added when calling ClrType.GetValue. // ClrMD should be updated in a future version to include ClrType.GetValue(int interior). fieldAddress = pointer - (ulong)type.Heap.PointerSize; } else if (type.IsValueClass) { fieldAddress = pointer; } else { throw new NotSupportedException(string.Format("Object type not supported '{0}'", type.Name)); } return new ClrObject(fieldAddress, actualType, !type.IsObjectReference); }
public DelegateTypeInformation(ClrDump clrDump, ClrType clrType, int count, long targetCount) { ClrDump = clrDump; ClrType = clrType; Count = count; Targets = targetCount; }
internal DependencyObjectMetadata(ClrType clrType, ulong address) { ClrType = clrType; Address = address; PopulateDependencyPropertiesFromObjectHierarchy(ClrType); GetEffectiveValues(); }
public ClrNullValue(ClrHeap heap) { foreach (var type in heap.EnumerateTypes()) { s_free = type; break; } }
public ClrHeapObject(ulong address, ClrType type, ulong size, int generation, object simpleValue, ClrException exceptionValue) { Address = address; Type = type; Size = size; Generation = generation; SimpleValue = simpleValue; ExceptionValue = exceptionValue; }
public void Add(ulong address, ClrType clrType) { if (bookmarks != null && ! bookmarks.ContainsKey(address) ) { var bookmark = new Bookmark(address, clrType.Name); bookmarks[address] = bookmark; SaveBookmarks(); } }
private bool IsDependencyProperty(ClrType clrType) { const string dependencyPropertyName = "System.Windows.DependencyProperty"; if (clrType == null) return false; return clrType.Name == dependencyPropertyName; }
public InstanceInformation(ClrDump clrDump, ulong address) { ClrDump = clrDump; Address = address; ClrType = ClrDump.GetObjectType(Address); if (ClrType != null) { TypeName = ClrType.Name; } }
/// <summary> /// Converts the specified type. /// </summary> /// <param name="type">The type.</param> /// <returns>IClrType.</returns> public IClrType Convert(ClrMd.ClrType type) { if (type == null) { return(null); } var item = new ClrTypeAdapter(this, type); return(Cache.GetOrAdd <IClrType>(type, () => item, () => item.Setup())); }
public ClrDynamicClass(ClrHeap heap, ClrType type) { if (heap == null) throw new ArgumentNullException("heap"); if (type == null) throw new ArgumentNullException("type"); m_heap = heap; m_type = type; }
public ClrObject(ClrHeap heap, ClrType type, ulong addr, bool inner) { if (heap == null) throw new ArgumentNullException("heap"); m_addr = addr; m_inner = inner; m_heap = heap; // For interior pointers (structs inside other objects), we simply have to trust the caller // gave us the right thing. m_type = inner ? type : heap.GetObjectType(addr); }
private bool IsDependencyObject(ClrType clrType) { const string dependencyObjectName = "System.Windows.DependencyObject"; if (clrType.Name == dependencyObjectName) return true; ClrType baseType = clrType.BaseType; if (baseType == null) return false; return IsDependencyObject(baseType); }
private static string ReadString(ClrType stringType, ulong stringAddress) { ClrInstanceField lengthField = stringType.GetFieldByName("m_stringLength"); if (lengthField == null) return String.Empty; var stringLength = (int)lengthField.GetFieldValue(stringAddress); if (stringLength <= 0) return String.Empty; var content = new byte[stringLength * 2]; int bytesRead; stringType.Heap.GetRuntime().ReadVirtual(stringAddress + 12, content, stringLength * 2, out bytesRead); return System.Text.Encoding.Unicode.GetString(content); }
public static object GetValue(ClrType type, ulong address) { if (type.IsPrimitive && type.HasSimpleValue) return type.GetValue(address); if (type.IsObjectReference) { if (type.IsString) return ReadString(type, address); return new MemoryAddress(address); } // TODO: Handle structs return "<Struct>"; }
public static object GetSimpleValue(ulong objAddress, ClrType clrType, bool isInterior=false) { if (objAddress == 0) throw new NullReferenceException("ClrObject at is pointing to null address."); ClrHeap heap = clrType.Heap; if (clrType.IsEnum) { var val = clrType.GetValue(objAddress); return clrType.GetEnumName(val); } if (clrType.IsPrimitive || clrType.IsString) return clrType.GetValue(objAddress); ulong address = isInterior ? objAddress : objAddress + (ulong)heap.PointerSize; switch (clrType.Name) { case GuidTypeName: { byte[] buffer = ReadBuffer(heap, address, 16); return new Guid(buffer); } case TimeSpanTypeName: { byte[] buffer = ReadBuffer(heap, address, 8); long ticks = BitConverter.ToInt64(buffer, 0); return new TimeSpan(ticks); } case DateTimeTypeName: { byte[] buffer = ReadBuffer(heap, address, 8); ulong dateData = BitConverter.ToUInt64(buffer, 0); return GetDateTime(dateData); } case IPAddressTypeName: { return GetIPAddress(new ClrObject(objAddress, clrType, isInterior)); } } throw new InvalidOperationException(string.Format("SimpleValue not available for type '{0}'", clrType.Name)); }
public ClrObject(ClrHeap heap, ClrType type, ulong addr) { if (heap == null) throw new ArgumentNullException("heap"); m_addr = addr; m_heap = heap; if (addr != 0) { var gcType = heap.GetObjectType(addr); if (gcType != null) type = gcType; } m_type = type; }
public static bool IsSimpleValue(ClrType type) { if( type == null) { return false; } if (type.IsPrimitive || type.IsString) return true; switch (type.Name) { case GuidTypeName: case TimeSpanTypeName: case DateTimeTypeName: case IPAddressTypeName: return true; } return false; }
public void Setup(ClrDumpType dumpType) { type = dumpType.ClrType; ClrDump = dumpType.ClrDump; pgTypeInfo.SelectedObject = new TypeInformations(dumpType); dlvFields.InitColumns<FieldInformation>(); dlvFields.SetUpTypeColumn<FieldInformation>(this); dlvFields.SetObjects(dumpType.Fields.Select(clrField => new FieldInformation(dumpType, clrField))); dlvMethods.InitColumns<MethodInformation>(); dlvMethods.SetUpTypeColumn<MethodInformation>(this); dlvMethods.SetObjects(dumpType.Methods.Select(clrMethod => new MethodInformation(dumpType, clrMethod))); dtlvParentClasses.InitData<AbstractTypeInformation>(); dtlvParentClasses.SetUpTypeColumn<AbstractTypeInformation>(this); var l = new List<object>(); var typeInformation = new TypeInformation(dumpType.BaseType); var interfaceInformations = InterfaceInformation.GetInterfaces(dumpType); l.Add(typeInformation); l.AddRange(interfaceInformations); dtlvParentClasses.Roots = l; }
internal static bool GetStaticField(ClrHeap heap, ClrType type, GetMemberBinder binder, out object result) { result = null; bool success = false; ClrStaticField field = null; StringComparison compare = binder.IgnoreCase ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture; foreach (var inst in type.StaticFields) { if (inst.Name.Equals(binder.Name, compare)) { field = inst; break; } } if (field != null) { result = new StaticVariableValueWrapper(heap, field); success = true; } return success; }
internal void AddBookmark(ulong address, ClrType clrType) { if (dicoBookmarks != null && !dicoBookmarks.ContainsKey(address)) { var bookmark = new Bookmark(address, clrType.Name); dicoBookmarks[address] = bookmark; Bookmarks.Add(bookmark); Save(); } }
public DisposableTypeInformation(ClrType type, long nbInstances) { ClrType = type; TypeName = ClrType.Name; Count = nbInstances; }
/// <summary> /// This is an implementation helper. Use ClrObject.Size instead. /// </summary> public abstract ulong GetObjectSize(ulong objRef, ClrType type);
/// <summary> /// This is an implementation helper. Use <see cref="ClrObject.EnumerateReferences(bool, bool)">ClrObject.EnumerateReferences</see> instead. /// Enumerates all objects that the given object references. This method is meant for internal use to /// implement ClrObject.EnumerateReferences, which you should use instead of calling this directly. /// </summary> /// <param name="obj">The object in question.</param> /// <param name="type">The type of the object.</param> /// <param name="considerDependantHandles">Whether to consider dependant handle mappings.</param> /// <param name="carefully"> /// Whether to bounds check along the way (useful in cases where /// the heap may be in an inconsistent state.) /// </param> public abstract IEnumerable <ClrObject> EnumerateObjectReferences(ulong obj, ClrType type, bool carefully, bool considerDependantHandles);
public Node(ulong obj, ClrType type, Node prev = null) { Object = obj; Prev = prev; Type = type; if (type == null) throw new ArgumentNullException("type"); if (prev != null) prev.Next = this; }
/// <summary> /// FirstObject returns the first object on this segment or 0 if this segment contains no objects. /// </summary> /// <param name="type">The type of the first object.</param> /// <returns>The first object on this segment or 0 if this segment contains no objects.</returns> abstract public ulong GetFirstObject(out ClrType type);
internal abstract IEnumerable <ClrObject> EnumerateObjectReferences(ulong obj, ClrType type, bool carefully);
private List<ClrObjectModel> GetValues(ulong obj, ClrType type, string baseName, int offset, bool inner, List<ClrObjectModel> values) { if (type.Name == "System.String") { object value; try { value = type.GetValue(obj); } catch (Exception ex) { value = ex.Message; } values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, TypeName = type.Name, Value = value }); values.AddRange(type.Fields.Select(field => new ClrObjectModel { Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = field.GetValue(obj, inner).ToString() })); } else if (type.IsArray) { int len = type.GetArrayLength(obj); if (type.ComponentType == null) { try { for (int i = 0; i < len; i++) values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i) }); } catch{ } } else if (type.ComponentType.HasSimpleValue) { for (int i = 0; i < len; i++) values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i) }); } else { for (int i = 0; i < len; i++) { ulong arrAddress = type.GetArrayElementAddress(obj, i); foreach (var field in type.ComponentType.Fields) { string value; if (field.HasSimpleValue) value = field.GetValue(arrAddress, inner).ToString(); // an embedded struct else value = field.GetAddress(arrAddress, inner).ToString(); values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = value }); if (field.ElementType == ClrElementType.Struct) values.AddRange(GetValues(arrAddress, field.Type, baseName + field.Name, offset + field.Offset, true, new List<ClrObjectModel>())); } } } } else { foreach (var field in type.Fields) { ulong addr = field.GetAddress(obj, inner); object value; if (field.HasSimpleValue) try { value = field.GetValue(obj, inner); } catch (Exception) { value = "{Unknown}"; } else value = addr; string sValue = value?.ToString() ?? "{Null}"; values.Add(new ClrObjectModel { Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = sValue }); if (field.ElementType == ClrElementType.Struct) values.AddRange(GetValues(addr, field.Type, baseName + field.Name, offset + field.Offset, true, new List<ClrObjectModel>())); } } return values; }
public ClrDumpObject(ClrDump dump, ClrType type, ulong address, bool isInterior=false) : base(dump, type) { Address = address; IsInterior = isInterior; }
public FinalizerInformation(ClrDump clrDump, ClrType type, List<ulong> addresses) { AddressList = new AddressList(clrDump, type, addresses); }
internal override IEnumerable <ClrObject> EnumerateObjectReferences(ulong obj, ClrType type, bool carefully) { if (type == null) { type = GetObjectType(obj); } else { Debug.Assert(type == GetObjectType(obj)); } if (!type.ContainsPointers) { return(s_emptyObjectSet); } GCDesc gcdesc = type.GCDesc; if (gcdesc == null) { return(s_emptyObjectSet); } ulong size = type.GetSize(obj); if (carefully) { ClrSegment seg = GetSegmentByAddress(obj); if (seg == null || obj + size > seg.End || (!seg.IsLarge && size > 85000)) { return(s_emptyObjectSet); } } List <ClrObject> result = new List <ClrObject>(); gcdesc.WalkObject(obj, size, GetMemoryReaderForAddress(obj), (reference, offset) => result.Add(new ClrObject(reference, GetObjectType(reference)))); return(result); }
public override ulong NextObject(ulong objRef, out ClrType type) { if (objRef >= CommittedEnd) { type = null; return(0); } uint minObjSize = (uint)_clr.PointerSize * 3; ClrType currType = _heap.GetObjectType(objRef); if (currType == null) { type = null; return(0); } ulong size = currType.GetSize(objRef); size = Align(size, _large); if (size < minObjSize) { size = minObjSize; } // Move to the next object objRef += size; // Check to make sure a GC didn't cause "count" to be invalid, leading to too large // of an object if (objRef >= End) { type = null; return(0); } // Ensure we aren't at the start of an alloc context while (!IsLarge && _subHeap.AllocPointers.TryGetValue(objRef, out ulong tmp)) { tmp += Align(minObjSize, _large); // Only if there's data corruption: if (objRef >= tmp) { type = null; return(0); } // Otherwise: objRef = tmp; if (objRef >= End) { type = null; return(0); } } type = _heap.GetObjectType(objRef); return(objRef); }
private void DecompileType(ClrType type) { string moduleFileName = type.Module.FileName; DecompileTypeFromModule(type.Name, moduleFileName); }
public static long CountTargets(ulong address, ClrType clrType, ClrInstanceField targetField, ClrInstanceField invocCountField) { ClrObject clrObject = new ClrObject(address, clrType); ClrObject target = clrObject[targetField]; if (target.Address != address) { return 1; } var invocCount = clrObject[invocCountField]; var value = invocCount.SimpleValue; return (long)value; }
public ClrObject(ulong objRef, ClrType type) { _objRef = objRef; _type = type; Fields = new Lazy<List<ClrObjectModel>>(ValueFactory, false); }
internal abstract void EnumerateObjectReferences(ulong obj, ClrType type, bool carefully, Action <ulong, int> callback);
public static long CountTargets(ClrDump clrDump, ClrType clrType) { long count = 0; var targetField = clrType.GetFieldByName(TargetFieldName); var invocCountField = clrType.GetFieldByName(InvocationCountFieldName); foreach (ulong address in clrDump.EnumerateInstances(clrType)) { count += CountTargets(address, clrType, targetField, invocCountField); } return count; }
/// <summary> /// This is an implementation helper. /// Enumerates all objects that the given object references. This method is meant for internal use to /// implement ClrObject.EnumerateReferencesWithFields, which you should use instead of calling this directly. /// </summary> /// <param name="obj">The object in question.</param> /// <param name="type">The type of the object.</param> /// <param name="considerDependantHandles">Whether to consider dependant handle mappings.</param> /// <param name="carefully"> /// Whether to bounds check along the way (useful in cases where /// the heap may be in an inconsistent state.) /// </param> public abstract IEnumerable <ClrReference> EnumerateReferencesWithFields(ulong obj, ClrType type, bool carefully, bool considerDependantHandles);
public static ulong FindOwner(ulong address, ClrDump clrDump, ClrType delegateType, ClrType arrayObjType, HashSet<ulong> visited) { if( visited.Contains(address)) { return 0; } var type = clrDump.GetObjectType(address); if (type == null) { return 0; } if( type != arrayObjType && (type.BaseType == null || type.BaseType != delegateType ) ) { return address; } visited.Add(address); var refs = clrDump.GetReferers(address); foreach(var newAddress in refs) { var owner = FindOwner(newAddress, clrDump, delegateType, arrayObjType, visited); if( owner != 0) { return owner; } } return 0; }
/// <summary> /// Given an object on the segment, return the 'next' object in the segment. Returns /// 0 when there are no more objects. (Or enumeration is not possible) /// </summary> abstract public ulong NextObject(ulong objRef, out ClrType type);