3

Can an ellipsis try-catch be used to catch all the errors that can lead to a crash? Are there are any anomalies?

try
{
//some operation
}
catch(...)
{
}
ssk
  • 9,045
  • 26
  • 96
  • 169
  • 2
    All of the answers have a small imprecision: in c++ you can throw *anything*, not just *exceptions*, read the answers as if *anything that has been thrown* was used instead of *all exceptions*. – David Rodríguez - dribeas Oct 12 '11 at 18:38
  • 6
    If your intent is to add a catch-all handler in order to prevent your program from crashing **please don't**. Fix the errors in your code instead. – John Dibling Oct 12 '11 at 18:50
  • @David: But what you throw becomes the exception even if is an int(1); – Martin York Oct 12 '11 at 19:58

4 Answers4

13

No, it'll only catch C++ exceptions, not things like a segfault, SIGINT etc.

You need to read up about and understand the difference between C++ exceptions and for want of a better word, "C-style" signals (such as SIGINT).

John Carter
  • 53,924
  • 26
  • 111
  • 144
  • 5
    Depending on the compiler and its settings, it might catch SEH exceptions on Windows as well (which include things like access violations). – Cat Plus Plus Oct 12 '11 at 18:38
1

It is the Catch All handler.
It catches all the C++ exceptions thrown from the try block. It does not catch segfault and other signals that cause your program to crash.

While using it, You need to place this handler at the end of all other specific catch handlers or it all your exceptions will end up being caught by this handler.

