catch(...) is not catching an exception, my program is still crashing - c++

I'm having a problem with a tester that my application crashes in initialization. I added more logging and exception handling but it still crashes with the generic "this program has stopped working" message rather than triggering my error handling.
Given my main() looks like this and has catch(...) under what circumstances would this not be triggered?
try{
simed::CArmApp app(0, cmd);
for(bool done = false;!done;)
{
done = !app.frame();
}
} catch(const std::runtime_error &e){
handleApplicationError(e.what());
return -1;
} catch(...) {
handleApplicationError("Unknown Error");
return -999;
}
My code is calling into a library doing OpenGL rendering which is where I believe things are going wrong.

If a C++ catch(...) block is not catching errors maybe it is because of a Windows error.
On Windows there is a concept called Structured Exception Handling which is where the OS raises "exceptions" when bad things happen such as dereferencing a pointer that is invalid, dividing by zero etc. I say "exceptions" because these are not C++ exceptions; rather these are critical errors that Windows defines in a C-style fashion - this is because Win32 was written in C so C++ exceptions were not viable.
See also:
Difference between a C++ exception and Structured Exception
try-except Statement
Method of getting a stack trace from an EXCEPTION_POINTERS struct
Update based on comments
If you want both C++ exception handing and SEH perhaps you could try the following (untested) code:
__try
{
try
{
// Your code here...
}
catch (std::exception& e)
{
// C++ exception handling
}
}
__except(HandleStructuredException())
{
// SEH handling
}

If an exception is thrown by the destructor of an object that is destroyed as a result of the stack unwinding to handle a different exception, the program will exit, catch(...) or not.

So far I know, there can be at least two situations where catch(...) cannot actually catch
More than 1 unhandled Exception: when an exception is raised before a previously occurred exception is handled, then c++ can not handle it, and application will crash.
Throwing exception that is not in exception specification list: if any method throws an exception which is not in the exception specification list (in any) then unexpected will be called which calls abort.

Do you declare any global objects?
If you have any objects created outside your main loop, that could explain why it is not caught ( it is not in your try-catch ).

Related

Get some information from exception caught with catch(...)? [duplicate]

This question already has answers here:
Is there any way to get some information at least for catch(...)?
(5 answers)
Closed 8 years ago.
I have a try catch clause where the outermost catch(...) never happened until now. After some changes, somewhere an exception which I don't handle with the other cases is thrown. Is there a way to get at least some information about the exception even though I catch it with (...)?
catch (const cone::BeginnersLibException& ex)
{
// handle the exception
}
catch (const std::exception& ex)
{
// handle std exception
}
catch (...)
{
log("Unknown exception caught.");
// How can I get more information about this exception?
}
Edit: here a code snippet that works for me:
#include <cxxabi.h>
// more code here
} catch (...) {
std::string exName(abi::__cxa_current_exception_type()->name());
std::cout<<"unknown exception: "<< exName <<std::endl;
throw;
}
You can do this using gdb or another debugger. Tell the debugger to stop when any exception is throw (in gdb the command is hilariously catch throw). Then you will see not only the type of the exception, but where exactly it is coming from.
Another idea is to comment out the catch (...) and let your runtime terminate your application and hopefully tell you more about the exception.
Once you figure out what the exception is, you should try to replace or augment it with something that does derive from std::exception. Having to catch (...) at all is not great.
If you use GCC or Clang you can also try __cxa_current_exception_type()->name() to get the name of the current exception type.
As a variant on John Zwinck's suggestion to comment out the catch(...) block to let the run-time terminate the application and hopefully provide some more info, you could
catch (...)
{
log("Unknown exception caught in [sensible info here]; will rethrow it");
throw;
}
then you will at least know where in your program the error occured (if there are several possibilities).
One possibility too, on Windows at least, is to write a minidump using MiniDumpWriteDump to get the exception plus stack traces, memory and lots of useful debugging info.
You can use a debugger and enable break on throw, assuming your exceptions really are exceptional this is a good way to know where its coming from.
Also a word of warning should you ever use catch(...) on windows. Under certain build options this will catch SEH exceptions, these are the kinds of things you should never attempt handle such as reading or writing memory out of bounds.
The only way in code (i.e. not using a debugger) to get information from an exception in a catch(...) block is to rethrow the exception, and catch it with specific clauses.
For example.
try
{
// code that might throw something
}
catch (...)
{
try_to_interpret_exception();
}
void try_to_interpret_exception() // we assume an exception is active
{
try
{
throw; // rethrow the exception. Calls terminate() if no exception active
}
catch (std::exception &)
{
// handle all exception types derived from std::exception
// this covers all exceptions that might be thrown by
// the standard C++ library
}
catch (specific_exception &e1)
{
// handle all exception types derived from specific_exception
}
catch (another_specific_exception &e2)
{
// etc
}
}
The catch (so to speak) of this approach is that it requires the programmer to have some knowledge of what the exception might be (e.g. from documentation of a third party library).
|

