Example #1
0
        private void DumpHandles(int GroupOnly          = 0,
                                 string filterByType    = null,
                                 string filterByObjType = null)
        {
            Dictionary <string, int> categories = new Dictionary <string, int>();

            if (m_runtime.PointerSize == 8)
            {
                WriteLine("Handle           Object           Refs Type            Object Type");
            }
            else
            {
                WriteLine("Handle   Object   Refs Type            Object Type");
            }

            int i = 0;
            int c = 0;

            foreach (var handle in m_runtime.EnumerateHandles())
            {
                if (!categories.ContainsKey(handle.HandleType.ToString()))
                {
                    categories[handle.HandleType.ToString()] = 0;
                }
                categories[handle.HandleType.ToString()]++;
                ClrType obj = m_runtime.GetHeap().GetObjectType(handle.Object);

                if (
                    (String.IsNullOrEmpty(filterByType) || handle.HandleType.ToString().ToLowerInvariant().Contains(filterByType.ToLowerInvariant()))
                    &&
                    (String.IsNullOrEmpty(filterByObjType) || obj.Name.ToLowerInvariant().Contains(filterByObjType.ToLowerInvariant()))
                    )
                {
                    if (GroupOnly == 0)
                    {
                        Write("{0:%p} {1:%p}", handle.Address, handle.Object);
                        Write(" {0,4} {1,-15}", handle.RefCount, handle.HandleType);
                        Write(" {0}", obj.Name);
                        WriteLine("");
                    }
                    c++;
                }
                i++;
            }
            WriteLine("");
            WriteLine("{0,8:#,#} Objects Listed or met the criteria", c);
            if (c != i)
            {
                WriteLine("{0,8:#,#} Objects Skipped by the filter(s)", i - c);
            }
            WriteLine("");
            WriteLine("{0,8:#,#} Handle(s) found in {1} categories", i, categories.Keys.Count);
            foreach (var cat in categories.Keys)
            {
                Write("{0,8:#,#} ", categories[cat]);
                Write("<link cmd=\"!wcghandle -handletype {0}\">{0}</link>", cat);
                WriteLine(" found");
            }
            WriteLine("");
        }
Example #2
0
 private static void PrintGCHandles(ClrRuntime runtime, StreamWriter sw)
 {
     foreach (ClrHandle handle in runtime.EnumerateHandles())
     {
         string objectType = runtime.Heap.GetObjectType(handle.Object).Name;
         sw.WriteLine("{0,12:X} {1,12:X} {2,12} {3}", handle.Address, handle.Object, handle.HandleType, objectType);
     }
 }
Example #3
0
 private void DumpGcHandles(ClrRuntime runtime)
 {
     Log.Information("GC Handles:");
     foreach (var handle in runtime.EnumerateHandles())
     {
         var objectType = runtime.Heap.GetObjectType(handle.Object).Name;
         Log.Information("{address,12:X} {object,12:X} {type,12} {objectType}", handle.Address, handle.Object,
                         handle.Type, objectType);
     }
 }
Example #4
0
        // OUTPUT SAMPLE
        // ------------------
        // 201E53A10D0  201E5561360 System.String System.String
        // 201E53A10D8  201E5561360 System.String System.String
        // 201E53A10E0  201E5561360 System.String System.String
        // 201E53A10E8  201E5561360 System.String System.String
        // ------------------
        public void ShowGcHandles(ClrRuntime runtime)
        {
            var heap = runtime.Heap;

            foreach (ClrHandle handle in runtime.EnumerateHandles())
            {
                string objectType = heap.GetObjectType(handle.Object).Name;
                Console.WriteLine("{0,12:X} {1,12:X} {2,12} {3}", handle.Address, handle.Object, handle.Type, objectType);
            }
            Console.WriteLine();
        }
