コード例 #1
0
        public ClrmdSegment(ClrmdHeap heap, IHeapHelpers helpers, ISegmentData data)
        {
            if (helpers is null)
            {
                throw new ArgumentNullException(nameof(helpers));
            }

            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            _helpers   = helpers;
            _clrmdHeap = heap;

            LogicalHeap           = data.LogicalHeap;
            IsLargeObjectSegment  = data.IsLargeObjectSegment;
            IsPinnedObjectSegment = data.IsPinnedObjectSegment;
            IsEphemeralSegment    = data.IsEphemeralSegment;

            ObjectRange     = new MemoryRange(data.Start, data.End);
            ReservedMemory  = new MemoryRange(data.CommittedEnd, data.ReservedEnd);
            CommittedMemory = new MemoryRange(data.BaseAddress, data.CommittedEnd);

            Generation0 = MemoryRange.CreateFromLength(data.Gen0Start, data.Gen0Length);
            Generation1 = MemoryRange.CreateFromLength(data.Gen1Start, data.Gen1Length);
            Generation2 = MemoryRange.CreateFromLength(data.Gen2Start, data.Gen2Length);

            _markers = new ulong[MarkerCount];
        }
コード例 #2
0
ファイル: ClrmdSegment.cs プロジェクト: wilvk/clrmd
        public ClrmdSegment(ClrmdHeap heap, IHeapHelpers helpers, ISegmentData data)
        {
            if (helpers is null)
            {
                throw new ArgumentNullException(nameof(helpers));
            }

            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            _helpers   = helpers;
            _clrmdHeap = heap;

            LogicalHeap = data.LogicalHeap;
            Start       = data.Start;
            End         = data.End;

            IsLargeObjectSegment = data.IsLargeObjectSegment;
            IsEphemeralSegment   = data.IsEphemeralSegment;

            ReservedEnd  = data.ReservedEnd;
            CommittedEnd = data.CommittedEnd;

            Gen0Start  = data.Gen0Start;
            Gen0Length = data.Gen0Length;
            Gen1Start  = data.Gen1Start;
            Gen1Length = data.Gen1Length;
            Gen2Start  = data.Gen2Start;
            Gen2Length = data.Gen2Length;

            _markers = new ulong[MarkerCount];
        }
コード例 #3
0
        public override IEnumerable <ClrObject> EnumerateObjects()
        {
            bool        large      = IsLargeObjectSegment;
            uint        minObjSize = (uint)IntPtr.Size * 3;
            ulong       obj        = FirstObjectAddress;
            IDataReader dataReader = _helpers.DataReader;

            // C# isn't smart enough to understand that !large means memoryReader is non-null.  We will just be
            // careful here.
            using MemoryReader memoryReader = (!large ? new MemoryReader(dataReader, 0x10000) : null) !;
            byte[] buffer = ArrayPool <byte> .Shared.Rent(IntPtr.Size * 2 + sizeof(uint));

            // The large object heap
            if (!large)
            {
                memoryReader.EnsureRangeInCache(obj);
            }

            while (ObjectRange.Contains(obj))
            {
                ulong mt;
                if (large)
                {
                    if (dataReader.Read(obj, buffer) != buffer.Length)
                    {
                        break;
                    }

                    mt = Unsafe.As <byte, nuint>(ref buffer[0]);
                }
                else
                {
                    if (!memoryReader.ReadPtr(obj, out mt))
                    {
                        break;
                    }
                }

                ClrType?type = _helpers.Factory.GetOrCreateType(_clrmdHeap, mt, obj);
                if (type is null)
                {
                    break;
                }

                int marker = GetMarkerIndex(obj);
                if (marker != -1 && _markers[marker] == 0)
                {
                    _markers[marker] = obj;
                }

                ClrObject result = new ClrObject(obj, type);
                yield return(result);

                ulong size;
                if (type.ComponentSize == 0)
                {
                    size = (uint)type.StaticSize;
                }
                else
                {
                    uint count;
                    if (large)
                    {
                        count = Unsafe.As <byte, uint>(ref buffer[IntPtr.Size]);
                    }
                    else
                    {
                        memoryReader.ReadDword(obj + (uint)IntPtr.Size, out count);
                    }

                    // Strings in v4+ contain a trailing null terminator not accounted for.
                    if (_clrmdHeap.StringType == type)
                    {
                        count++;
                    }

                    size = count * (ulong)type.ComponentSize + (ulong)type.StaticSize;
                }

                size = ClrmdHeap.Align(size, large);
                if (size < minObjSize)
                {
                    size = minObjSize;
                }

                obj += size;
                obj  = _clrmdHeap.SkipAllocationContext(this, obj);
            }

            ArrayPool <byte> .Shared.Return(buffer);
        }
コード例 #4
0
        public override ulong GetNextObjectAddress(ulong addr)
        {
            if (addr == 0)
            {
                return(0);
            }

            if (!ObjectRange.Contains(addr))
            {
                throw new InvalidOperationException($"Segment [{FirstObjectAddress:x},{CommittedMemory:x}] does not contain object {addr:x}");
            }

            bool          large        = IsLargeObjectSegment;
            uint          minObjSize   = (uint)IntPtr.Size * 3;
            IMemoryReader memoryReader = _helpers.DataReader;
            ulong         mt           = memoryReader.ReadPointer(addr);

            ClrType?type = _helpers.Factory.GetOrCreateType(Heap, mt, addr);

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

            ulong size;

            if (type.ComponentSize == 0)
            {
                size = (uint)type.StaticSize;
            }
            else
            {
                uint count = memoryReader.Read <uint>(addr + (uint)IntPtr.Size);

                // Strings in v4+ contain a trailing null terminator not accounted for.
                if (Heap.StringType == type)
                {
                    count++;
                }

                size = count * (ulong)type.ComponentSize + (ulong)type.StaticSize;
            }

            size = ClrmdHeap.Align(size, large);
            if (size < minObjSize)
            {
                size = minObjSize;
            }

            ulong obj = addr + size;

            if (!large)
            {
                obj = _clrmdHeap.SkipAllocationContext(this, obj); // ignore mt here because it won't be used
            }
            if (obj >= End)
            {
                return(0);
            }

            int marker = GetMarkerIndex(obj);

            if (marker != -1 && _markers[marker] == 0)
            {
                _markers[marker] = obj;
            }

            return(obj);
        }