19

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.

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • 1
    I'm not sure I understand. How do you know that it's an uncaught exception? – kec May 08 '14 at 13:42
  • Because `handleApplicationError` isn't being called (it raises a MessageBox and kills my splashscreen, neither of these is happening) – Mr. Boy May 08 '14 at 13:49
  • But why couldn't it just be some other kind of program crash? – kec May 08 '14 at 13:52
  • Sorry I misunderstood. My understanding was `catch(...)` should let me regain control if _anything_ goes wrong, or rather I was asking under what circumstances that is _not_ true. – Mr. Boy May 08 '14 at 13:53
  • 6
    Ah, no. In C++, an exception is a very specific programming language mechanism. It's not like a hardware exception. You have to specifically use a `throw` statement to throw an exception. So, for example, any kind of undefined behavior like null pointer dereference, etc. will in general *not* cause an C++ exception to be thrown. – kec May 08 '14 at 13:56
  • The answer below by Monks addresses this, I believe. – kec May 08 '14 at 13:58
  • "this program has stopped working" can also indicate infinite recursion or a broken callstack. Those usually don't generate any exceptions at all. Does this only happen for your tester? – molbdnilo May 08 '14 at 14:04
  • It's possible that something is flat-out causing the program to terminate. Do you have a [`std::terminate_handler`](http://www.cplusplus.com/reference/exception/terminate_handler/) registered? (In addition to unhandled/unhandlable exceptions, [std::terminate can be called if something else bad happens](http://akrzemi1.wordpress.com/2011/09/28/who-calls-stdterminate/ "Who calls std::terminate?").) – Lilshieste May 08 '14 at 14:09

5 Answers5

28

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:

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 
}
djvg
  • 11,722
  • 5
  • 72
  • 103
Peter Monks
  • 4,219
  • 2
  • 22
  • 38
  • 1
    Interesting, thankyou. It's not immediately clear how I try to implement both - or rather in my example code how I should write it to be safer. I _believe_ a 3rd-party lib is where things are breaking - that lib does throw C++ exceptions so I'd hoped they caught such problems for me! Is it possible you could use my code as an example what to do, as a perfect answer? – Mr. Boy May 08 '14 at 14:01
  • I've added some sample code, maybe this could be used to catch both kinds of exceptions – Peter Monks May 08 '14 at 14:06
  • yuck (having to do this, not your code!) but it seems this is the solution – Mr. Boy May 08 '14 at 14:20
  • 1
    Structured exception handling (`__try`, `__except`, and `__finally`) and C++ exception handling (`try` and `catch`) cannot be used in the same function. Note that it is _exceedingly_ rare that handling a structured exception is the right thing to do. – James McNellis May 08 '14 at 19:33
8

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.

dlf
  • 9,045
  • 4
  • 32
  • 58
7

So far I know, there can be at least two situations where catch(...) cannot actually catch

  1. 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.
  2. 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.
Rakib
  • 7,435
  • 7
  • 29
  • 45
  • +1, but in the case #1, it's not simply a "crash," it's a call to `std::terminate`. – Angew is no longer proud of SO May 08 '14 at 13:55
  • @Angew, right, infact by default `terminate` will also call `abort`, so same as #2. – Rakib May 08 '14 at 13:58
  • I'd like to be extra clear that #2 also includes if your throwing function is called by some other function, and/or either function was declared as `noexcept`. If the throwing function is specified correctly but it's called by a `noexcept` function, the caller will terminate. This might be basic, but it just cost me a few mins of head-scratching, so! – underscore_d Jun 05 '20 at 11:21
1

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 ).

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Paul
  • 370
  • 3
  • 12
  • It's definitely crashing due to something called from inside that try/catch block - I get logging to prove code is running and then it just dies, but none of my error-handling is triggered :( – Mr. Boy May 08 '14 at 13:55
0

If you are using multithreading and an exception is thrown, prompting the destructor of the threads, then it is possible that the exception will be ignored and abort will be called. std::jthread (C++20) solves this, but if you don't have access to C++20, then you will need to have a cleanup function/lambda to terminate the threads before the exception is thrown.

Jcsq6
  • 474
  • 1
  • 4
  • 15