Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get a stack trace for un-handled (Objective) C++ exceptions?

I'm developing an iOS application that has recently grown a large C++ base. C++ is not my forte, and I'm getting frustrated by exceptions. What I'm looking for is a way to get a stack track to the site of an (un-handled) exception throw. I'll say that the "un-handled" qualifier is optional; I would settle for breaking on any exception throw as a last resort, though un-handled exceptions are ideal.

What I currently get is useless. Assuming I don't have any appropriate exception handlers higher up the callstack, and I do something like

std::vector<int> my_vector;
my_vector.at(40) = 2; // Throws std::out_of_range

The app will break in main() and I'll get a log message saying "terminate called throwing an exception." Not helpful.

Putting generic try/catch blocks higher up the callstack doesn't help either, because the callstack is unwound during exception handling up to the point of the catch block, leaving me ignorant to actual origin of the exception. This also applies to providing my own terminate_handler. Asserts are more useful, but they require me to anticipate error conditions to some extent, which I cannot always do. I would still like the debugger to be able to step in even if an unexpected exception makes it past my pre-emptive assert()s.

What I want to avoid is having to wrap every call that might possibly throw an exception in a try/catch block just to get the stack trace to the error. At runtime, I'm really not interested in catching these exceptions. When they occur, it means there's a fatal flaw in the program execution, and there's no way it can continue normally. I just want to be notified so I can determine the cause and mend the issue so it won't happen again.


In Objective C, I can put a symbolic breakpoint on objc_exception_throw, and any time I screw something up I'll immediately break execution and be presented with a nice stack trace so I know where the issue is. Very helpful.

I realize this behavior is really only useful because of a philosophical difference in exception handling between the two languages. Objective C exceptions are intended only to signify unrecoverable errors. The task of routine error handling is accomplished via error return codes. This means that any Objective C exception is a great candidate for a breakpoint to the developer.

C++ seems to have a different use for Exceptions. They're used to handle both fatal errors and routine errors (at least in the 3rd party libs I'm using). This means I might not actually want to break on every exception that's thrown in C++, but I would still find the ability useful if I can't break only on un-handled exceptions.

like image 432
Matt Wilding Avatar asked Feb 29 '12 21:02

Matt Wilding


People also ask

What is exception stack trace?

A trace of the method calls is called a stack trace. The stack trace listing provides a way to follow the call stack to the line number in the method where the exception occurs. The StackTrace property returns the frames of the call stack that originate at the location where the exception was thrown.

Is exception handling in C++ cheap?

Modern C++ implementations reduce the overhead of using exceptions to a few percent (say, 3%) and that's compared to no error handling. Writing code with error-return codes and tests is not free either. As a rule of thumb, exception handling is extremely cheap when you don't throw an exception.


2 Answers

You can quickly establish a break on all C++ throw conditions in Xcode:

  • cmd+6
  • "+" button -> Add Exception Breakpoint
    • C++ -> std::out_of_range
    • On Throw

Update

If you have a lot of them tho filter out, you may prefer to:

  • Create a Symbolic Breakpoint
  • Symbol = __cxa_throw (may vary by std library)
  • Action > Debugger Command = bt
  • Automatically continue after eval = On

The bt command logs the backtrace. Configured this way, it will automatically continue.

So, this will just log the backtrace of every thrown exception - when your program terminates due to an unhandled exception, the clues will be among the final logged backtraces (often the last, unless the library rethrows).

like image 138
justin Avatar answered Sep 21 '22 06:09

justin


In the app I get to debug with many c++ exceptions, I leave the "Catch C++ Exceptions on Throw" off until I get to the point in the app where it will throw the exception, then I turn that option on and usually the next exception that is thrown is what I'm looking for. This will break a few levels deeper than where the error is, but the stack is intact so you can figure out what is going on.

like image 32
Mark Avatar answered Sep 23 '22 06:09

Mark