Application crashes when throwing an exception

In the application I am writing, I make usage of exceptions for most of my error handling. I've not defined my own exception classes just yet, I merely did the following:
namespace Mage {
typedef std::exception Exception;
}
This way I won't have to change all of my code when I define my own type later which should use the same interface.
That said, any exception crashes my application. Taking the above definition in mind, why would this crash?
void Mage::Root::initialize(Mage::String& p_log) {
// initialize GLFW and GLEW.
if (!glfwInit()) {
throw new Mage::Exception("failed to initialize OpenGL");
return;
} else m_GLFWInitialized = true;
Whether I remove or keep 'new', it would still crash. Am I missing something? I've looked up tutorials but those don't get me any wiser.
I also catch the error right here:
try {
MAGE_ROOT.initialize(Mage::String("Mage.log"));
} catch (Mage::Exception& e) {
std::cerr << e.what() << std::endl;
}
The crash I'm getting is:
Debug Error!
Program: ...sual Studio 2010\Project\Mage3D\Binaries\Debug\Test.exe
R6010
- abort() has been called
(Press Retry to debug application)
The problem is that you are not catching your exception.
I wasn't aware you -have- to catch the exception (from the comments)
Yes, you have to. If you do not catch a thrown exception, std::terminate() will be called. This is the intended behavior: exceptions exist to prevent programmers from forgetting about error handling.
This said, I suggest:
throwing by value;
catching by reference
For instance:
void foo()
{
// ...
throw std::logic_error("Error!");
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Throw by value (std::logic_error derives from std::exception)
// ...
}
void bar()
{
try
{
// ...
foo();
// ...
}
catch (std::exception& e)
^^^^^^^^^^^^^^^
// Catch by reference
{
std::cout << e.what(); // For instance...
}
}
UPDATE:
With regards to the piece of code you posted, you are throwing a pointer and catching by reference. The handler won't match. And since there is no other matching handler, std::terminate() will be called.
Instead, you should throw your exception by value:
throw Mage::Exception("failed to initialize OpenGL");
And if the code you posted is indeed the one you are using, you will see that control is transferred to your handler.
Based on the error message, you're using Visual Studio (2010) for your project. Unless you wrap your throw in a try/catch block, it will "sail through the roof" and be "handled" by the C++ runtime, which means calling abort(). You probably want something like this higher in the call stack:
try
{
SomeFunctionThatUltimatelyThrows();
}
catch(Exception & e)
{
// .. handle error - log, resume, exit, whatever
}
Note also Scott Meyers advice to always catch exceptions by reference. The "exception": If you're using MFC CExceptions though, you want to catch by pointer and call the Delete method for self-destructing heap-based exceptions.
Based on your edit, you may have a mismatch between throwing "by pointer" and catching "by reference". If you've resolved that and are still not getting your catch block to execute, you could try debugging the abort() call by using the CRT SetAbortHandler to install your own abort function. This could simply chain into the existing one, but would give an opportunity to set a breakpoint and examine the call stack to see what is going wrong.
C++ try-catch-throw logic for dummies. Note that this does NOT cover RAII / stack-based allocation / destruction.
When you throw an exception, an exception is said to be "propagating". It propagates up the call stack until it finds the first handler that can handle it (so it's caught) or until it's reached the root of your call stack.
If it is caught, execution continues from the point the exception is caught. The exception is destructed at the end of the catch block.
If it finds the root, it calls std::unhandled_exception, which usually calls std::terminate, which usually calls abort(). In short, everything's dropped ASAP.
If you throw an exception while an exception is currently propagating, you would have two propagating at a time. Java and C# have cutesy ways of dealing with this, but this should never happen in the first place - there's no exception handler that is logically going to handle combinations of exceptions. Do not throw exceptions while one is currently propagating. This rule isn't too hard to hold even if you don't use std::uncaught_exception() which you shouldn't.
While unwinding the stack / propagating the exception all objects found on the stack are destructed. These destructors should never throw an exception - after all, when destroying an object "fails", what else are you going to do after the destructor to fix it?
Always throw by value, catch by reference. If you throw & catch by pointer, you will most likely leak something, which is impossible by reference. If you catch by value, you will slice off your derived exception types. Catch by reference.
At the root of your software, include a catch-all - catch(...). This doesn't allow you to find out what exactly you've caught, but at least you can crash safely. Do this also when the called code may throw "something" that you don't know.

about c++ try -catch

I read code in a large project, that includs a lot of code like:
try
{
}
catch(...)
{
}
Literally, in the parenthesis after "catch", there is "..." in it. Not something like "exception e".
This makes me a little worry.
Is this practice good or safe?
thanks.
No, this is a terrible practice.
If you catch(...), you have no idea what you've caught. It catches all C++ exceptions (and on some platforms with some settings, it catches other exceptions too, like structured exceptions in Visual C++).
If you have no idea what exception was thrown, you have no idea what the state of the system is: how do you know whether it is safe for the program to continue running?
The only two ways that it is absolutely safe to exit a catch(...) block is to terminate the program or to rethrow the exception (using throw;). The latter is occasionally useful if you need to perform some cleanup when an exception is thrown but can't rely on a destructor.
catch(...) catches all exceptions.
Normally, you would not want to do this. You have no idea what it is you just caught, and if you leave the catch block you have just silently ignored some kind of error. This could lead to very bad things happening later on. Since you have no idea what error just happened, you have no way to recover from it, and thus the only reasonable thing to do is to either allow the exception to continue (re-throw it) or abort the program's execution (call abort() or exit()).
However, if you have some cleanup you need to perform, it may be reasonable to catch all exceptions, perform the cleanup, then re-throw the exception:
try {
// ...
} catch (...) {
abortTransaction();
throw;
}
That said, it's usually better to use so-called RAII classes to automate this cleanup:
DBTransaction txn = db.StartTransaction();
// do stuff that may throw; if it throws, txn will be destroyed,
// and its destructor can abort the transaction
// As such, an explicit try { } catch(...) { } isn't needed
It catches all exceptions. See this code:
try {
throw CSomeOtherException();
}
catch(...) { // Handle all exceptions
// Respond (perhaps only partially) to exception
throw; // Pass exception to some other handler
}
From MSDN
You do not need to declare this parameter; in many cases it may be
sufficient to notify the handler that a particular type of exception
has occurred. However, if you do not declare an exception object in
the exception-declaration, you will not have access to that object in
the catch handler clause.
A throw-expression with no operand re-throws the exception currently
being handled. Such an expression should appear only in a catch
handler or in a function called from within a catch handler. The
re-thrown exception object is the original exception object (not a
copy). For example:
Hope this helps!
This practice is safe only if you have proper handlers written for exceptions. Avoiding it is better in my opinion.

How to trap errors in DLL

We have a .NET program that calls major functionality in unmanaged C++. I have a global exception catcher on the .NET side to catch any unhandled errors, but errors such as access violations in the unmanaged C++ DLLs can bring the program down without any logging. What is the best way to add "global" exception catcher in a DLL? Can I do this in DllMain?
You can use the /EHa exception handling flag, which will cause your C++ catch (...) to also catch structured exceptions, i.e. access violations. The downside of this is that you can't see what the exception was.
Alternatively, you can use a structed exception handler, __try { } __except(FILTER) { }, to handle structured exceptions. This allows you to output what type of exception was caught. However, there are limitations on what you can do in a function with a __try, such as no C++ exception handling or objects with destructors.
You can, however, get around the __try limitation by just calling a function containing the C++ exception handling and original code.
void main() {
__try {
Foo();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
// Log some error regarding the structured exception
}
return 0;
}
void Foo() {
try {
SomeCPPObject bar(1,2);
DoSomeStuff();
}
catch (const std::exception&) {
// Log the C++ exception
}
}
Be careful, however, as you usually should not continue execution after a structured exception has been raised, as the state of your program could be completely destroyed. It's best to only use this type of exception handling to log an error before exiting.
The CLR cannot trap any hardware exceptions that are raised in threads started by the native code. The only way to do so is by using SetUnhandledExceptionFilter(), the callback you register is called by Windows before it is about to tear down the process.
Using this in a program that also has managed code is filled with traps and pitfalls. The CLR uses it too, it has to in order to generate exceptions like NullReferenceException and DivideByZeroException. You have to be very careful to not break that. Doing something like calling GetThreadId() and only filter exceptions of threads that you know are native ones is important. Next thing you'd do is, say, use MiniDumpWriteDump() to generate a minidump so that you can debug the crash.

Does it make sense to catch exceptions in the main(...)?

I found some code in a project which looks like that :
int main(int argc, char *argv[])
{
// some stuff
try {
theApp.Run();
} catch (std::exception& exc) {
cerr << exc.what() << std::endl;
exit(EXIT_FAILURE);
}
return (EXIT_SUCCESS);
}
I don't understand why the exceptions are being catched. If they weren't, the application would simply exit and the exception would be printed.
Do you see any good reason to catch exceptions here ?
EDIT : I agree that it is good to print the exception error. However, wouldn't it be better to rethrow the exception ? I have the feeling that we are swallowing it here...
If an exception is uncaught, then the standard does not define whether the stack is unwound. So on some platforms destructors will be called, and on others the program will terminate immediately. Catching at the top level ensures that destructors are always called.
So, if you aren't running under the debugger, it's probably wise to catch everything: (...) as well as std::exception. Then your application code can clean up with RAII even on a fatal exception. In many such cases you don't actually need to clean up, since the OS will do it for you. But for instance you might prefer to disconnect cleanly from remote services where possible, and there might be resources external to the process, such as named pipes/mutexes, that you'd prefer to destroy rather than leaking.
Rethrowing the exception in main seems to me of limited use, since you've already lost the context in which it was originally thrown. I suppose that trapping an uncaught exception in the debugger is noisier than just logging the fault to std::cerr, so rethrowing would be the smart move if there's a chance of missing the logging.
If you want the debugger to trap unexpected conditions in debug mode, which in release mode throw an exception that eventually results in an exit, then there are other ways to do that than leaving the exception uncaught so that the debugger sees it. For example, you could use assert macros. Of course, that doesn't help with unexpected and unpredictable conditions, like hardware exceptions if you're using SEH on .NET.
Why do you say that the exception would be printed? This is not the typical behavior of the C++ runtime. At best, you can expect that its type gets printed.
In addition, this program leaves a "failure" status, whereas an exception might cause a termination-through-abort status (i.e. with a signal indicated in the exit code).
Try-catch in the main function hides the exception from debugger. I would say, it isn't good.
On the other hand, customers are not expected to have debuggers, so catching exceptions is nice. So it is good.
Personally, I catch all exceptions in main function, when making a release build, and I don't do that, when building a debug configuration.
A simple example of a situation where the stack did not unwind:
Why destructor is not called on exception?
A list of situations where exceptions may cause the application to terminate rather than unwind the stack.
Why destructor is not called on exception?
If an exception is not caught at any level and would escape main() then the implementation is allowed to call terminate() rather that unwinding the stack (yes this caught me by surprise as well).
As a result I always catch all exceptions in main().
int main()
{
try
{
}
catch(std::exception const& e)
{ /* LOG */
// optimally rethrow
}
catch(...) // Catch anything else.
{ /* LOG */
// optimally rethrow
}
}
To help with catching problems during debugging. Derive your exceptions from std::exception and then stick the break point in the constructor for std::exception.
This is a global catch block. It is common for displaying a nice and user understood message ('Internal error') instead of a cryptic exception print-out. This may be not evident from the specific code block, but it is in general a good idea.
Have a look at the C++ bible i.e. Stroustrup, he has an example which is also repeated in Applied C++ programming. The reasoning is:
int main(void)
{
try
{
// your code
}
catch ( /* YourPossibleExceptions i.e. barfs you expect may occur */ )
{
}
catch ( ... ) // unexpected errors, so you can exit gracefully
{
}
}
According the the Windows spec, the main isn't allowed to throw.
(practically it results into the message that asks if you want to send the bug-report to Microsoft)