Esempio n. 1
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);
            }
        }
Esempio n. 2
0
        private static void PrintOffsets(ClrHeap heap, List <ulong> addresses)
        {
            if (addresses.Count == 0)
            {
                return;
            }

            var segments     = new HashSet <ulong>();
            var offsetCounts = new Dictionary <long, int>();
            var previous     = addresses[0];

            segments.Add(heap.GetSegmentByAddress(previous).Start);

            foreach (var address in addresses.Skip(1))
            {
                var offset = address > previous ? (long)(address - previous) : -(long)(previous - address);
                segments.Add(heap.GetSegmentByAddress(address).Start);

                offsetCounts[offset] = offsetCounts.TryGetValue(offset, out var count) ? count + 1 : 1;
                previous             = address;
            }

            Console.WriteLine($"Segments count: {segments.Count}");

            var sortedOffsetCounts = offsetCounts.Select(x => (offset: x.Key, count: x.Value, absOffset: Math.Abs(x.Key))).OrderBy(x => x.absOffset).ToList();

            foreach (var offsetCount in sortedOffsetCounts.Take(5))
            {
                Console.WriteLine($"Offset: {offsetCount.offset} Count: {offsetCount.count}");
            }

            var remainingOffsets = sortedOffsetCounts.Skip(5).ToList();

            if (remainingOffsets.Count != 0)
            {
                var eventsCount   = remainingOffsets.Sum(x => x.count);
                var maxOffset     = remainingOffsets.Max(x => x.absOffset);
                var averageOffset = (long)remainingOffsets.Average(x => x.absOffset);

                Console.WriteLine($"{remainingOffsets.Count} remaining offsets for {eventsCount} events, max: {maxOffset}, avg: {averageOffset}");
            }
        }
Esempio n. 3
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));
            }
        }
        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));
            }
        }
Esempio n. 5
0
        private void button3_Click(object sender, EventArgs e)
        {
            StartRuntime();
            if (currObj == 0)
            {
                WriteLine("No object selected");
                return;
            }
            var type = m_heap.GetObjectType(currObj);

            if (type.IsException)
            {
                DumpException(currObj);
                return;
            }
            WriteLine("===================================================");
            WriteLine("000>!wdo {0:x16}", currObj);
            WriteLine("Address: {0:x16}", currObj);
            WriteLine("EE Class: {0:x16}", GetEEClass(ReadPointer(currObj)));
            WriteLine("Method Table: {0:x16}", ReadPointer(currObj));
            WriteLine("Class Name: {0}", type.Name);
            WriteLine("Size: {0}", type.GetSize(currObj));
            WriteLine("Instance Fields: {0}", type.Fields.Count);
            WriteLine("Static Fields: {0}", type.StaticFields.Count);
            WriteLine("Total Fields: {0}", type.Fields.Count + type.StaticFields.Count);
            var seg = m_heap.GetSegmentByAddress(currObj);

            WriteLine("Heap/Generation: {0}/{1}", seg.ProcessorAffinity, m_heap.GetGeneration(currObj));

            WriteLine("Module: {0:x16}", type.Module.ImageBase);
            WriteLine("Assembly: {0:x16}", type.Module.AssemblyId);

            WriteLine("File Name: {0}", type.Module.FileName);


            WriteLine("Domain: {0:x16}", AdHoc.GetDomainFromMT(m_runtime, ReadPointer(currObj)));

            /*
             * foreach(var domainAddr in Hacks.GetDomainFromMT(runtime, ReadPointer(currObj))
             * {
             *  Write("{0:x16} ", domainAddr);
             * }
             * WriteLine("");
             */

            WriteLine("===================================================");
            DumpFields(currObj);
        }
Esempio n. 6
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);
            }
        }
Esempio n. 7
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);
                }
            }
        }
Esempio n. 8
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);
                }
            }
        }
Esempio n. 9
0
 /// <summary>
 ///     Returns the GC segment for the given object.
 /// </summary>
 /// <param name="objRef">The object reference.</param>
 /// <returns>IClrSegment.</returns>
 /// <inheritdoc />
 public IClrSegment GetSegmentByAddress(ulong objRef) => Converter.Convert(Heap.GetSegmentByAddress(objRef));
Esempio n. 10
0
        public StringSummary GetTypeReferenceStringSummary(ClrType referrerType, int fieldOffset, CancellationToken token = default)
        {
            var tallyByString = new Dictionary <string, ObjectTally>();

            ulong stringCount                 = 0;
            ulong stringByteCount             = 0;
            ulong totalManagedObjectByteCount = 0;
            long  charCount = 0;

            foreach (var seg in _heap.Segments)
            {
                var segType = seg.IsEphemeral
                    ? GCSegmentType.Ephemeral
                    : seg.IsLarge
                        ? GCSegmentType.LargeObject
                        : GCSegmentType.Regular;

                for (ulong refObj = seg.GetFirstObject(out ClrType referringType); refObj != 0; refObj = seg.NextObject(refObj, out referringType))
                {
                    if (referringType == null)
                    {
                        continue;
                    }

                    totalManagedObjectByteCount += referringType.GetSize(refObj);

                    if (!ReferenceEquals(referringType, referrerType))
                    {
                        continue;
                    }

                    token.ThrowIfCancellationRequested();

                    if (!_heap.ReadPointer(refObj + (ulong)fieldOffset, out var strObjRef) || strObjRef == 0)
                    {
                        continue;
                    }

                    var type = _heap.GetObjectType(strObjRef);
                    if (type == null)
                    {
                        continue;
                    }
                    var value = (string)type.GetValue(strObjRef);

                    charCount += value.Length;
                    stringCount++;

                    if (!tallyByString.TryGetValue(value, out var tally))
                    {
                        var size = type.GetSize(strObjRef);
                        tally = new ObjectTally(size);
                        tallyByString[value] = tally;
                    }

                    var strSeg     = _heap.GetSegmentByAddress(strObjRef);
                    int generation = strSeg.GetGeneration(strObjRef);
                    if (tally.Add(strObjRef, segType, generation))
                    {
                        stringByteCount += tally.InstanceSize;
                    }
                }
            }

            var uniqueStringCount     = tallyByString.Count;
            var stringCharCount       = tallyByString.Sum(s => s.Key.Length * (long)s.Value.Count);
            var uniqueStringCharCount = tallyByString.Keys.Sum(s => s.Length);
            var wastedBytes           = tallyByString.Values.Sum(t => (long)t.WastedBytes);
            var stringOverhead        = ((double)stringByteCount - (charCount * 2)) / stringCount;

            return(new StringSummary(
                       tallyByString.OrderByDescending(p => p.Value.WastedBytes)
                       .Select(
                           p => new StringItem(
                               p.Key,
                               (uint)p.Key.Length,
                               p.Value.InstanceSize,
                               p.Value.Addresses,
                               p.Value.CountBySegmentType,
                               p.Value.CountByGeneration)).ToList(),
                       totalManagedObjectByteCount,
                       stringByteCount,
                       (ulong)stringCharCount,
                       (ulong)uniqueStringCharCount,
                       stringCount,
                       (ulong)uniqueStringCount,
                       ulong.MaxValue, // TODO review
                       (ulong)wastedBytes,
                       (uint)Math.Round(stringOverhead)));
        }