Prolific Usage of MiniDumpWriteDump (Automating Crash Dump Analysis Part 0)


As a precursor to a series on programmatically querying crash dump files, I wanted to first talk about the MiniDumpWriteDump function.


 


You don't necessarily need to wait for your application to crash in order to generate a memory dump. As soon as you detect something bad happening, you can call MiniDumpWriteDump yourself and generate a crash dump file on the fly. If your application likes to eat exceptions or ignore error codes, or important asserts fire, or special test cases fail, then this is a great place to start collecting failure data for offline analysis.


 


And to make it super easy for you, I've created a helper function which will generate a filename based on the computer's name along with the date and time, then invoke the crash dump generator.


 



#include <dbghelp.h>


 


HRESULT GenerateCrashDump(MINIDUMP_TYPE flags, EXCEPTION_POINTERS *seh=NULL)


    {


    HRESULT error = S_OK;


 


    // get the time


    SYSTEMTIME sysTime = {0};


    GetSystemTime(&sysTime);


 


    // get the computer name


    char compName[MAX_COMPUTERNAME_LENGTH + 1] = {0};


    DWORD compNameLen = ARRAYSIZE(compName);


    GetComputerNameA(compName, &compNameLen);


 


    // build the filename: APPNAME_COMPUTERNAME_DATE_TIME.DMP


    char path[MAX_PATH] = {0};


    sprintf_s(path, ARRAYSIZE(path),


        "c:\\myapp_%s_%04u-%02u-%02u_%02u-%02u-%02u.dmp",


        compName, sysTime.wYear, sysTime.wMonth, sysTime.wDay,


        sysTime.wHour, sysTime.wMinute, sysTime.wSecond);


 


    // open the file


    HANDLE hFile = CreateFileA(path,


        GENERIC_READ|GENERIC_WRITE,


        FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,


        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);


 


    if(hFile == INVALID_HANDLE_VALUE)


        {


        error = GetLastError();


        error = HRESULT_FROM_WIN32(error);


        return error;


        }


 


    // get the process information


    HANDLE hProc = GetCurrentProcess();


    DWORD procID = GetProcessId(hProc);


 


    // if we have SEH info, package it up


    MINIDUMP_EXCEPTION_INFORMATION sehInfo = {0};


    MINIDUMP_EXCEPTION_INFORMATION *sehPtr = NULL;


    if(seh)


        {


        sehInfo.ThreadId = GetCurrentThreadId();


        sehInfo.ExceptionPointers = seh;


        sehInfo.ClientPointers = FALSE;


        sehPtr = &sehInfo;


        }


 


    // generate the crash dump


    BOOL result = MiniDumpWriteDump(hProc, procID, hFile,


        flags, sehPtr, NULL, NULL);


 


    if(!result)


        {


        error = (HRESULT)GetLastError(); // already an HRESULT


        }


 


    // close the file


    CloseHandle(hFile);


 


    return error;


    }


 


Sample call:



    GenerateCrashDump((MINIDUMP_TYPE)


        (MiniDumpNormal |


        MiniDumpWithHandleData |


        MiniDumpWithUnloadedModules),


        NULL);


 


If you happen to have OS exception information available (via __try/__except), then you will definitely want to pass in the EXCEPTION_POINTERS information. This will embed important and detailed information about the exception into the crash dump.



And if you want to get really fancy, you can embed additional (custom) information via the 2nd to last parameter to MiniDumpWriteDump. For example, if your application is consuming external documents or information, it can be very handy to have this information (or metadata about it) accessible when diagnosing crash dumps after the fact.


 

Comments (4)
  1. So let’s assume for the moment that you have a collection of crash dump files from your team’s application.

  2. So now that we have a memory dump file , and know how to open it , we will want to pull some useful data

  3. For a reference, here are some links to the previous parts in this series: · Prolific Usage of MiniDumpWriteDump

  4. Marc Durdin says:

    It's worth noting that this helper function will usually not generate valid a call stack for the thread from which it is called, if no EXCEPTION_POINTERS info is provided.  One simple fix is to just create a separate worker thread to call MiniDumpWriteDump from and then wait for it to complete, within this helper function…

Comments are closed.

Skip to main content