Exemple #1
0
        public ulong SkipAllocationContext(ClrSegment seg, ulong obj, ulong mt, Action <ulong, ulong, int, int, uint>?callback)
        {
            if (seg is null)
            {
                throw new ArgumentNullException(nameof(seg));
            }

            if (seg.IsLargeObjectSegment)
            {
                return(obj);
            }

            uint minObjSize = (uint)IntPtr.Size * 3;

            while (AllocationContext.TryGetValue(obj, out ulong nextObj))
            {
                nextObj += Align(minObjSize, seg.IsLargeObjectSegment);

                if (obj >= nextObj || obj >= seg.End)
                {
                    return(0);
                }

                // Only if there's data corruption:
                if (obj >= nextObj || obj >= seg.End)
                {
                    callback?.Invoke(obj, mt, int.MinValue + 2, -1, 0);
                    return(0);
                }

                obj = nextObj;
            }

            return(obj);
        }
Exemple #2
0
        private static void CheckSegments(ClrHeap heap)
        {
            foreach (ClrSegment seg in heap.Segments)
            {
                Assert.NotEqual(0ul, seg.Start);
                Assert.NotEqual(0ul, seg.End);
                Assert.True(seg.Start <= seg.End);

                Assert.True(seg.Start < seg.CommittedEnd);
                Assert.True(seg.CommittedEnd < seg.ReservedEnd);

                if (!seg.IsEphemeralSegment)
                {
                    Assert.Equal(0ul, seg.Gen0Length);
                    Assert.Equal(0ul, seg.Gen1Length);
                }

                int count = 0;
                foreach (ulong obj in seg.EnumerateObjects())
                {
                    ClrSegment curr = heap.GetSegmentByAddress(obj);
                    Assert.Same(seg, curr);
                    count++;
                }

                Assert.True(count >= 1);
            }
        }
Exemple #3
0
        public void SegmentEnumeration()
        {
            // Simply test that we can enumerate the heap.
            using DataTarget dt      = TestTargets.Types.LoadFullDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
            ClrHeap heap = runtime.Heap;

            ClrObject[] objs = heap.EnumerateObjects().ToArray();

            // Enumerating each segment and then each object on each segment should produce
            // the same enumeration as ClrHeap.EnumerateObjects().
            int index = 0;

            foreach (ClrSegment seg in heap.Segments)
            {
                foreach (ClrObject obj in seg.EnumerateObjects())
                {
                    Assert.Equal(objs[index], obj);
                    index++;
                }
            }

            ClrSegment large = heap.Segments.Single(s => s.IsLargeObjectSegment);

            large.EnumerateObjects().ToArray();

            Assert.Equal(objs.Length, index);
        }
Exemple #4
0
        public void StringEmptyTest()
        {
            using DataTarget dt      = TestTargets.Types.LoadFullDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();

            ClrType strType   = runtime.Heap.StringType;
            var     statics   = strType.StaticFields;
            ulong   valueSlot = Assert.Single(statics).GetAddress(runtime.AppDomains[0]);

            Assert.NotEqual(0ul, valueSlot);

            ulong address = dt.DataReader.ReadPointer(valueSlot);

            Assert.NotEqual(0ul, address);
            ClrObject obj = runtime.Heap.GetObject(address);

            Assert.True(obj.Type.IsString);

            string strValue = obj.AsString();

            Assert.Equal("", strValue);

            ClrSegment seg = runtime.Heap.GetSegmentByAddress(valueSlot);

            Assert.NotNull(seg);

            ulong prev = seg.GetPreviousObjectAddress(valueSlot);

            Assert.NotEqual(0ul, prev);

            ClrObject staticsArray = runtime.Heap.GetObject(prev);

            Assert.True(staticsArray.IsValid);
            Assert.True(staticsArray.IsArray);
        }
