Some time ago Sasha Goldstein wrote on his blog a post about a new open-source tool he created: minidumper. The idea is great and allows you to create more compact memory dumps for .NET processes. I completely agree with Sasha that most of the time when you are working with .NET processes memory dumps you are focused on .NET memory heap. All native elements are usually not necessary and take a lot of space in dumps. Having said that, I need to admit that there were times when those native parts were invaluable in my diagnosis, such as diagnosing native memory leaks (when using pinvoke) or handle leaks. But those are quite rare and in such situations we have no choice but to use the full memory dumps. For all other .NET problems you are welcome to use minidumper. If you are interested in minidumper internals there is another post on Sasha’s blog which explains them very well.
Although I’ve fallen in love with minidumper at first sight, there were things I was missing. I am used to creating dumps with procdump – its command line is for me an unwritten standard for tools of this kind. And I badly wanted to have some of its features in minidumper. One of them was an option to create a memory dump when an exception occurs (both 1st and 2nd chance) or when a process terminates. So I decided to improve this tool. This was about 4 months ago 🙂 My idea was quite simple – I wanted to extend the usage of Microsoft.Diagnostics.Runtime in minidumper and instead of using the LiveDataReader
start using the full-featured DebuggerDataReader. I must say the process of switching was much much harder than I expected and I didn’t manage to finish it (as you may see in the repository history there was about two months break when I rested from the COM hell I run into). You may ask: why I wanted to switch? Well, LiveDataReader
has no option to control a process, it even does not receive any events about what’s happening in the process. It just attaches to the process, reads and parses its memory and allows you to query the CLR structures. In order to get notifications about exceptions or about the process termination I needed to have a debugger loop. To be more precise, it must have been a debugger loop which is interactive with the process (explicitly breaking the process execution and forcing it to wait till the dump is done). As I stated previously I failed to do that with the Microsoft.Diagnostics.Runtime API. This API gives you a lot of possibilities (it depends deeply on the dbgeng.dll API) when it comes to debugging a process, but at the same time it adds additional layers to the native Win32 Debug API and makes it harder to investigate problems you might run into when writing a debugger. One of such problems (the straw which broke the camel’s back) was that I couldn’t find a way to detach from a process I started under the debugger without killing it on the debugger exit. Procdump does that so I knew it was possible. I found the DebugSetProcessKillOnExit function, but it seemed that it does not affect the way dbgeng works in any way. And at that time I left the project for better times. About two weeks ago an idea struck me: why not use the Win32 Debug API and leave LiveDataReader
untouched? With Win32 Debug API I would be able to control the process, listen to events and when an interesting event comes (such as an exception or a process terminate event) create LiveDataReader
and use the original Sasha’s code to generate the dump (this is actually the recommended way to use the LiveMemoryDump
). And this approach seems to be working! I used API mappings from the vschromium – they have a lot of native Win32 methods nicely mapped and organized. The options I added to the original minidumper are:
- a possibility to create dumps on the 1st and the 2nd chance exceptions with the exception type filtering
- a possibility to create a dump on the process terminate event
- a possibility to limit the number of dumps to be done (with default set to one)
- a possibility to start a process under minidumper and wait for events
- a possibility to run the debugee process in a seperate console window (this one is missing in procdump! :))
- a nice welcome screen which resembles the one of procdump 🙂
This is a sample session which start a Test.exe process and generates at maximum two dumps on the first chance exceptions:
PS Debug> .\MiniDumper.exe -mh -e1 -n2 -x c:\temp C:\temp\Test.exe MiniDumper - writes .NET process dump files Copyright (C) 2015 Sasha Goldstein (@goldshtn) With contributions from Sebastian Solnica (@lowleveldesign) Process: Test (11820) Exception monitor: First Chance+Unhandled Exception filter: * Dump folder: c:\temp Number of dumps: 2 Dump filename/mask: PROCESSNAME_YYMMDD_HHMMSS Terminal monitor: Disabled Debug output: Disabled Press Ctrl-C to end monitoring without terminating the process. [07:21.51] Exception: E0434352.System.Exception ("test") [07:21.51] Dumping process memory to file: c:\temp\Test_151221_072151.dmp exception: 0 [07:21.51] Exception: E0434352.System.Exception ("test") [07:21.51] Dumping process memory to file: c:\temp\Test_151221_072151_1.dmp Number of dumps exceeded the specified limit - detaching. exception: 1 exception: 2 exception: 3 exception: 4 exception: 5 PS Debug>
While running minidumper you can always safely detach by pressing Ctrl+C and the debugee process should not be terminated. I still consider minidumper a work in progress and I have several ideas I would like to implement, such as: process cloning, dumps on performance counter values, self-extracting x64 version and some others. It may take some time to do that, but stay tuned 🙂
One thing to remember: always run the minidumper version which has the same bitness as the debugee process. Otherwise you will receive errors like: The request is not supported. (Exception from HRESULT: 0x80070032)
or Dac architecture mismatch!
.
You may download the binaries from my fork: https://github.com/lowleveldesign/minidumper/releases the release page. If you find any issues running minidumper please let me know. Happy debugging 🙂
Do I understand it correctly that I can run my console application through “your” Minidumper and when it crashes I will get a dump of memory, right? I’m still new to this, but this would really help me a lot on my current assignment.. Btw. Do I need any special Windows Security permissions or be in some group to be able to use it?
Hi Ondrej,
Sorry for a delay with my response. And yes, you can run your console application through Minidumper and the dump will be generated – you would need a debug permission in Windows. Also there is still a memory corruption bug for 64-bit dumps which I haven’t yet time to investigate. So please don’t try this bitness on production yet. I will let you know when the fix is ready.
Best,
Sebastian