I am attempting to make post-mortem life a little easier for a very large and cross-platform project that makes use of many 3rd party libraries. On Linux, I use backtrace() to dump the backtrace/callstack to console. On Windows, I use EXCEPTION_POINTERS to create a minidump and that StalkWalker class to dump the callstack to console. Now, with all the platform-specific signal handlers registered and SEH enabled on Windows, I catch and report a lot of helpful information, most importantly, the file and line number of where the bad thing happened. However, in the callstack, I have noticed that I never actually get the location of any throw statements, only where it was caught, i.e. a catch block. As you can imagine, if your try-catch encompasses a gigantic amount of code, where the exception was caught is not terribly helpful. So, why is that?
And now for the obvious followup question: How do I get the location of throw statements into my callstack console dumps?
I will stop anyone who tries to tell me to change all the throw statements to custom exceptions with __FILE__ and __LINE__ macros right here. Please refer back to my opening sentence. As such, present uses of throw will not be changed.
Related
I have a Windows service written in (Visual) C++ with a very detail logging functionality that has often helped me find the cause of errors customers are sometimes experiencing. Basically I check every return value and log what is going on and where errors are coming from.
Ideally, I would like to have the same level of detailed visibility into exceptions (like array out of range, division by zero, and so on). In other words: I want to know exactly where an exception is coming from. For reasons of readability and practicality I do not want to wrap every few lines of code into separate try/catch blocks.
What I have today is one general catch-all that catches everything and logs an error before shutting down the program. This is good from the user's point of view - clean shutdown instead of app crash - but bad for me because I only get a generic message from the exception (e.g. "array out of range") but have no idea where that is coming from.
Wouldn't it be better to remove the catch-all and let the program crash instead? I could direct the customer to have Windows create an application crash dump (as described here). With the dump file WinDbg would point me exactly to the position in the code where the exception was thrown.
You can register a custom, vectored exception handler by calling AddVectoredExceptionHandler .
This will get called whenever an exception gets thrown, and in it you can generate a stack trace that you can then save off for logging purposes.
Writing the code to do this is not completely trivial but not rocket surgery either.
I've never personally done it in C++, but I would be surprised if there weren't ready-built libraries that do this available somewhere, if you don't have the time or inclination to do it on your own.
You can throw exceptions with description where the error occurred and why:
throw std::string("could not open this file");
If you do not want to write different descriptions for every possible error you can use standard macros __FILE__ and __LINE__:
#define _MyError std::string("error in " __FILE__ + std::to_string(__LINE__))
// ...
throw _MyError;
If source file name and line of the error is not enough and you need more information, for example stack trace or memory values, your program can generate a debug report. Google Breakpad is a C++ library that allows you to do that in a portable way. Class wxDebugReport from wxWidgets library is an alternative. On Windows the debug reports may include a minidump file that can be loaded in Visual Studio and allows you to analyse the error in a way similar to debugging.
Wouldn't it be better to remove the catch-all and let the program
crash instead?
You can catch-all and
Write a (more personal) message about the fatal error that occurred, forcing the application to be closed. Do not let the program continue: you don't know what happened, where. Continuing might cause damage to the user's data, follow up errors, etc.
Tell the user to contact you with specifics as to what they did and what happened.
Tell the user to include the log file your application has generated.
If you don't do something like this, then you might just as well remove the catch-all.
For reasons of readability and practicality I do not want to wrap
every few lines of code into separate try/catch blocks.
And yet if you want your program to be able to recover, this is exactly what you have to do. What you could do is
Tell the user what happened, perhaps what was wrong with the input that may have caused it. Don't make it sound technical.
Save any data the user has entered so their work is not completely lost
You know at which step the failure happened. Undo that step, i.e. throw away objects / data, and go back to the point before the exception.
Restore data the user had entered from the second point so they don't need to repeat actions all over again.
The point being that your program can return to a valid state.
How can I identify exact line of program on which my application crashed? Is there any tool to tell me which line in which source file has crashed the application?
I am using C/C++, MFC, and VC++.
Use gdb to see where your application crash. For linux, use gdb --args (Application command line)
use breakpoints for stepping into various functions. And if you run into crash, use bt to backtrace the code.
Though there are many many things in gdb, my aim was to give just the pointer, where you can begin.
For run time (non-debugger attached) exceptions I like using "BOOST_EXCEPTIONS" because the BOOST_THROW_EXCEPTION macro attaches BOOST_CURRENT_FUNCTION, FILE and LINE to the exception.
But the best way is to compile in debug mode and run with a debugger attached. If you're using visual studio (which with VC++, you probably already are) move to debug mode and run it. When an un-handled exception is thrown, it should bring you right there.
If you want to catch handled exceptions, from the Menu bar, Debug->Exceptions. Checking all of these will make the exceptions caught by the debugger, even when they are handled. Though people using exceptions for non-fatal errors can make this SUPER ANNOYING...
It depends a lot by what you mean by 'crash'. But assuming that you mean an exception occured in your app, then the EXCEPTION_RECORD structure will contain the exact address where the exception occurred, in other words the IP that was executed when the exception was raised. On Windows C++ exception use SEH. Read the timeless A Crash Course on the Depths of Win32™ Structured Exception Handling to understand SEH.
You can retrieve the exception info from a crash dump (see ecxr Display Exception Context Record) or you can instruct debuggers to break on exception. Dr. Watson will create dumps for you when crash 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)
This is an unusual question to ask but here goes:
In my code, I accidentally dereference NULL somewhere. But instead of the application crashing with a segfault, it seems to stop execution of the current function and just return control back to the UI. This makes debugging difficult because I would normally like to be alerted to the crash so I can attach a debugger.
What could be causing this?
Specifically, my code is an ODBC Driver (ie. a DLL). My test application is ODBC Test (odbct32w.exe) which allows me to explicitly call the ODBC API functions in my DLL. When I call one of the functions which has a known segfault, instead of crashing the application, ODBC Test simply returns control to the UI without printing the result of the function call. I can then call any function in my driver again.
I do know that technically the application calls the ODBC driver manager which loads and calls the functions in my driver. But that is beside the point as my segfault (or whatever is happening) causes the driver manager function to not return either (as evidenced by the application not printing a result).
One of my co-workers with a similar machine experiences this same problem while another does not but we have not been able to determine any specific differences.
Windows has non-portable language extensions (known as "SEH") which allow you to catch page faults and segmentation violations as exceptions.
There are parts of the OS libraries (particularly inside the OS code that processes some window messages, if I remember correctly) which have a __try block and will make your code continue to run even in the face of such catastrophic errors. Likely you are being called inside one of these __try blocks. Sad but true.
Check out this blog post, for example: The case of the disappearing OnLoad exception – user-mode callback exceptions in x64
Update:
I find it kind of weird the kind of ideas that are being attributed to me in the comments. For the record:
I did not claim that SEH itself is bad.I said that it is "non-portable", which is true. I also claimed that using SEH to ignore STATUS_ACCESS_VIOLATION in user mode code is "sad". I stand by this. I should hope that I had the nerve to do this in new code and you were reviewing my code that you would yell at me, just as if I wrote catch (...) { /* Ignore this! */ }. It's a bad idea. It's especially bad for access violation because getting an AV typically means your process is in a bad state, and you shouldn't continue execution.
I did not argue that the existence of SEH means that you must swallow all errors.Of course SEH is a general mechanism and not to blame for every idiotic use of it. What I said was that some Windows binaries swallow STATUS_ACCESS_VIOLATION when calling into a function pointer, a true and observable fact, and that this is less than pretty. Note that they may have historical reasons or extenuating circumstances to justify this. Hence "sad but true."
I did not inject any "Windows vs. Unix" rhetoric here. A bad idea is a bad idea on any platform. Trying to recover from SIGSEGV on a Unix-type OS would be equally sketchy.
Dereferencing NULL pointer is an undefined behavior, which can produce almost anything -- a seg.fault, a letter to IRS, or a post to stackoverflow :)
Windows 7 also have its Fault Tollerant Heap (FTH) which sometimes does such things. In my case it was also a NULL-dereference. If you develop on Windows 7 you really want to turn it off!
What is Windows 7's Fault Tolerant Heap?
http://msdn.microsoft.com/en-us/library/dd744764%28v=vs.85%29.aspx
Read about the different kinds of exception handlers here -- they don't catch the same kind of exceptions.
Attach your debugger to all the apps that might call your dll, turn on the feature to break when an excption is thrown not just unhandled in the [debug]|[exceptions] menu.
ODBC is most (if not all) COM as such unhandled exceptions will cause issues, which could appear as exiting the ODBC function strangely or as bad as it hang and never return.
At runtime, when myApp.exe crashes i receive "Unhandled Win32 exception" but how would i know which exception was occurred? where did something went wrong?
For a Native C++ app see my earlier answer here: Detect/Redirect core dumps (when a software crashes) on Windows for catching the unhandled exception (that also gives code for creating a crash dump that you can use to analyse the crash later. If the crash is happening on a development system then in Visual Studio (I'm assuming you're using that, if not other IDEs will have something similar), in Debug/Exceptions tick the 'Thrown' box for 'Win32 Exceptions'.
Typically, Windows will give you several hexadecimal numbers as well. Chances are that the exception code will be 0xC0000005. This is the code of an Access Violation. When that happens, you also will have three additional bits of information: the violating address, the violated address, and the type of violation (read, write or execute).
Windows won't narrow it down any further than that, and often it couldn't anyway. For instance, if you walk past the end of an array in your program, Windows likely won't realize that you were even iterating over an array. It just sees "read:OK, read:OK, read:out of bounds => page fault => ACCESS VIOLATION". You will have to figure that out from the violating address (your array iteration code) and the violated address (the out-of-bounds address behind your array).
If it's a .Net app you could try to put in a handledr for the UnhandledException event. You can find more information about it and some sample code here.
In general it's a good sign that your exception handling is broken though, so might be worth going through your code and finding places that could throw but where you don't handle exceptions.
Use the debugger. You can run the program and see what exception is been thrown that kills your application. It might be able to pinpoint the location of the throw. I have not used the VS debugger for this, but in gdb you can use catch throw to force a breakpoint when an exception is thrown, there should be something similar.