Exemple #5
0
        public ulong SkipAllocationContext(ClrSegment seg, ulong address)
        {
            if (seg is null)
            {
                throw new ArgumentNullException(nameof(seg));
            }

            if (seg.IsLargeObjectSegment)
            {
                return(address);
            }

            uint minObjSize = (uint)IntPtr.Size * 3;

            while (AllocationContexts.TryGetValue(address, out ulong nextObj))
            {
                nextObj += Align(minObjSize, seg.IsLargeObjectSegment);

                if (address >= nextObj || address >= seg.End)
                {
                    return(0);
                }

                // Only if there's data corruption:
                if (address >= nextObj || address >= seg.End)
                {
                    return(0);
                }

                address = nextObj;
            }

            return(address);
        }
        /// <summary>
        /// Gets the LOH size and the object summary in the LOH
        /// </summary>
        /// <param name="minTotalSize">The min size that we will be filtering on.</param>
        /// <returns>List with ClrType's Name, Count of Object of ClrType and total size of that type</returns>
        private IEnumerable <(string type, int count, long size)> GetLOHStats()
        {
            ClrSegment lohSegment           = Runtime.Heap.Segments.Where(s => s.IsLargeObjectSegment).First();
            IEnumerable <ClrObject> objects = lohSegment.EnumerateObjects();
            var stats = GetStats(objects);

            return(stats.Select(s => (type: s.type.Name, count: s.objects.Count(), s.size)));
        }
        public ClrStackInteriorRoot(ClrSegment seg, ulong address, ulong objAddr, ClrStackFrame stackFrame, bool pinned)
        {
            _segment      = seg;
            ObjectPointer = objAddr;

            Address    = address;
            StackFrame = stackFrame;
            IsPinned   = pinned;
        }
Exemple #8
0
        public SegmentInfo(ClrSegment segment)
        {
            _segment    = segment;
            Number      = _segment.ProcessorAffinity;
            IsEphemeral = _segment.IsEphemeral;
            IsLoh       = _segment.IsLarge;
            IsGen2      = !(IsEphemeral || IsLoh);

            ComputeGenerations(segment);
        }
 private static void WalkSegment(ClrSegment seg)
 {
     foreach (ClrObject obj in seg.EnumerateObjects().Take(2048))
     {
         foreach (ClrReference reference in obj.EnumerateReferencesWithFields(carefully: false, considerDependantHandles: true))
         {
             _ = reference.Object;
         }
     }
 }
Exemple #10
0
        private bool TryGetSegmentMemoryRange(ClrSegment segment, GCGeneration generation, out ulong start, out ulong end)
        {
            start = 0;
            end   = 0;
            switch (generation)
            {
            case GCGeneration.Generation0:
                if (segment.IsEphemeralSegment)
                {
                    start = segment.Generation0.Start;
                    end   = segment.Generation0.End;
                }
                return(start != end);

            case GCGeneration.Generation1:
                if (segment.IsEphemeralSegment)
                {
                    start = segment.Generation1.Start;
                    end   = segment.Generation1.End;
                }
                return(start != end);

            case GCGeneration.Generation2:
                if (!(segment.IsLargeObjectSegment || segment.IsPinnedObjectSegment))
                {
                    start = segment.Generation2.Start;
                    end   = segment.Generation2.End;
                }
                return(start != end);

            case GCGeneration.LargeObjectHeap:
                if (segment.IsLargeObjectSegment)
                {
                    start = segment.Start;
                    end   = segment.End;
                }
                return(start != end);

            case GCGeneration.PinnedObjectHeap:
                if (segment.IsPinnedObjectSegment)
                {
                    start = segment.Start;
                    end   = segment.End;
                }
                return(start != end);

            default:
                return(false);
            }
        }
Exemple #11
0
        private void CheckSorted(IReadOnlyList <ClrSegment> segments)
        {
            ClrSegment last = null;

            foreach (ClrSegment seg in segments)
            {
                if (last != null)
                {
                    Assert.True(last.Start < seg.Start);
                }

                last = seg;
            }
        }
Exemple #12
0
        private void CheckSorted(ImmutableArray <ClrSegment> segments)
        {
            ClrSegment last = null;

            foreach (ClrSegment seg in segments)
            {
                if (last != null)
                {
                    Assert.True(last.Start < seg.Start);
                }

                last = seg;
            }
        }
        private static int?GenerationOf(ClrHeap heap, ClrObject obj)
        {
            ClrSegment segment = heap.GetSegmentByAddress(obj.Address);

            if (segment == null)
            {
                // This happen if the object is no longer live
                return(null);
            }
            else
            {
                return(segment.GetGeneration(obj));
            }
        }
