Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
                }
            }
        }
Exemplo n.º 3
0
        }                                  // Used for deserialization

        internal ICorDebugGCHeapType(ICorDebugGCHeap heap, COR_TYPEID typeID)
        {
            // Console.WriteLine("Creating type for typeId {0:x} {1:x}", typeID.token1, typeID.token2);
            m_heap           = heap;
            m_index          = heap.m_types.Count;
            m_name           = "";
            m_moduleFilePath = "";

            heap.m_typeTable[typeID] = this;
            heap.m_types.Add(this);

            COR_TYPE_LAYOUT header = new COR_TYPE_LAYOUT();

            // Console.WriteLine("Calling GetTypeLayout for typeId {0:x} {1:x}", typeID.token1, typeID.token2);
            heap.m_process5.GetTypeLayout(typeID, out header);
            m_typeKind  = header.type;
            m_boxOffset = header.boxOffset;
            m_size      = header.objectSize;

            // Strings are considered arrays.
            m_isArray = (header.type == CorElementType.ELEMENT_TYPE_ARRAY || header.type == CorElementType.ELEMENT_TYPE_SZARRAY || header.type == CorElementType.ELEMENT_TYPE_STRING);
            if (m_isArray)
            {
                // Console.WriteLine("Calling GetArrayLayout for typeId {0:x} {1:x}", typeID.token1, typeID.token2);
                heap.m_process5.GetArrayLayout(typeID, out m_array);
                m_elementType = heap.GetObjectTypeFromID(m_array.componentID);

                m_moduleFilePath = ComponentType.Module.FileName;
                if (m_typeKind == CorElementType.ELEMENT_TYPE_SZARRAY)
                {
                    m_name = ComponentType.Name + "[]";
                }
                else if (m_typeKind == CorElementType.ELEMENT_TYPE_ARRAY)
                {
                    if (m_array.numRanks == 1)
                    {
                        m_name = ComponentType.Name + "[*]";
                    }
                    else
                    {
                        m_name = ComponentType.Name + "[" + new string(',', m_array.numRanks - 1) + "]";
                    }

                    Debug.Assert(m_array.firstElementOffset > m_array.rankOffset);
                }
                else if (m_typeKind == CorElementType.ELEMENT_TYPE_STRING)
                {
                    m_name = "System.String";
                }

                Debug.Assert(m_array.firstElementOffset > 0);
            }
            else
            {
                if (header.parentID.token1 != 0 || header.parentID.token2 != 0) // If we have a parent get it.
                {
                    m_baseType = heap.GetObjectTypeFromID(header.parentID);
                }

                SetNameModuleAndFields(m_typeKind, typeID, header.numFields);
#if DEBUG
                if (m_fields != null)
                {
                    foreach (var field in m_fields)
                    {
                        Debug.Assert(field != null);
                    }
                }
#endif
            }
        }