Getting the Crash Details from a .DMP File (Automating Crash Dump Analysis Part 3)

Aside from a stack trace (the "where"), you probably want to know something about the crash (the "why" or the "how"). With the code below, we can query some of the basic details about what happened. From this we will at least be able to determine if the application attempted to write to a protected page, or if it decided to feel the effects of a division by zero.

 

HRESULT DumpEvent(IDebugControl *control, IDebugSymbols *symbols)

    {

    union ExtraInfo

        {

        DEBUG_LAST_EVENT_INFO_EXCEPTION exceptionInfo;

        // as needed, we can add more of the

        // DEBUG_LAST_EVENT_INFO_xyz structs here

        };

 

    HRESULT hr = S_OK;

    ULONG type = 0;

    ULONG procID = 0;

    ULONG threadID = 0;

    ExtraInfo extraInfo;

    ULONG extraInfoUsed = 0;

    char description[80] = {0};

 

    ULONG bugCheckCode = 0;

    ULONG64 bugCheckArgs[4] = {0};

 

    ZeroMemory(&extraInfo, sizeof(extraInfo));

 

    printf("\nFault Information\n");

 

    // look for Bug Check data

    hr = control->ReadBugCheckData(&bugCheckCode, &bugCheckArgs[0], &bugCheckArgs[1],

        &bugCheckArgs[2], &bugCheckArgs[3]);

 

    if(SUCCEEDED(hr))

        {

        printf(" Bug Check: %X (0x%08X, 0x%08X, 0x%08X, 0x%08X)\n",

            bugCheckCode, bugCheckArgs[0], bugCheckArgs[1],

            bugCheckArgs[2], bugCheckArgs[3]);

        }

 

    // get the fault information

    hr = control->GetLastEventInformation(&type, &procID, &threadID,

        &extraInfo, sizeof(extraInfo), &extraInfoUsed, description,

        ARRAYSIZE(description)-1, NULL);

 

    if(FAILED(hr))

        goto cleanup;

 

    printf(" Description: %s\n", description);

 

    // if we hit an exception, and we understand the type of exception, write

    // out some additional information

    if((type == DEBUG_EVENT_EXCEPTION) &&

        (extraInfoUsed >= sizeof(extraInfo.exceptionInfo)))

        {

        EXCEPTION_RECORD64 *er = &extraInfo.exceptionInfo.ExceptionRecord;

        printf(" Type: %s\n", GetExceptionName(er->ExceptionCode));

 

        if(er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||

            er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR)

           {

            if(er->ExceptionInformation[0] == 0)

                printf(" Read at: 0x%08X\n", er->ExceptionInformation[1]);

            else if(er->ExceptionInformation[0] == 1)

                printf(" Write at: 0x%08X\n", er->ExceptionInformation[1]);

            else if(er->ExceptionInformation[0] == 8)

                printf(" User Mode Fault: 0x%08X\n", er->ExceptionInformation[1]);

            }

        }

 

    cleanup:

 

    return hr;

    }

 

The GetExceptionName function is a simple helper that you can provide, which just transforms the exception defines into human readable strings.

MSDN References

· ReadBugCheckData

· GetLastEventInformation

· EXCEPTION_RECORD