Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Background Info


using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Diagnostics.Runtime;

namespace CLRMD_Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("ClrMD Demo");
            
            // https://github.com/Microsoft/clrmd/blob/master/Documentation/GettingStarted.md
            // https://github.com/Microsoft/clrmd/blob/master/Documentation/ClrRuntime.md
            var path = @"C:\Users\Owner\Downloads\__Matt__\HelloWorld.DMP";
            using (DataTarget dataTarget = DataTarget.LoadCrashDump(path))
            {
                EnumerateVersions(dataTarget.ClrVersions);
                
                ClrInfo runtimeInfo = dataTarget.ClrVersions[0];  // just using the first runtime
                ClrRuntime runtime = runtimeInfo.CreateRuntime();
                
                // AppDomains
                Console.WriteLine("AppDomains:"); 
                foreach (ClrAppDomain domain in runtime.AppDomains)
                {
                    Console.WriteLine("  ID:      {0}", domain.Id);
                    Console.WriteLine("  Name:    {0}", domain.Name);
                    Console.WriteLine("  Address: {0}", domain.Address);
                }
                Console.WriteLine("");
                
                // Walking the stack
                foreach (ClrThread thread in runtime.Threads)
                {
                    if (!thread.IsAlive)
                        continue;

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

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

                    Console.WriteLine();
                }
                
                // CLR Memory Regions
                foreach (var region in (from r in runtime.EnumerateMemoryRegions()
                        where r.Type != ClrMemoryRegionType.ReservedGCSegment
                        group r by r.Type into g
                        let total = g.Sum(p => (uint)p.Size)
                        orderby total descending
                        select new
                        {
                            TotalSize = total,
                            Count = g.Count(),
                            Type = g.Key
                        }))
                {
                    Console.WriteLine("{0,6:n0} {1,12:n0} {2}", region.Count, region.TotalSize, region.Type.ToString());
                }
            }
        }
        
        private static void EnumerateVersions(IList<ClrInfo> versions)
        {
            foreach (ClrInfo version in versions)
            {
                Console.WriteLine("Found CLR Version: " + version.Version.ToString());

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

                // 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.LocalMatchingDac;
                if (!string.IsNullOrEmpty(dacLocation))
                    Console.WriteLine("Local dac location: " + dacLocation);

                // You may also download the dac from the symbol server, which is covered
                // in a later section of this tutorial.
            }
        }
    }
}

Challenges

Useful Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment