I've got a c++ app that wraps large parts of code in try blocks. When I catch exceptions I can return the user to a stable state, which is nice. But I'm not longer receiving crash dumps. I'd really like to figure out where in the code the exception is taking place, so I can log it and fix it.
Being able to get a dump without halting the application would be ideal, but I'm not sure that's possible.
Is there some way I can figure out where the exception was thrown from within the catch block? If it's useful, I'm using native msvc++ on windows xp and higher. My plan is to simply log the crashes to a file on the various users' machines, and then upload the crashlogs once they get to a certain size.
It's possible to design your exceptions to include source file names & line numbers. In order to do so, you need to create a class derived from
std::exception
to contain the information. In the example below, I have a library of exceptions for my application includingmy_exception
. I also have atraced_error
which is a template exception class derived from my application-level exceptions. Thetraced_error
exception holds information about the filename & line number, and calls the application-level exception class'what()
method to get detailed error information.The output of this program is:
You could also redesign this so that the application-level exceptions derive from
traced_error
instead of the other way round, in case you would rather catch specific application-level exceptions. In yourcatch
, you can log the error to a log file & create a dump file using MiniDumpWriteDump().What you need is to analyze the stack to figure out where the exception came from. For msvc there is a lib called dbghelp.dll that can help you log out the exceptions. In general what I do is to log out a minidump file and use this to replay the issue beside using the right program database (pdb file). This works on a customer systems that do not come with source code or to whom you won't want to give pdbs.
You can write dumps using MiniDumpWriteDump function.
If you're using C++ exceptions, then you can simply include file/line/function information (so you'll see it as text if you call std::exception.what()) in any place where you throw that exception (using ____FUNCTION____, ____FILE____ and ____LINE____ macros).
If you're trying to catch OS exceptions, then crashing the application will be probably a better choice.
One trick that is compiler independent is to wrap the throw statement in a function. The function can perform other duties before throwing the exception, such as recording to a log file. It also makes a handy place to put a breakpoint. If you create a macro to call the function you can automatically include the
__FILE__
and__LINE__
where the throw occurred.This is possible with using SEH (structured exception handling). The point is that MSVC implements C++ exceptions via SEH. On the other hand the pure SEH is much more powerful and flexible.
That's what you should do. Instead of using pure C++ try/catch blocks like this:
You should wrap the inner code block
DoSomething
with the SEH block:That is, inside the C++ try/catch block we place another raw SEH block, which only dumps all the exceptions without catching them.
See here for an example of using MiniDumpWriteDump.