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.
}
}
}
}