Example #5
0
        public void EnsureEnumerationStability()
        {
            // I made some changes to v4.5 handle enumeration to enumerate handles out faster.
            // This test makes sure I have a stable enumeration.
            using (DataTarget dt = TestTargets.GCHandles.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();

                List <ClrHandle> handles = new List <ClrHandle>(runtime.EnumerateHandles());

                int i = 0;
                foreach (var hnd in runtime.EnumerateHandles())
                {
                    Assert.Equal(handles[i++], hnd);
                }

                // We create at least this many handles in the test, plus the runtime uses some.
                Assert.True(handles.Count > 4);
            }
        }
Example #6
0
        public void EnsureAllItemsAreUnique()
        {
            // Making sure that handles are returned only once
            HashSet <ClrHandle> handles = new HashSet <ClrHandle>();

            using DataTarget dt      = TestTargets.GCHandles.LoadFullDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();

            foreach (ClrHandle handle in runtime.EnumerateHandles())
            {
                Assert.True(handles.Add(handle));
            }

            // Make sure we had at least one AsyncPinned handle
            Assert.Contains(handles, h => h.HandleKind == ClrHandleKind.AsyncPinned);
        }
Example #7
0
        public void EnsureAllItemsAreUnique()
        {
            // Making sure that handles are returned only once
            var handles = new HashSet <ClrHandle>();

            using (DataTarget dt = TestTargets.GCHandles.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();

                foreach (var handle in runtime.EnumerateHandles())
                {
                    Assert.IsTrue(handles.Add(handle));
                }

                // Make sure we had at least one AsyncPinned handle
                Assert.IsTrue(handles.Any(h => h.HandleType == HandleType.AsyncPinned));
            }
        }
        public void RuntimeTests(TestHost host)
        {
            // The current Linux test assets are not alpine/musl
            if (OS.IsAlpine)
            {
                throw new SkipTestException("Not supported on Alpine Linux");
            }
            var runtimeService = host.Target.Services.GetService <IRuntimeService>();

            Assert.NotNull(runtimeService);

            var contextService = host.Target.Services.GetService <IContextService>();

            Assert.NotNull(contextService);
            Assert.NotNull(contextService.GetCurrentRuntime());

            foreach (ImmutableDictionary <string, TestDataReader.Value> runtimeData in host.TestData.Runtimes)
            {
                if (runtimeData.TryGetValue("Id", out int id))
                {
                    IRuntime runtime = runtimeService.EnumerateRuntimes().FirstOrDefault((r) => r.Id == id);
                    Assert.NotNull(runtime);

                    runtimeData.CompareMembers(runtime);

                    ClrInfo clrInfo = runtime.Services.GetService <ClrInfo>();
                    Assert.NotNull(clrInfo);

                    ClrRuntime clrRuntime = runtime.Services.GetService <ClrRuntime>();
                    Assert.NotNull(clrRuntime);
                    Assert.NotEmpty(clrRuntime.AppDomains);
                    Assert.NotEmpty(clrRuntime.Threads);
                    Assert.NotEmpty(clrRuntime.EnumerateModules());
                    if (!host.DumpFile.Contains("Triage"))
                    {
                        Assert.NotEmpty(clrRuntime.EnumerateHandles());
                    }
                }
            }
        }
Example #9
0
        public void EnsureEnumerationStability()
        {
            // I made some changes to v4.5 handle enumeration to enumerate handles out faster.
            // This test makes sure I have a stable enumeration.
            using (DataTarget dt = TestTargets.GCHandles.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();

                List <ClrHandle> handles = new List <ClrHandle>();

                bool cont;
                do
                {
                    cont = false;
                    int i = 0;
                    foreach (var hnd in runtime.EnumerateHandles())
                    {
                        if (i > handles.Count)
                        {
                            break;
                        }

                        if (i == handles.Count)
                        {
                            cont = true;
                            handles.Add(hnd);
                            break;
                        }

                        Assert.AreEqual(handles[i++], hnd);
                    }
                } while (cont);

                // We create at least this many handles in the test, plus the runtime uses some.
                Assert.IsTrue(handles.Count > 4);
            }
        }
Example #10
0
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var crashDumpPath = "../../artefacts/core_20200503_003216";

            using (DataTarget dataTarget = DataTarget.LoadDump(crashDumpPath))
            {
                foreach (ClrInfo version in dataTarget.ClrVersions)
                {
                    Console.WriteLine("Found CLR Version: " + version.Version);

                    // This is the data needed to request the dac from the symbol server:
                    DacInfo dacInfo = version.DacInfo;
                    Console.WriteLine("Filesize:  {0:X}", dacInfo.IndexFileSize);
                    Console.WriteLine("Timestamp: {0:X}", dacInfo.IndexTimeStamp);
                    Console.WriteLine("Dac File:  {0}", dacInfo.PlatformSpecificFileName);

                    // If we just happen to have the correct dac file installed on the machine,
                    // the "LocalMatchingDac" property will return its location on disk:
                    string dacLocation = version.DacInfo.LocalDacPath;;
                    if (!string.IsNullOrEmpty(dacLocation))
                    {
                        Console.WriteLine("Local dac location: " + dacLocation);
                    }

                    ClrInfo    runtimeInfo = dataTarget.ClrVersions[0]; // just using the first runtime
                    ClrRuntime runtime     = runtimeInfo.CreateRuntime();

                    // You may also download the dac from the symbol server, which is covered
                    // in a later section of this tutorial.
                    foreach (ClrAppDomain domain in runtime.AppDomains)
                    {
                        Console.WriteLine("ID:      {0}", domain.Id);
                        Console.WriteLine("Name:    {0}", domain.Name);
                        Console.WriteLine("Address: {0}", domain.Address);
                        foreach (ClrModule module in domain.Modules)
                        {
                            Console.WriteLine("Module: {0}", module.Name);
                        }
                        foreach (ClrThread thread in runtime.Threads)
                        {
                            if (!thread.IsAlive)
                            {
                                continue;
                            }

                            Console.WriteLine("Thread {0:X}:", thread.OSThreadId);

                            foreach (ClrStackFrame frame in thread.EnumerateStackTrace())
                            {
                                Console.WriteLine("Stack Name: " + frame.ToString());
                                Console.WriteLine("{0,12:X} {1,12:X} {2}", frame.StackPointer, frame.InstructionPointer, frame);
                            }

                            Console.WriteLine();

                            Console.WriteLine("{0,12} {1,12} {2,12} {3,12} {4,4} {5}", "Start", "End", "CommittedMemory", "ReservedMemory", "Heap", "Type");
                            foreach (ClrSegment segment in runtime.Heap.Segments)
                            {
                                string type;
                                if (segment.IsEphemeralSegment)
                                {
                                    type = "Ephemeral";
                                }
                                else if (segment.IsLargeObjectSegment)
                                {
                                    type = "Large";
                                }
                                else
                                {
                                    type = "Gen2";
                                }

                                Console.WriteLine("{0,12:X} {1,12:X} {2,12:X} {3,12:X} {4,4} {5}", segment.Start, segment.End, segment.CommittedMemory, segment.ReservedMemory, segment.LogicalHeap, type);
                            }

                            foreach (var item in (from seg in runtime.Heap.Segments
                                                  group seg by seg.LogicalHeap into g
                                                  orderby g.Key
                                                  select new
                            {
                                Heap = g.Key,
                                Size = g.Sum(p => (uint)p.Length)
                            }))
                            {
                                Console.WriteLine("Heap {0,2}: {1:n0} bytes", item.Heap, item.Size);
                            }
                        }

                        foreach (var handle in runtime.EnumerateHandles())
                        {
                            string objectType = runtime.Heap.GetObjectType(handle.Object).Name;
                            Console.WriteLine("{0,12:X} {1,12:X} {2,12} {3}", handle.Address, handle.Object, handle.GetType(), objectType);
                        }


                        if (!runtime.Heap.CanWalkHeap)
                        {
                            Console.WriteLine("Cannot walk the heap!");
                        }
                        else
                        {
                            foreach (ClrSegment seg in runtime.Heap.Segments)
                            {
                                for (ulong obj = seg.FirstObjectAddress; obj != 0; obj = seg.GetNextObjectAddress(obj))
                                {
                                    ClrType type = runtime.Heap.GetObjectType(obj);

                                    // If heap corruption, continue past this object.
                                    if (type == null)
                                    {
                                        continue;
                                    }

                                    int size = type.StaticSize;
                                    Console.WriteLine("{0,12:X} {1,8:n0} {2,1:n0} {3}", obj, size, seg.GetGeneration(obj), type.Name);
                                }
                            }
                        }
                        //  https://github.com/microsoft/clrmd/blob/master/doc/WalkingTheHeap.md#walking-objects-without-walking-the-segments
                        if (!runtime.Heap.CanWalkHeap)
                        {
                            Console.WriteLine("Cannot walk the heap!");
                        }
                        else
                        {
                            foreach (ulong obj in runtime.Heap.EnumerateObjects())
                            {
                                ClrType type = runtime.Heap.GetObjectType(obj);

                                // If heap corruption, continue past this object.
                                if (type == null)
                                {
                                    continue;
                                }

                                int size = type.StaticSize;
                                Console.WriteLine("{0,12:X} {1,8:n0} {2,1:n0} {3}", obj, size, type.GCDesc, type.Name);
                            }
                        }
                    }
                }
            }
        }
