Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get stack trace from uncaught exception?

I realise this will be platform specific: is there any way to get a stack trace from an uncaught C++ exception, but from the point at which the exception is thrown?

I have a Windows Structured Exception Handler to catch access violations, etc. and generate a minidump. But of course that won't get called in the event of termination due to an uncaught C++ exception, and so there is no crash dump.

I'm looking for a Windows solution at the moment (no matter how dirty!), but would like to hear about other platforms if possible.

Thanks.

like image 653
Steve Folly Avatar asked Dec 22 '22 07:12

Steve Folly


2 Answers

We implemented MiniDumps for unhandled exceptions in our last title using the information from this site:

http://beefchunk.com/documentation/sys-programming/os-win32/debug/www.debuginfo.com/articles/effminidumps.html

And to catch the unhandled exceptions on windows have a look at:

SetUnhandledExceptionFilter (http://msdn.microsoft.com/en-us/library/ms680634%28VS.85%29.aspx).

As an aisde, we spent a lot of time experimenting with the different levels of minidump until we settled on one. This proved to be of no real use in real world crashes as we had no idea what they would be at the time the minidumps were implemented. It's very application specific, and also crash specific, so my recommendation is to add the minidump handler as early as possible, it will grow with the project and through QA and it will be a life saver at somepoint (and hopefully out in the real world too).

like image 78
Danny Parker Avatar answered Dec 24 '22 22:12

Danny Parker


You can use the try-except Statement to "convert" a C++ exception to a structured exception (out of which you can then get a nice stack trace). Consider this:

// Your function to get a backtrace from a CONTEXT
const char *readBacktrace( CONTEXT &ctx );

extern "C"
static DWORD exceptFilter( struct _EXCEPTION_POINTERS* exInf )
{
    OutputDebugStringA( readBacktrace( *exInf->ContextRecord ) );
    return EXCEPTION_EXECUTE_HANDLER;
}

try {
  // your C++ code which might yield exceptions
} catch ( ... ) {
  // In case a C++ exception occurs, raise a structured exception and catch it    immediately
  // so that we get a CONTEXT object which we can use to generate a stack trace.
  __try {
    RaiseException( 1, 0, 0, NULL );
  } __except( exceptFilter( GetExceptionInformation() ) ) {
  }
}

This is a little clumsy, but the nice thing is that you can put the __try { } __except() { } part into a general purpose dumpStackTrace() function. You can then yield stack traces from any point in your program, as you like.

like image 45
Frerich Raabe Avatar answered Dec 24 '22 20:12

Frerich Raabe