It is a bad idea to use catch all handler because it just masks your problems and hides the programs inability by catching all(even unrecognized) exceptions. If you face such a situation you better let the program crash, and create a crash dump you can analyze later and resolve the root of the problem.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • It is a great idea for logging. Just be sure to continue the throw with `throw;` – Mooing Duck Oct 12 '11 at 18:35
  • @MooingDuck: Not really. You lose the type information, all you can log is "oops, exception, sorry". It's better to catch on `std::exception` in the top-level handler for that. – Cat Plus Plus Oct 12 '11 at 18:36
  • @CatPlusPlus: Vlad convinced me that logging in an unknown state is dangerous. Comment retracted. – Mooing Duck Oct 12 '11 at 18:59
  • 1
    I think it's basically wrong to say it's a bad idea to use it. I'd compare a catch-all handler to an ejection seat in a military aircraft. Yes, you'd rather never use it, but when things go badly enough wrong, using it is still better than riding it down in flames. – Jerry Coffin Oct 12 '11 at 19:08
  • @JerryCoffin: None of the answers actually seemed to point out that using it actually is not a good practice, i tried to, maybe words didn't justify/convey what i wanted to but nevertheless I tried conveying the right thing.And I don't know if users vote by brains or mob mentality but I got 3 downvotes for saying a correct but not so popular thing. – Alok Save Oct 12 '11 at 19:13
  • @Jerry: look at http://blogs.msdn.com/b/oldnewthing/archive/2009/11/13/9921676.aspx for some reasoning why doing something in catch_all is a bad thing. Example: the exception might have happened in the middle of heap block allocation, so any logging attempt may do unpredictable things (including launching nasal demons). – Vlad Oct 12 '11 at 19:18
  • Yup -- I understand what you're getting at, and agree with the basic idea, but wish it were phrased better. I don't think @Vlad is exactly right either though. Yes, it *can* theoretically fail completely -- just like any function call could cause stack overflow and fail horribly. Both, however, are useful enough often enough to be useful tools. – Jerry Coffin Oct 12 '11 at 20:05
  • @Jerry: inside the `catch(...)` clause, chances that something went terribly wrong are quite high. In particular, chances that heap is in inconsistent state, or a global I/O lock is taken, are sensible. – Vlad Oct 12 '11 at 20:35
  • 1
    @Vlad: Not really. A `catch(...)` clause is only invoked for C++ exceptions. To get invoked, the stack has to be consistent enough to trace back to find the catch handlers. Along the way, stack unwinding will (try to) destroy locals. That will usually involve some `delete`s, so if the heap is really corrupted, it'll probably exit to the OS before the handler is reached. In that handler, chances that the system is horribly corrupt are actually fairly remote. The article you linked talked about SetUnhandledExceptionFilter -- which is a radically different situation. – Jerry Coffin Oct 12 '11 at 20:47
  • @Jerry: Not quite. :) On Windows/Visual C++ `catch(...)` catches SEH, which can be thrown at quite nasty moments. (So there is not so much difference between `catch(...)` and `SetUnhandledExceptionFilter`.) There is a [comment here on SO](http://stackoverflow.com/questions/315948/c-catching-all-exceptions/316070#316070) suggesting that on Linux `catch(...)` can catch a signal (if I understood it correctly), but I couldn't find any references about this in Internet. – Vlad Oct 12 '11 at 21:05
  • @Vlad: The question is tagged C++. Catching SEH happened in VC++6, but that certainly should *not* be mistaken for C++. – Jerry Coffin Oct 12 '11 at 21:18
  • @Jerry: well, Windows is still the most popular desktop platform, right? So we cannot say VC++ doesn't count. But well, I must admit that this consideration lies outside of the ivory tower of standard C++ (sigh). (AFAIK the behaviour of catch is the same in VC++ 2010, too.) – Vlad Oct 12 '11 at 21:22
  • @Vlad: That's my point: the behavior of catch is *not* the same in VC++2010, or VC++2008, or anything else since VC++6. It's *possible* to get the VC++6-like behavior if you want to badly enough, but it does *not* happen by default and hasn't for years now. – Jerry Coffin Oct 12 '11 at 21:27
  • @Jerry: quick googling had found me the [link](http://blogs.msdn.com/b/zhanli/archive/2010/06/25/structured-exception-handling-seh-and-c-exception-handling.aspx), which suggests that under some circumstances the behaviour in year 2010 was still the same. When coding a part of a big project, one must be careful. – Vlad Oct 12 '11 at 21:30
  • @Vlad: Did you read the linked article? It fits exactly with what I said: it's *possible* to get that behavior if you try hard enough, but it won't happen by default. Nobody whose IQ is higher than their hat size would even consider doing it except to get ancient code written for VC++6 or earlier to work (for a loose enough definition of "work"). – Jerry Coffin Oct 12 '11 at 21:35
  • @Jerry: in fact, the last C++ project I was working in compiled with `/EHa`. Our architect didn't wear the hat though. (Maybe because it was converted from some old code.) – Vlad Oct 12 '11 at 21:44
1

If the code inside try/catch block crashed somehow, the program is anyway in a non-recoverable state. You shouldn't try to prevent the crash, the best that the program can do is just let the process crash.

The "anomaly" is in the fact that your code only catches the exceptions, and not the errors. Even if the code is exception-safe (which may be not the case, if you are trying to work-around its mistakes by a try/catch block), any other inner error may bring the program into irrecoverable state. There is simply no way to protect the program from it.


Addition: look at this article at "The Old New Thing" for some insights.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • Although this is still handy for logging. Just be sure to end the `catch` block with a `throw;` statement to continue the throw. – Mooing Duck Oct 12 '11 at 18:34
  • @MooingDuck: I wouldn't better do any logging in catchall-block. You never know how exactly corrupted your program state is, and better is to do a little as possible, in order to prevent for example corrupting the user data. – Vlad Oct 12 '11 at 18:38
  • @MooingDuck: yes :-) Look at the article I'm referencing. – Vlad Oct 12 '11 at 18:43
  • Good article. I had quite a argument on how it can't hurt to try typed up until I realized logging to `std::cerr` in a fail-state could overwrite the buffer of a RIAA stream or inter-process memory, which would then be flushed during stack unwinding. So you're right. Minimize damage done. Do not use `catch (...)`. – Mooing Duck Oct 12 '11 at 18:58
  • @MooingDuck: indeed, on Visual C++ `catch(...)` catches [SEs](http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657.aspx) (!), so the program is potentially in a very bad state. – Vlad Oct 12 '11 at 21:14
0

It catches everything that is thrown, it is not limited to exceptions. It doesn't handle things like windows debug asserts, system signals, segfaults.

TEST(throw_int) {
    try {
        throw -1;
    } catch (std::exception &e) {
        std::cerr << "caught " << e.what() << std::endl;
    } catch (...) {
        std::cerr << "caught ..." << std::endl;
    }
}

Throwing an integer isn't really recommended though. It's better to throw something that inherits from std::exception.

You might expect to see something like this as a last ditch effort for documenting failure, though. Some applications aren't required to be very robust. Internal tools might cost more than they are worth if you went through the paces of making them better than hacked together crap.

int main(int argc, char ** argv) {
    try {
        // ...
    } catch (std::exception &e) {
        std::cerr << "error occured: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}
Tom Kerr
  • 10,444
  • 2
  • 30
  • 46