Example #11
0
 public IEnumerable <HandleInfo> GetAllHandles()
 {
     return(runtime.EnumerateHandles().Select(h => new HandleInfo {
         ClrHandle = h
     }));
 }
Example #12
0
 public IEnumerable <ClrHandle> GCHandles()
 {
     return(_runtime.EnumerateHandles());
 }
Example #13
0
 public void EnumerateGCHandles(out IMDHandleEnum ppEnum)
 {
     ppEnum = new MDHandleEnum(m_runtime.EnumerateHandles());
 }
Example #14
0
        private void InspectProcess(int pId)
        {
            using (DataTarget target = DataTarget.AttachToProcess(pId, 10000))
            {
                ShowCLRRuntimeInformation(target);

                ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();

                LoadThreads(runtime);

                Dictionary <string, TypeEntry>   types       = new Dictionary <string, TypeEntry>();
                Dictionary <string, StringInfor> stringCount = new Dictionary <string, StringInfor>();

                ClrHeap heap = runtime.Heap;

                var finalizerQueueObjects = runtime.EnumerateFinalizerQueueObjectAddresses().ToList();
                var pinnedObjects         = runtime.EnumerateHandles().Where(h => h.IsPinned).Select(h => h.Object).ToList();
                var blockingObjects       = heap.EnumerateBlockingObjects().Select(x => x.Object).ToList();
                //var blockingObjects = runtime.Threads.SelectMany(x => x.BlockingObjects).Select(x => x.Object).ToList();

                foreach (ulong obj in heap.EnumerateObjects())
                {
                    ClrType type = heap.GetObjectType(obj);
                    var     size = type.GetSize(obj);
                    var     gen  = heap.GetGeneration(obj);
                    var     isInFinalizerQueue = finalizerQueueObjects.Contains(obj);
                    var     isPinned           = pinnedObjects.Contains(obj);
                    var     isBlocking         = blockingObjects.Contains(obj);

                    if (types.ContainsKey(type.Name))
                    {
                        types[type.Name].Count++;
                        types[type.Name].MinSize              = Math.Min(types[type.Name].MinSize, size);
                        types[type.Name].MaxSize              = Math.Max(types[type.Name].MaxSize, size);
                        types[type.Name].TotalSize           += size;
                        types[type.Name].Generation0         += gen == 0 ? 1 : 0;
                        types[type.Name].Generation1         += gen == 1 ? 1 : 0;
                        types[type.Name].Generation2         += gen == 2 ? 1 : 0;
                        types[type.Name].FinalizerQueueCount += isInFinalizerQueue ? 1 : 0;
                        types[type.Name].PinnedCount         += isPinned ? 1 : 0;
                        types[type.Name].BlockingCount       += isBlocking ? 1 : 0;
                    }
                    else
                    {
                        types[type.Name] = new TypeEntry
                        {
                            Name                = type.Name,
                            Count               = 1,
                            MinSize             = size,
                            MaxSize             = size,
                            TotalSize           = size,
                            Generation0         = gen == 0 ? 1 : 0,
                            Generation1         = gen == 1 ? 1 : 0,
                            Generation2         = gen == 2 ? 1 : 0,
                            FinalizerQueueCount = isInFinalizerQueue ? 1 : 0,
                            PinnedCount         = isPinned ? 1 : 0,
                            BlockingCount       = isBlocking ? 1 : 0,
                        };
                    }

                    if (type.IsString)
                    {
                        var text = (string)type.GetValue(obj);

                        if (stringCount.ContainsKey(text))
                        {
                            stringCount[text].Count++;
                            stringCount[text].Generation0 += gen == 0 ? 1 : 0;
                            stringCount[text].Generation1 += gen == 1 ? 1 : 0;
                            stringCount[text].Generation2 += gen == 2 ? 1 : 0;
                        }
                        else
                        {
                            stringCount[text] = new StringInfor
                            {
                                Text        = text,
                                Count       = 1,
                                Generation0 = gen == 0 ? 1 : 0,
                                Generation1 = gen == 1 ? 1 : 0,
                                Generation2 = gen == 2 ? 1 : 0,
                            };
                        }
                    }
                }

                var sortOrder = heapObjectsGrid.SortOrder == SortOrder.Ascending ?
                                ListSortDirection.Ascending : ListSortDirection.Descending;
                var sortCol = heapObjectsGrid.SortedColumn;

                int rowcount = 0;
                heapObjectsGrid.Rows.Clear();
                foreach (var val in types.Where(x => x.Value.Count > 1))
                {
                    var             infor   = val.Value;
                    DataGridViewRow gridrow = new DataGridViewRow();
                    gridrow.DefaultCellStyle.SelectionBackColor = Color.Black;
                    if (rowcount % 2 > 0)
                    {
                        gridrow.DefaultCellStyle.BackColor = Color.AliceBlue;
                    }
                    rowcount++;

                    DataGridViewTextBoxCell name = new DataGridViewTextBoxCell();
                    name.Value = infor.Name;
                    gridrow.Cells.Add(name);

                    DataGridViewTextBoxCell count = new DataGridViewTextBoxCell();
                    count.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    count.Style.Format    = "n0";
                    count.Value           = infor.Count;
                    gridrow.Cells.Add(count);

                    DataGridViewTextBoxCell minSize = new DataGridViewTextBoxCell();
                    minSize.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    minSize.Style.Format    = "n0";
                    if (infor.MinSize >= 85000)
                    {
                        minSize.Style.ForeColor = Color.Orange;
                        minSize.ToolTipText     = "Large Object Heap";
                    }
                    minSize.Value = infor.MinSize;
                    gridrow.Cells.Add(minSize);

                    DataGridViewTextBoxCell maxSize = new DataGridViewTextBoxCell();
                    maxSize.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    maxSize.Style.Format    = "n0";
                    if (infor.MaxSize >= 85000)
                    {
                        maxSize.Style.ForeColor = Color.Orange;
                        maxSize.ToolTipText     = "Large Object Heap";
                    }
                    maxSize.Value = infor.MaxSize;
                    gridrow.Cells.Add(maxSize);

                    DataGridViewTextBoxCell totalSize = new DataGridViewTextBoxCell();
                    totalSize.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    totalSize.Style.Format    = "n0";
                    totalSize.Value           = infor.TotalSize;
                    gridrow.Cells.Add(totalSize);

                    DataGridViewTextBoxCell generation0 = new DataGridViewTextBoxCell();
                    generation0.Value           = infor.Generation0;
                    generation0.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    generation0.Style.Format    = "n0";
                    gridrow.Cells.Add(generation0);

                    DataGridViewTextBoxCell generation1 = new DataGridViewTextBoxCell();
                    generation1.Value           = infor.Generation1;
                    generation1.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    generation1.Style.Format    = "n0";
                    gridrow.Cells.Add(generation1);

                    DataGridViewTextBoxCell generation2 = new DataGridViewTextBoxCell();
                    generation2.Value           = infor.Generation2;
                    generation2.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    generation2.Style.Format    = "n0";
                    gridrow.Cells.Add(generation2);

                    DataGridViewTextBoxCell finalizerQueue = new DataGridViewTextBoxCell();
                    finalizerQueue.Value           = infor.FinalizerQueueCount;
                    finalizerQueue.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    finalizerQueue.Style.Format    = "n0";
                    gridrow.Cells.Add(finalizerQueue);

                    DataGridViewTextBoxCell pinned = new DataGridViewTextBoxCell();
                    pinned.Value           = infor.PinnedCount;
                    pinned.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    pinned.Style.Format    = "n0";
                    gridrow.Cells.Add(pinned);

                    DataGridViewTextBoxCell blocking = new DataGridViewTextBoxCell();
                    blocking.Value           = infor.BlockingCount;
                    blocking.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    blocking.Style.Format    = "n0";
                    gridrow.Cells.Add(blocking);

                    heapObjectsGrid.Rows.Add(gridrow);
                }

                heapObjectsGrid.Columns[1].HeaderCell.ToolTipText = $"Total: { types.Values.Sum(x => x.Count).ToString("N0")} objects";
                heapObjectsGrid.Columns[4].HeaderCell.ToolTipText = $"Total: {types.Values.Sum(x => (long)x.TotalSize).ToString("N0")} bytes";

                if (sortCol != null)
                {
                    heapObjectsGrid.Sort(sortCol, sortOrder);
                }

                // Strings Grid View:
                rowcount = 0;
                stringsGrid.Rows.Clear();
                foreach (var str in stringCount)
                {
                    DataGridViewRow gridrow = new DataGridViewRow();
                    gridrow.DefaultCellStyle.SelectionBackColor = Color.Black;
                    if (rowcount % 2 > 0)
                    {
                        gridrow.DefaultCellStyle.BackColor = Color.AliceBlue;
                    }
                    rowcount++;

                    DataGridViewTextBoxCell name = new DataGridViewTextBoxCell();
                    name.Value = str.Key;
                    gridrow.Cells.Add(name);

                    DataGridViewTextBoxCell length = new DataGridViewTextBoxCell();
                    length.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    length.Style.Format    = "n0";
                    length.Value           = str.Key.Length;
                    gridrow.Cells.Add(length);

                    DataGridViewTextBoxCell count = new DataGridViewTextBoxCell();
                    count.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    count.Style.Format    = "n0";
                    count.Value           = str.Value.Count;
                    gridrow.Cells.Add(count);

                    DataGridViewTextBoxCell generation0 = new DataGridViewTextBoxCell();
                    generation0.Value           = str.Value.Generation0;
                    generation0.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    generation0.Style.Format    = "n0";
                    gridrow.Cells.Add(generation0);

                    DataGridViewTextBoxCell generation1 = new DataGridViewTextBoxCell();
                    generation1.Value           = str.Value.Generation1;
                    generation1.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    generation1.Style.Format    = "n0";
                    gridrow.Cells.Add(generation1);

                    DataGridViewTextBoxCell generation2 = new DataGridViewTextBoxCell();
                    generation2.Value           = str.Value.Generation2;
                    generation2.Style.Alignment = DataGridViewContentAlignment.BottomRight;
                    generation2.Style.Format    = "n0";
                    gridrow.Cells.Add(generation2);

                    stringsGrid.Rows.Add(gridrow);
                }
            }
        }
Example #15
0
 /// <summary>
 ///     Enumerates a list of GC handles currently in the process.  Note that this list may be incomplete
 ///     depending on the state of the process when we attempt to walk the handle table.
 /// </summary>
 /// <returns>The list of GC handles in the process, NULL on catastrophic error.</returns>
 /// <inheritdoc />
 public IEnumerable <IClrHandle> EnumerateHandles() => Runtime.EnumerateHandles().Select(Converter.Convert);