Analyze your memory dumps in C# with DynaMD

Kevin Gosse
2 min readJul 16, 2021

Whenever you need to analyze complex structures in a .NET memory dump, the WinDbg scripting API quickly shows its limits. In those cases, you can instead use the ClrMD library, that will give you everything you need to inspect the memory dump from C# code.

Not everything is perfect however, and sometimes I feel like the ClrMD syntax does not feel “natural” enough. To take one concrete example, for an investigation I had to retrieve the URLs of the pending HTTP requests in a memory dump. To do so, I needed to:

With ClrMD, that code would look like:

I feel like those repeated ReadObjectField calls add a lot of noise, and accessing the array is not straightforward.

To make all of this easier, I wrote the DynaMD library. This is a helper that runs on top of ClrMD, and leverages the C# dynamic keyword to expose the structures in a much more fluent way. When rewritten with DynaMD, the previous code becomes:

Of course it’s always a matter of personal preference, but I find this version much easier to write and read.

So, what is DynaMD capable of?

Introduction to DynaMD

The first step is of course to install the nuget package. The versions 1.0.8+ use ClrMD 2.*, you can use a previous version if for some reason you need ClrMD 1.*.

Then, there are multiple ways to retrieve a dynamic proxy to an object:

proxy is dynamic, so you don’t get any autocompletion. But, knowing the structure of the object, you can access any field just like you would with a “real” object:

Only fields are supported, but automatic properties are translated:

At some point, you’ll probably need to materialize the value of a field. This is done automatically for primitive types:

DynaMD also supports explicit conversion to string or blittable structs:

If you don’t know what “blittable structs” are, you can think of them as “any object that is stored as a single chunk of consecutive memory”. In other words, a blittable struct in C# would be a struct that only contains primitive types and other blittable structs. No references.

When dealing with arrays, you can directly enumerate the contents, get the length, or use an indexer:

To retrieve the address of a proxified object, explicitly cast it to ulong. Also, calling .ToString() on a proxy will return the address encoded in hexadecimal:

To retrieve the instance of ClrType, call GetClrType():

That’s all the library is capable of doing for now, but this should be enough to cover most scenarios. I’m still working on an experimental branch that would allow to cast a proxy to any reference type, I hope I’ll be able to release something in the coming months.

Feel free to contribute or report bugs on the GitHub repository!

--

--

Kevin Gosse

Software developer at Datadog. Passionate about .NET, performance, and debugging.