Opening a Crash Dump File (Automating Crash Dump Analysis Part 1)
So let's assume for the moment that you have a collection of crash dump files from your team's application. These files may be generated from your stress tests, betas, etc. But where they come from really isn't important, what is important is that we want some way to dig into these files and gather information, evaluate priority, etc., without having to manually open each one in the debugger.
Once you install WinDBG, you are given a COM interface allowing you to integrate debugging functionality into your own application. We can then use this to drive the task of opening and querying a crash dump file. When installing, just make sure you select the SDK option, which will give you the header files you will need. To make you life happier, you should also install the symbol packages for all the Operating Systems you support (also available from the above link) - doing so will give you function names from system binaries in the stack traces we will eventually create.
To start with we will go over the minimum code to initialize the debugging library and open a crash dump file.
#include "dbgeng.h" // windbg header
int __cdecl main(int argc, char* argv)
HRESULT hr = E_FAIL;
IDebugClient *client = NULL;
IDebugControl *control = NULL;
IDebugSymbols *symbols = NULL;
// Initialize COM
hr = CoInitialize(NULL);
// Create the base IDebugClient object
hr = DebugCreate(__uuidof(IDebugClient), (LPVOID*)&client);
// from the base, create the Control and Symbols objects
hr = client->QueryInterface(__uuidof(IDebugControl), (LPVOID*)&control);
hr = client->QueryInterface(__uuidof(IDebugSymbols), (LPVOID*)&symbols);
// we can supplement the _NT_SYMBOL_PATH environment variable
// by adding a path here
// the debugger will need to look at the actual binaries
// so provide the path to the exsecutable files
// open the crash dump
hr = client->OpenDumpFile("c:\\myApp\\myApp.dmp");
// wait for the engine to finish processing
// cleanup and destroy the objects
symbols = NULL;
control = NULL;
client = NULL;
// cleanup COM
The semicolon separated path you pass into SetSymbolPath() should provide the location of the .pdb symbol files for all binaries consumed by your application. The same goes for the paths to the actual binary files themselves, which is passed in via SetImagePath(). Without the symbols or the actual binaries, your investigations won't be as successful.
· DebugCreate() which is used to instantiate the initial IDebugClient interface.