Exemple #14
0
        public override ClrSegment?GetSegmentByAddress(ulong objRef)
        {
            VolatileHeapData            data     = GetHeapData();
            ImmutableArray <ClrSegment> segments = data.Segments;

            if (segments.Length == 0)
            {
                return(null);
            }

            if (segments[0].FirstObjectAddress <= objRef && objRef < segments[segments.Length - 1].End)
            {
                // Start the segment search where you where last
                int prevIndex = data.LastSegmentIndex;
                int curIdx    = prevIndex;
                for (; ;)
                {
                    ClrSegment segment = segments[curIdx];
                    unchecked
                    {
                        long offsetInSegment = (long)(objRef - segment.Start);
                        if (offsetInSegment >= 0)
                        {
                            long intOffsetInSegment = offsetInSegment;
                            if (intOffsetInSegment < (long)segment.Length)
                            {
                                data.LastSegmentIndex = curIdx;
                                return(segment);
                            }
                        }
                    }

                    // Get the next segment loop until you come back to where you started.
                    curIdx++;
                    if (curIdx >= segments.Length)
                    {
                        curIdx = 0;
                    }
                    if (curIdx == prevIndex)
                    {
                        break;
                    }
                }
            }

            return(null);
        }
Exemple #15
0
        private void ComputeGenerations(ClrSegment segment)
        {
            _generations = new List <GenerationInSegment>();

            if (segment.IsLarge)
            {
                _generations.Add(
                    new GenerationInSegment()
                {
                    Generation = 3,
                    Start      = segment.Gen2Start,
                    End        = segment.Gen2Start + segment.Gen2Length,
                    Length     = segment.Gen2Length
                }
                    );
            }
            else if (segment.IsEphemeral)
            {
                _generations.Add(
                    new GenerationInSegment()
                {
                    Generation = 0,
                    Start      = segment.Gen0Start,
                    End        = segment.Gen0Start + segment.Gen0Length,
                    Length     = segment.Gen0Length
                }
                    );
                _generations.Add(
                    new GenerationInSegment()
                {
                    Generation = 1,
                    Start      = segment.Gen1Start,
                    End        = segment.Gen1Start + segment.Gen1Length,
                    Length     = segment.Gen1Length
                }
                    );
                _generations.Add(
                    new GenerationInSegment()
                {
                    Generation = 2,
                    Start      = segment.Gen2Start,
                    End        = segment.Gen2Start + segment.Gen2Length,
                    Length     = segment.Gen2Length
                }
                    );
            }
        }
Exemple #16
0
        private static void CheckSegments(ClrHeap heap)
        {
            foreach (ClrSegment seg in heap.Segments)
            {
                Assert.NotEqual(0ul, seg.Start);
                Assert.NotEqual(0ul, seg.End);
                Assert.True(seg.Start <= seg.End);

                Assert.True(seg.Start < seg.CommittedMemory.End);
                Assert.True(seg.CommittedMemory.End < seg.ReservedMemory.End);
                Assert.False(seg.CommittedMemory.Overlaps(seg.ReservedMemory));
                Assert.True(seg.CommittedMemory.Contains(seg.ObjectRange));

                if (seg.Generation0.Length > 0)
                {
                    Assert.True(seg.ObjectRange.Contains(seg.Generation0));
                }

                if (seg.Generation1.Length > 0)
                {
                    Assert.True(seg.ObjectRange.Contains(seg.Generation1));
                }

                if (seg.Generation2.Length > 0)
                {
                    Assert.True(seg.ObjectRange.Contains(seg.Generation2));
                }

                if (!seg.IsEphemeralSegment)
                {
                    Assert.Equal(0ul, seg.Generation0.Length);
                    Assert.Equal(0ul, seg.Generation1.Length);
                }

                int count = 0;
                foreach (ulong obj in seg.EnumerateObjects())
                {
                    ClrSegment curr = heap.GetSegmentByAddress(obj);
                    Assert.Same(seg, curr);
                    count++;
                }

                Assert.True(count >= 1);
            }
        }
Exemple #17
0
 public static void SetGenerationStats(ClrSegment clrSeg, ulong addr, ulong size, int[] cnts, ulong[] sizes)
 {
     addr = Utils.RealAddress(addr);
     if (clrSeg.IsLarge)
     {
         cnts[0]  += 1;
         sizes[0] += size;
     }
     else
     {
         var gen = clrSeg.GetGeneration(addr);
         if (gen >= 0)
         {
             cnts[gen]  += 1;
             sizes[gen] += size;
         }
     }
 }
