Пример #1
0
        public override Address NextObject(Address addr)
        {
            if (addr >= CommittedEnd)
            {
                return(0);
            }

            uint minObjSize = (uint)m_clr.PointerSize * 3;

            ClrType type = m_heap.GetObjectType(addr);

            if (type == null)
            {
                return(0);
            }

            ulong size = type.GetSize(addr);

            size = Align(size, m_large);
            if (size < minObjSize)
            {
                size = minObjSize;
            }

            // Move to the next object
            addr += size;

            // Check to make sure a GC didn't cause "count" to be invalid, leading to too large
            // of an object
            if (addr >= End)
            {
                return(0);
            }

            // Ensure we aren't at the start of an alloc context
            ulong tmp;

            while (!IsLarge && m_subHeap.AllocPointers.TryGetValue(addr, out tmp))
            {
                tmp += Align(minObjSize, m_large);

                // Only if there's data corruption:
                if (addr >= tmp)
                {
                    return(0);
                }

                // Otherwise:
                addr = tmp;

                if (addr >= End)
                {
                    return(0);
                }
            }

            return(addr);
        }
Пример #2
0
        public override ulong NextObject(ulong objRef)
        {
            if (objRef >= CommittedEnd)
            {
                return(0);
            }

            uint minObjSize = (uint)_clr.PointerSize * 3;

            ClrType currType = _heap.GetObjectType(objRef);

            if (currType == 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)
            {
                return(0);
            }

            // Ensure we aren't at the start of an alloc context
            ulong tmp;

            while (!IsLarge && _subHeap.AllocPointers.TryGetValue(objRef, out tmp))
            {
                tmp += Align(minObjSize, _large);

                // Only if there's data corruption:
                if (objRef >= tmp)
                {
                    return(0);
                }

                // Otherwise:
                objRef = tmp;

                if (objRef >= End)
                {
                    return(0);
                }
            }

            return(objRef);
        }
Пример #3
0
        internal static bool IsTooLarge(ulong obj, ClrType type, ClrSegment seg)
        {
            ulong size = type.GetSize(obj);

            if (!seg.IsLarge && size >= 85000)
            {
                return(true);
            }

            return(obj + size > seg.End);
        }
Пример #4
0
        protected internal override IEnumerable <ClrObjectReference> EnumerateObjectReferencesWithFields(ulong obj, ClrType type, bool carefully)
        {
            if (type == null)
            {
                type = GetObjectType(obj);
            }
            else
            {
                Debug.Assert(type == GetObjectType(obj));
            }

            if (type == null || (!type.ContainsPointers && !type.IsCollectible))
            {
                return(s_emptyObjectReferenceSet);
            }

            List <ClrObjectReference> result = null;

            if (type.ContainsPointers)
            {
                GCDesc gcdesc = type.GCDesc;
                if (gcdesc == null)
                {
                    return(s_emptyObjectReferenceSet);
                }

                ulong size = type.GetSize(obj);
                if (carefully)
                {
                    ClrSegment seg = GetSegmentByAddress(obj);
                    if (seg == null || obj + size > seg.End || (!seg.IsLarge && size > 85000))
                    {
                        return(s_emptyObjectReferenceSet);
                    }
                }

                result = new List <ClrObjectReference>();
                MemoryReader reader = GetMemoryReaderForAddress(obj);
                gcdesc.WalkObject(obj, size, ptr => ReadPointer(reader, ptr), (reference, offset) => result.Add(new ClrObjectReference(offset, reference, GetObjectType(reference))));
            }

            if (type.IsCollectible)
            {
                result ??= new List <ClrObjectReference>(1);
                ulong loaderAllocatorObject = type.LoaderAllocatorObject;
                result.Add(new ClrObjectReference(-1, loaderAllocatorObject, GetObjectType(loaderAllocatorObject)));
            }

            return(result);
        }
Пример #5
0
        protected 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>();
            MemoryReader     reader = GetMemoryReaderForAddress(obj);

            gcdesc.WalkObject(obj, size, ptr => ReadPointer(reader, ptr), (reference, offset) => result.Add(new ClrObject(reference, GetObjectType(reference))));
            return(result);
        }
Пример #6
0
        protected internal override void EnumerateObjectReferences(ulong obj, ClrType type, bool carefully, Action <ulong, int> callback)
        {
            if (type == null)
            {
                type = GetObjectType(obj);
            }
            else
            {
                Debug.Assert(type == GetObjectType(obj));
            }

            if (!type.ContainsPointers)
            {
                return;
            }

            GCDesc gcdesc = type.GCDesc;

            if (gcdesc == null)
            {
                return;
            }

            ulong size = type.GetSize(obj);

            if (carefully)
            {
                ClrSegment seg = GetSegmentByAddress(obj);
                if (seg == null || obj + size > seg.End || !seg.IsLarge && size > 85000)
                {
                    return;
                }
            }

            MemoryReader reader = GetMemoryReaderForAddress(obj);

            gcdesc.WalkObject(obj, size, ptr => ReadPointer(reader, ptr), callback);
        }
Пример #7
0
        private static void VerifyStringObjectSize(ClrRuntime runtime, ClrType type, ulong obj, string text)
        {
            var objSize = type.GetSize(obj);
            var objAsHex = obj.ToString("x");
            var rawBytes = Encoding.Unicode.GetBytes(text);

            if (runtime.ClrInfo.Version.Major == 2)
            {
                // This only works in .NET 2.0, the "m_array_Length" field was removed in .NET 4.0
                var arrayLength = (int)type.GetFieldByName("m_arrayLength").GetValue(obj);
                var stringLength = (int)type.GetFieldByName("m_stringLength").GetValue(obj);
                
                var calculatedSize = (((ulong)arrayLength - 1) * 2) + HeaderSize;
                if (objSize != calculatedSize)
                {
                    Console.WriteLine("Object Size Mismatch: arrayLength: {0,4}, stringLength: {1,4}, Object Size: {2,4}, Object: {3} -> \n\"{4}\"",
                                      arrayLength, stringLength, objSize, objAsHex, text);
                }
            }
            else
            {
                // In .NET 4.0 we can do a more normal check, i.e. ("object size" - "raw byte array length") should equal the expected header size
                var theRest = objSize - (ulong)rawBytes.Length;
                if (theRest != HeaderSize)
                {
                    Console.WriteLine("Object Size Mismatch: Raw Bytes Length: {0,4}, Object Size: {1,4}, Object: {2} -> \n\"{3}\"",
                                      rawBytes.Length, objSize, objAsHex, text);
                }
            }
        }