Getting useful C++ exception information from Visual Studio

Trying to get useful information about a C++ exception from a crash dump in Visual Studio is often an exercise in frustration, with useless dialogs like this being typical:

In this post I’m going to present two ways of getting more information from the exception. The second method is more reliable and easier to use, but also requires a minor code change.

The first thing to do is find the _CxxThrowException frame in the stack trace. This contains the information you need to find the exception object.

In the local variables window navigate to ThisExceptionparamspExceptionObject. This carries the pointer to the object that was thrown.

Getting the type of the exception object may take a bit of guesswork, but can probably be determined by looking at pThrowInfo, or at where the exception was thrown in the code. Otherwise, the std::exception base class is usually fine anyway. In this case it is std::system_error.

Copy the address into the watch window and add an appropriate cast. You now have all the exception information you need! You may need to switch to the frame in which the exception was thrown in your application for the cast to work, otherwise the debugger won’t know about the type you specified.

We can see here that we failed to open some super-important file with an error code of 3, which we know means the file doesn’t exist.

Unfortunately, sometimes you might find your exception information has been optimised away:

If this happens you’re pretty much out of luck for any existing crash dumps, but if you switch to method two then future dumps should be more useful.

The second method involves installing your own unhandled exception filter and forcing the process to exit immediately, while still preserving the exception information. I generally prefer this method because it is more reliable and easier to work with.

First thing to do is define your unhandled exception filter:

LONG WINAPI unhandledExceptionFilter(EXCEPTION_POINTERS *exInfo)
{
    RaiseFailFastException(exInfo->ExceptionRecord,
        exInfo->ContextRecord, 0);
    return EXCEPTION_CONTINUE_SEARCH; // Not reached
}

int main()
{
    SetUnhandledExceptionFilter(unhandledExceptionFilter);

    // ...
}

Here we use RaiseFailFastException to kill the process immediately and invoke Windows Error Reporting to create your crash dump.  This bypasses whatever the C runtime does which causes it to lose your exception information and you get a much more useful dialog when you enter the debugger:

This time we’ve got both the type of the exception and its address (which in this case is 0x0028FD38). Put this in your watch window in the same way as described before and you will have your exception object!

Bonus: You can get WER to generate full crash dumps when your program crashes and you don’t have a debugger attached by creating the DWORD registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\DumpType and setting it to 1 (for mini dumps) or 2 (for full dumps). This will create a dump file in %LOCALAPPDATA%\CrashDumps when your program crashes which you can import into Visual Studio. This is particularly useful when you are testing on someone else’s machine where you can’t debug directly.

This entry was posted in programming. Bookmark the permalink.

One Response to Getting useful C++ exception information from Visual Studio

  1. Pingback: Getting useful C++ exception information from Visual Studio | Musings by Chris Spencer | Itsaat

Comments are closed.