internal ICorDebugGCHeapField(string name, int offset, ICorDebugGCHeapType fieldType, CorElementType componentType) { m_offset = offset; m_name = name; m_type = fieldType; m_ComponentType = componentType; }
} // For deserialization internal ICorDebugGCHeapRoot(string name, GCRootKind kind, Address heapReference, Address addressOfRoot, ICorDebugGCHeapType type, string appDomainName) { m_kind = kind; m_name = name; m_type = type; m_heapReference = heapReference; m_addressOfRoot = addressOfRoot; m_appDomain = new ICorDebugAD(appDomainName); }
private static ICorDebugGCHeapType GetTypeFromNames(Dictionary <string, ICorDebugGCHeapType> types, string className, string moduleFilePath, ICorDebugGCHeap heap) { ICorDebugGCHeapType ret; if (types.TryGetValue(className, out ret)) { return(ret); } ret = new ICorDebugGCHeapType(heap, className, moduleFilePath); types.Add(className, ret); return(ret); }
/// <summary> /// Can only be used when we have a live heap. returns the type type given a ICorDebug COR_TYPEID token /// </summary> internal ICorDebugGCHeapType GetObjectTypeFromID(COR_TYPEID typeID) { Debug.Assert(m_process5 != null); // only used when we have a live heap ICorDebugGCHeapType ret; if (m_typeTable.TryGetValue(typeID, out ret)) { return(ret); } ret = new ICorDebugGCHeapType(this, typeID); return(ret); }
internal Address GetCurObject(out ICorDebugGCHeapType objType) { if (m_heapEnum == null) { m_heapObjs = new COR_HEAPOBJECT[8192]; // TODO decide on a good number m_process5.EnumerateHeap(out m_heapEnum); Debug.Assert(m_heapObjsCur == m_heapObjsLimit); // Both should be zero. } if (m_heapObjsCur >= m_heapObjsLimit) { m_heapObjsCur = 0; m_heapEnum.Next((uint)m_heapObjs.Length, m_heapObjs, out m_heapObjsLimit); if (m_heapObjsLimit == 0) { objType = null; return(Address.MaxValue); } } objType = GetObjectTypeFromID(m_heapObjs[m_heapObjsCur].type); return(m_heapObjs[m_heapObjsCur].address); }
public ICorDebugGCHeap(ICorDebugProcess process) { int isRunning; process.IsRunning(out isRunning); if (isRunning != 0) { throw new InvalidOperationException("The process must be stopped to dump the GC "); } m_typeTable = new Dictionary <COR_TYPEID, ICorDebugGCHeapType>(); m_types = new List <ICorDebugGCHeapType>(); // Type index 0 is reserverd for the 'Bad Type' var badType = new ICorDebugGCHeapType(this, "!BAD_TYPE!", ""); badType.m_size = 4; // We use the bad type as a way of filling holes in the heap, // Setting these fields marks this as the 'live heap' case. // GCHeapSegment is 'smart' and only fetches the information it // needs from the big blob of data in the segement. m_process = process; m_process5 = process as ICorDebugProcess5; if (m_process5 == null) { throw new Exception("The process is not running V4.5 of the .NET Framework (or V5.0 of silverlight), can't dump the GC Heap."); } COR_HEAPINFO heapInfo; m_process5.GetGCHeapInformation(out heapInfo); if (heapInfo.areGCStructuresValid == 0) { throw new Exception("The process is at a point where the GC structures are being updated. A heap dump is not possible at this time."); } m_pointerSize = (int)heapInfo.pointerSize; Debug.Assert(PointerSize == 4 || PointerSize == 8); // Create the segments (but this leaves the data in the segments // alone) var segmentList = new List <ICorDebugGCHeapSegment>(); ICorDebugHeapSegmentEnum regionEnum; m_process5.EnumerateHeapRegions(out regionEnum); uint fetched; COR_SEGMENT[] corSegment = new COR_SEGMENT[1]; for (; ;) { regionEnum.Next(1, corSegment, out fetched); if (fetched == 0) { break; } segmentList.Add(new ICorDebugGCHeapSegment(this, ref corSegment[0])); } m_icorDebugSegments = segmentList.ToArray(); // Create the segments. UpdateSegments(m_icorDebugSegments); // This is used in FetchIntPtrAt m_data = new byte[1024]; m_pinningHandle = GCHandle.Alloc(m_data, GCHandleType.Pinned); fixed(byte *ptr = m_data) { m_dataPtr = ptr; } }
private void SetNameModuleAndFields(CorElementType typeKind, COR_TYPEID typeID, int numFields) { // THere is recursion in the definition of primitive types (they have a value field of the primtitive type. // Cut this off here. if (GCRootNames.IsPrimitiveType(typeKind)) { numFields = 0; } var buffer = new StringBuilder(1024); IMetadataImport metaData = null; int bufferSizeRet; // This is getting names. If we fail, we can still plow on .... try { ICorDebugType corType = null; // Console.WriteLine("Calling GetTypeForTypeID {0:x} {1:x}", typeID.token1, typeID.token2); m_heap.m_process5.GetTypeForTypeID(typeID, out corType); string moduleFilePath; m_name = GCRootNames.GetTypeName(corType, out moduleFilePath, out metaData, buffer); m_moduleFilePath = moduleFilePath; } catch (Exception e) { Console.WriteLine("Error: Caught exception for type ID {0:x} {1:x}: {2}", typeID.token1, typeID.token2, e.Message); m_name = string.Format("!ERROR TYPE ID {0:x} {1:x}", typeID.token1, typeID.token2); m_moduleFilePath = Name; } if (numFields > 0) { m_fields = new ICorDebugGCHeapField[numFields]; var corFields = new COR_FIELD[numFields]; int fieldsFetched; m_heap.m_process5.GetTypeFields(typeID, corFields.Length, corFields, out fieldsFetched); Debug.Assert(fieldsFetched == m_fields.Length); for (int i = 0; i < corFields.Length; i++) { int fieldTypeToken, fieldAttr, sigBlobSize, cplusTypeFlab, fieldValSize; IntPtr sigBlob, fieldVal; buffer.Length = 0; if (metaData != null) { metaData.GetFieldProps(corFields[i].token, out fieldTypeToken, buffer, buffer.Capacity, out bufferSizeRet, out fieldAttr, out sigBlob, out sigBlobSize, out cplusTypeFlab, out fieldVal, out fieldValSize); } var fieldName = buffer.ToString(); ICorDebugGCHeapType fieldType = null; // If the type has never been loaded, then you can get a null field type. // TODO FIX NOW, think about this. if (corFields[i].id.token1 != 0 || corFields[i].id.token2 != 0) { // Console.WriteLine("Looking up field {0}.{1} typeId {2:x} {3:x}", Name, fieldName, corFields[i].id.token1, corFields[i].id.token2); Debug.Assert(corFields[i].fieldType != CorElementType.ELEMENT_TYPE_END); // TODO FIX NOW remove the condition if (!GCRootNames.IsReferenceType(corFields[i].fieldType)) { fieldType = m_heap.GetObjectTypeFromID(corFields[i].id); } } else { // Console.WriteLine("Warning, NULL type token for {0}.{1} assuming it is an objectRef", Name, fieldName); // Zero means the type is not loaded. This can only happen if it is a reference type corFields[i].fieldType = CorElementType.ELEMENT_TYPE_CLASS; } // The element types match. (string matches class) #if DEBUG if (fieldType != null) { var fieldTypeKind = fieldType.TypeKind; if (fieldTypeKind == CorElementType.ELEMENT_TYPE_STRING) { fieldTypeKind = CorElementType.ELEMENT_TYPE_CLASS; } if (fieldTypeKind == CorElementType.ELEMENT_TYPE_OBJECT) { fieldTypeKind = CorElementType.ELEMENT_TYPE_CLASS; } Debug.Assert(fieldTypeKind == corFields[i].fieldType); } #endif m_fields[i] = new ICorDebugGCHeapField(fieldName, corFields[i].offset, fieldType, corFields[i].fieldType); } } }