예제 #1
0
        private void EnumerateRefsOfUnboxedClass(Address objref, int offsetInObject, Action <ulong, int> action)
        {
            if (m_fields == null)
            {
                return;
            }

            for (int i = 0; i < m_fields.Length; i++)
            {
                var field  = m_fields[i];
                var offset = offsetInObject + field.Offset;

                if (GCRootNames.IsReferenceType(field.m_ComponentType))
                {
                    var val = m_heap.FetchIntPtrAt(objref, offset);
                    if (val != 0)
                    {
                        action(val, offset);
                    }
                }
                else if (field.m_ComponentType == CorElementType.ELEMENT_TYPE_VALUETYPE)
                {
                    // We should not have recursive VALUE TYPEs
                    Debug.Assert(field.m_type != this);

                    field.m_type.EnumerateRefsOfUnboxedClass(objref, offset, action);
                }
            }
        }
예제 #2
0
        public override void EnumerateRefsOfObject(Address objRef, Action <Address, int> action)
        {
            if (IsArray)
            {
                bool isRefType = GCRootNames.IsReferenceType(m_array.componentType);
                if (isRefType || m_array.componentType == CorElementType.ELEMENT_TYPE_VALUETYPE)
                {
                    var arrayLength = (int)m_heap.FetchIntPtrAt(objRef, m_array.countOffset);
                    int offset      = m_array.firstElementOffset;
                    if (isRefType)
                    {
                        for (int i = 0; i < arrayLength; i++)
                        {
                            var val = m_heap.FetchIntPtrAt(objRef, offset);
                            if (val != 0)
                            {
                                action(val, offset);
                            }

                            offset += m_array.elementSize;
                        }
                    }
                    else
                    {
                        Debug.Assert(m_array.componentType == CorElementType.ELEMENT_TYPE_VALUETYPE);
                        for (int i = 0; i < arrayLength; i++)
                        {
                            m_elementType.EnumerateRefsOfUnboxedClass(objRef, offset, action);
                            offset += m_array.elementSize;
                        }
                    }
                }
            }
            else
            {
                // Do the base type's references
                if (BaseType != null)
                {
                    BaseType.EnumerateRefsOfObjectCarefully(objRef, action);
                }
                // And then my fields.
                EnumerateRefsOfUnboxedClass(objRef, m_boxOffset, action);
            }
        }
예제 #3
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);
                }
            }
        }