Tuesday, May 21, 2013

Traversing the GC Heap with ClrMd

ClrMd is a newly released diagnostic library that wraps the CLR's undocumented data access interfaces (a.k.a. "DAC") in a friendly managed API. The underlying interfaces are what debugger extensions like SOS and SOSEX use to implement various diagnostic features, including enumerating the managed heap, detecting deadlocks, inspecting object contents, and dumping type/method information.

Given my personal and professional interest in debugging tools and techniques, ClrMd is an incredible tool – I can now implement my own diagnostic features without relying on undocumented interfaces or parsing text output from debugging extensions (which also requires going through a debugger in another process).

To pique your interest, I whipped together a quick sample illustrating how commands like !DumpHeap, !DumpObj, and !GCRoot can be implemented using ClrMd. This is a sample, so there is clearly room for optimization and the code could be cleaner, but the ability to cram so much functionality in 200 lines of C# code is nothing short of overwhelming.

Without further ado, here's some output (slightly formatted for clarity):

$ GcRoot.exe d:\temp\leak.dmp 
> dumpobjects Schedule 
31cae98 MemoryLeak.Schedule 
31cd5f0 MemoryLeak.Schedule 
31cfd48 MemoryLeak.Schedule 
31d24a0 MemoryLeak.Schedule 
31d4bf8 MemoryLeak.Schedule 
31d7350 MemoryLeak.Schedule 
31d9aa8 MemoryLeak.Schedule 
31dc200 MemoryLeak.Schedule 
31de958 MemoryLeak.Schedule 
31e10b0 MemoryLeak.Schedule 
31e3808 MemoryLeak.Schedule 
31e5f60 MemoryLeak.Schedule 
31e86b8 MemoryLeak.Schedule 
> dumpobject 31d9aa8 
System.Byte[] _data = 31d9ac0 
> gcroot 31d9aa8 


QR: Inline image 1