Example #1
0
 internal ICorDebugGCHeapField(string name, int offset, ICorDebugGCHeapType fieldType, CorElementType componentType)
 {
     m_offset        = offset;
     m_name          = name;
     m_type          = fieldType;
     m_ComponentType = componentType;
 }
Example #2
0
        }                                  // 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);
        }
Example #3
0
        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);
        }
Example #4
0
        /// <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);
        }
Example #5
0
        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);
        }
Example #6
0
        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;
            }
        }
Example #7
0
        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);
                }
            }
        }