Exemple #18
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="ClrSegmentAdapter" /> class.
 /// </summary>
 /// <param name="segment">The segment.</param>
 /// <exception cref="ArgumentNullException">segment</exception>
 /// <inheritdoc />
 public ClrSegmentAdapter(IConverter converter, ClrSegment segment) : base(converter)
 {
     Segment           = segment ?? throw new ArgumentNullException(nameof(segment));
     CommittedEnd      = Segment.CommittedEnd;
     End               = Segment.End;
     FirstObject       = Segment.FirstObject;
     Gen0Length        = Segment.Gen0Length;
     Gen0Start         = Segment.Gen0Start;
     Gen1Length        = Segment.Gen1Length;
     Gen1Start         = Segment.Gen1Start;
     Gen2Length        = Segment.Gen2Length;
     Gen2Start         = Segment.Gen2Start;
     IsEphemeral       = Segment.IsEphemeral;
     IsLarge           = Segment.IsLarge;
     Length            = Segment.Length;
     ProcessorAffinity = Segment.ProcessorAffinity;
     ReservedEnd       = Segment.ReservedEnd;
     Start             = Segment.Start;
 }
Exemple #19
0
 public ClrtSegment(ClrSegment seg, ulong firstAddr, ulong lastAddr, int firstNdx, int endNdx)
 {
     CommittedEnd      = seg.CommittedEnd;
     ReservedEnd       = seg.ReservedEnd;
     Start             = seg.Start;
     End               = seg.End;
     Gen0Start         = seg.Gen0Start;
     Gen0Length        = seg.Gen0Length;
     Gen1Start         = seg.Gen1Start;
     Gen1Length        = seg.Gen1Length;
     Gen2Start         = seg.Gen2Start;
     Gen2Length        = seg.Gen2Length;
     FirstObject       = seg.FirstObject;
     ProcessorAffinity = seg.ProcessorAffinity;
     Ephemeral         = seg.IsEphemeral;
     Large             = seg.IsLarge;
     FirstAddress      = firstAddr;
     LastAddress       = lastAddr;
     FirstIndex        = firstNdx;
     EndIndex          = endNdx;
 }
Exemple #20
0
        public void AllocationContextLocation()
        {
            // Simply test that we can enumerate the heap.
            using DataTarget dt      = TestTargets.Types.LoadFullDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
            ClrHeap heap = runtime.Heap;

            // Ensure that we never find objects within allocation contexts.
            MemoryRange[] allocationContexts = heap.EnumerateAllocationContexts().ToArray();
            Assert.NotEmpty(allocationContexts);

            foreach (MemoryRange ac in allocationContexts)
            {
                Assert.True(ac.Length > 0);

                ClrSegment seg = heap.GetSegmentByAddress(ac.Start);
                Assert.NotNull(seg);
                Assert.Same(seg, heap.GetSegmentByAddress(ac.End - 1));

                Assert.True(seg.ObjectRange.Contains(ac));
            }
        }
Exemple #21
0
        public static IEnumerable <ulong> EnumerateObjectAddresses(this ClrSegment segment,
                                                                   Func <ClrType, bool> predicate)
        {
            var address = segment.FirstObjectAddress;

            while (address != 0 && address < segment.CommittedMemory.End)
            {
                if (predicate != null)
                {
                    var type = segment.Heap.GetObjectType(address);
                    if (predicate(type))
                    {
                        yield return(address);
                    }
                }
                else
                {
                    yield return(address);
                }

                address = segment.GetNextObjectAddress(address);
            }
        }
Exemple #22
0
        private static void CheckSegments(ClrHeap heap)
        {
            foreach (ClrSegment seg in heap.Segments)
            {
                Assert.AreNotEqual(0ul, seg.Start);
                Assert.AreNotEqual(0ul, seg.End);
                Assert.IsTrue(seg.Start <= seg.End);

                Assert.IsTrue(seg.Start < seg.CommittedEnd);
                Assert.IsTrue(seg.CommittedEnd < seg.ReservedEnd);

                if (!seg.IsEphemeral)
                {
                    Assert.AreEqual(0ul, seg.Gen0Length);
                    Assert.AreEqual(0ul, seg.Gen1Length);
                }

                foreach (ulong obj in seg.EnumerateObjectAddresses())
                {
                    ClrSegment curr = heap.GetSegmentByAddress(obj);
                    Assert.AreSame(seg, curr);
                }
            }
        }
Exemple #23
0
 public ObjectSegmentEnum(ClrSegment seg)
 {
     m_seg = seg;
     m_obj = seg.FirstObject;
 }
 public SegmentInformation(ClrSegment segment) => this.segment = segment;
Exemple #25
0
 public MDSegment(ClrSegment seg)
 {
     m_seg = seg;
 }