The fact a stack/function trace is supplied in Java/C# exceptions is really useful. Is there a handy way to do this in C++ or would I have to bake extra data into every method/function?
Most debuggers can be set up to pause your program each time an exception is thrown (either any exception or an exception for which there's no handler) so that you can obserevr a call stack.
Also if your code only throws exceptions of classes you control you can put code for dumping the call stack in those classes constructors.
If you are considering adding metdata to your exceptions, You may consider using boost exception handling . boost::exception allows adding information to an exception after it has been thrown.
Some OS APIs provide for stack traces, I know that the Windows API has StackWalk64 or something like that that can do stack tracing.
However, if you can't depend on such a thing, then pretty much all you can do is either ship a debug build, or do it manually.
Related
I am a C developer looking into C++:
Do I understand it correctly that if I throw an exception then the stack will unwind until the first exception-handler is found? Is it possible to instead open a debugger upon any throw without unwinding (ie without leaving the scope in which it was declared or any higher scope)?
The reason I am asking is, that - even though there are exception handlers in a higher scope - I am interested in the locals of that scope (and also dont want to lose the RAII'ed objs) and want to look at them during debugging.
EDIT: mostly for g++ on win+linux, but also interested in other platforms.
You didn't specify your toolset/platform.
But in MSVC you can configure the debugger to break on various types of exceptions, in your case it would be C++ exceptions.
See here for details:
http://msdn.microsoft.com/en-us/library/d14azbfh.aspx
Edit: For gcc/gdb see this question Run an Application in GDB Until an Exception Occurs
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.
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).
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.
Check PLCrashReporter. We use it with our application (which relies heavily on C++) and it produces stack traces even for the C++ code.
The only problem you might have is when using assembly routines which were not written natively for iOS (Apple's compiler is using R7 to hold the stack frame for tracing back symbols which is not according to official ARM EBI)
I know that there has to be quite a lot of documentation about this topic on the internet.
But doing research for hours without a proper answer is quite frustrating. So I assume I can't put my question in a good phrase. So here the full version:
I'm doing a presentation about try-catch, but it's rather boring to do the basic things. I know what try catch is and I know how it works.
But here comes the magic: Let's assume I use C++.
The compiler will create a read only list on the heap with structures that give information about the functions in the try-block. That includes pointers for start and end of the routine, information about about the object type of the exception and so on. (Please correct me if I'm wrong)
Okay. Now an exception occurs. The so called error handler (here we go, who is the error handler?) will look up all the data about the failing routine and get the appropriate catch routine. The correct catch is found by comparing the exception object that is generated through the error with the exception objects in the catch.
For example: InvalidCastException (or something like that) is created. There is a catch for that, the error is handled and all objects that are created in the try block are destroyed.
But: How can the program notice that there is an exception? Is this handled by the program, by the runtime or maybe even by the processor (I read something about Ring0 and Ring1, different levels in the CPU oO).
There are two ways of implementing exception handling in C++. First is to use Itanium ABI Zero-Cost exception handling. The second one is to use a pair of setjmp/longjmp to handle control flow for exceptions. The first is a preferred implementation for every modern compiler.
The program does not "listen" for exceptions, so it doesn't notice exceptions. Instead, it raises and processes them as part of the control flow. For example, "throw" is always raising an exception which triggers transfers the execution to exception handling code.
Even though these exceptions are heavily used in C++ which provides a nice interface to "throw" and "catch" them, they are also used in C, and even in the Linux kernel.
You can read more here:
http://sourcery.mentor.com/public/cxx-abi/abi-eh.html
http://llvm.org/docs/ExceptionHandling.html
Zero cost exception handling vs setjmp/longjmp
I have a Win32 C++ app developed in VS2005. There is a try {} catch (...) {} wrapped around a block of code, and yet 3 functions deep, when the algorithm breaks down and tries to reference off the end of a std::vector, instead of catching the exception, the program drops into the VS debugger, tells me I have an unhandled win32 exception, and the following is found on the call stack above my function:
msvcr80.dll!:inavlid_parameter_noinfo()
msvcr80.dll!:invoke_watson(....)
msvcr80.dll!:_crt_debugger_hook(...)
How can I prevent the debugger being called? This occurs at the end of a 30 minute simulation, at which point I lose all my results unless I can catch and log the exception. This and similar try/catch constructs have been working in the past - are there compiler settings which affect this? Help?
You may want to convert non-C++ exceptions into C++ exceptions. Here's an example of how to do it.
Apologies for the delay - unforeseen circumstances - but the real answer appears to be the following.
First, the application is also wrapped in a __try {} __except () {} construct, and uses unhandled exception filtering based on XCrashReport. This picks up the non C++ exceptions for the reasons many have pointed out above.
Second, however, as one can find here and elsewhere, since CRT 8.0, for security reasons Microsoft bypasses unhandled exception handling on buffer overruns (and certain other situations), and passes the issue directly to Dr Watson.
This is really annoying - I want to know where my buffer overruns are occurring, and why, and to fix them. I also want my program to crash, leave an audit trail, and then be automatically restarted, 24/7. Having MS Visual Studio on the PC seems to mean that Dr Watson will pause and offer me the option of using MSVC to debug the issue. However, until I respond to the dialog box, nothing will happen. Comments on workarounds greatly appreciated...
Just because you have a catch(...) doesn't mean you can catch and recover from all exceptions. Not all exceptions are recoverable.
You problem might be that the first exception that pin points the exact problem is getting obscured by your catch statement
You need to attach the debugger to the program and have it break on all exceptions and fix the code
Standard Library containers do not check for any logic errors and hence themselves never emit any exceptions.
Specifically, for std::vector only method that throws an exception is std::vector::at().
Any Undefined Behavior w.r.t to them will most likely lead your program to crash.
You will need to use Windows' SEH and C++ Exception Handling for catching Windows specific exceptions, which are non C++ standard btw.
My Visual C++ application is compiled with /EHA option, letting me catch structured exceptions (division by zero, access violation, etc). I then translate those exceptions to my own exception class using _set_se_translator(). My goal is to improve our logging of those types of exceptions.
I can get the type of exception from the EXCEPTION_RECORD structure, and the exception address. I would like to be able to gather more information, like the source file/location where the exception is thrown, the call stack, etc. Is that possible?
I do create an exception minidump on structured exceptions - is there a tool to automatically get the call stack from that?
Call stack and all other exception information is available using minidump post-mortem debugging:
http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx
AFAIK, generating stack information in the place for logging is impossible without .pdb files. Usually .pdb files are not installed on a client computer.
One idea I had is to use different translator functions in some of the different threads (there is one translator function per thread) so I can know from which thread the structured exception was thrown.
It's not so practical because you can't pass any argument to the translator function, so you need a bunch of different translator functions.