Is there an occasion where using catch all clause : catch (...) is justified? - c++

Each time I have seen the catch all statement:
try
{
// some code
}
catch (...)
{
}
it has always been an abuse.
The arguments against using cache all clauses are obvious. It will catch anything including OS generated exceptions such as access violations.
Since the exception handler can't know what it's dealing with, in most cases the exceptions will manifest as obscure log messages or some incoherent message box.
So catch(...) seems inherently evil.
But it is still implemented in C++ and other languages (Java, C#) implements similar mechanisms. So is there some cases when its usage is justified?

(1) It's not true that the statement will catch OS exceptions. Your use of the term "Access Violation" betrays a Windows background; it was true for older MSVC++ versions.
(2) Regardsless, the catch-all behavior is useful for threads with specific purposes. Catching the failure allows the thread to report it failed. Without it, the other parts of the program need to deal with the possibility of a thread just disappearing. It also allows you to log which thread failed, and the arguments used to start the thread.

The case where it's justified in general is when you log the exception (or do something similar) or do some cleanup, and then immediately rethrow.
In C++ in particular, logging in a catch(...) block is pretty pointless since you don't have any way to obtain the exception, and cleanup is pointless because you should be using RAII for that. Using it in destructors seems to be about the only legitimate case.

the arguments against using cache all clauses are obvious , it will catch anything including OS generated exceptions such as access violation. since the exception handler can't know what its dealing with, in most cases the exceptions will manifest as obscure log message or some incoherent message box.
And if those same exceptions aren't caught you get... an incoherent message box.
catch(...) lets me at least present my own message box (and invoke custom logging, save a crash dump, etc.).
I think there are also reasonable uses of catch(...) in destructors. Destructors can't throw--well, I mean, they can throw, but if a destructor throws during stack unwinding due to an in-progress exception the program terminates, so they should not ever allow exceptions to escape. It is in general better to allow the first exception to continue to be unwound than to terminate the program.
Another situation is in a worker thread that can run arbitrary functions; generally you don't want an unceremonious crash if the task throws an exception. A catch(...) in the worker thread provides the opportunity for semi-orderly clean-up and shutdown.

In addition to what other posters have already said, I'd like to mention one nice point from the C++ Standard:
If no matching handler is found in a
program, the function std::terminate()
is called; whether or not the stack is
unwound before this call to
std::terminate() is
implementation-deļ¬ned.
(15.3/9)
This means that main() and every thread function must be wrapped in a catch-all handler; otherwise, one can't even be sure that destructors for automatic objects will be called if an uncaught exception is thrown.

try {...} catch (...) is needed around body of callback function which is called from code
that doesn't understand C++ exceptions (usually C library).
Otherwise, if some C++ library you use throws an exception that doesn't derive from
std::exception, it will probably cause calling code to crash or corrupt its internal state.
Instead you should catch this exception and either finish program immediately or
return some error code (meaning "we are doomed and I don't know why", but it's still better
then letting C++ exception to pass through).
Around thread procedure. Mostly because of the same reason as 1.
And because otherwise thread failure would pass unnoticed.

catch(...) has been useful for me in two circumstances, both of which are unjustified (I can't even remember the second)
The first is my overall application safety. While throwing exceptions that don't derive from std::exception is a No-No, I have one just in case in my main() function:
int execute(void); // real program lies here
int main(void)
{
try
{
return execute();
}
catch(const std::exception& e)
{
// or similar
std::cerr << "Unhandled exception: " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch(...)
{
std::cerr << "Unknown exception!" << std::endl;
return EXIT_FAILURE;
}
}
Now, it's only there "just in case", and it's not really justified. There should be no reason to ever enter that catch clause, as that would mean somebody has done a Bad Thing. Observe how useless the statement really is; "Something bad happened, no clue what!" It's only a step above just crashing in the first place.
The second use might be in destructors or some other function that needs to do manual management before letting the exception propagate. That's not really a justification either, as things should clean themselves up safely with RAII. But I may have used it once or twice for some reason I can't recall, and I can't see a reason to ever do so again.

catch (...) allows you to write code in which you can legitimately claim a guarantee that your code will not crash even when you are not in long term complete control of the submodules your code depends on. Your claim is tantamount to claiming that this semantic cannot be used except as a means of abuse. Maybe so, but military specifications may differ from you on this issue.

catch(...) is necessary in the absence of the finally clause as found in other languages:
try {
...
} catch(...) {
cleanup...
throw;
}
The alternative - making stack objects to 'own' everything - is often much more code and less readable and maintainable. The platform API is often C, and does not come with it conveniently bundled.
It is also useful around plugin code that you do not control or simply do not trust from a stability perspective. It won't stop them crashing, but it might keep things a little saner.
Finally, there are times when you really do not care about the outcome of something.

Related

Can I use a try catch statement to catch any error instead of being specific?

try{
//some function
}catch(...){
//write information to a file including this line number
}
--
What's stopping me from doing this instead of specifying a null pointer exception for instance? The program is going to crash anyways so I might as well catch all errors if there is something I haven't thought about?
It's a myth that every program fault will be caught by catch(...). In particular the behaviour of a null pointer dereference is undefined so there's no guarantee at all that it would be caught there.
If you want a particularly generic catch site, then catching std::exception& is a good idea, as is const char*.
C++11 gives you the ability to inspect the exception in catch(...) to a degree via std::current_exception. See https://en.cppreference.com/w/cpp/error/current_exception.
In Microsoft C, an extension exists that allows you to try and catch exceptions:
void exceptionTest(void)
{
int *zz = NULL;
__try {
*zz += 1;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
printf("gotcha! 0x%08x\n", GetExceptionCode() );
}
}
From the documentation (MSC2008):
The try-except statement is a Microsoft extension to the C language that enables applications to gain control of a program when events that normally terminate execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling.
Exceptions can be either hardware- or software-based. Even when applications cannot completely recover from hardware or software exceptions, structured exception handling makes it possible to display error information and trap the internal state of the application to help diagnose the problem. This is especially useful for intermittent problems that cannot be reproduced easily.
Being specific in exception handling facilitates the bug or probleme analysis by a human or programmatically.
You can build an excpetion handling strategy and eventually recover from an exception. Exception is not necessarily a design flaw resulting in some unexpected null pointer. You may throw exception based on data values or process results to stop the processing or take a decision.
You are confusing things. If you dereference a null pointer then there is no automatically created exception. Dereferencing a null pointer is undefined behaviour. Once it happened its too late for exceptions. They simply wont help a bit.
On the other hand if some code checks for null pointer and then throws an exception, then this only makes sense before the null pointer is dereferenced, ie before undefined behaviour can occur. The program will not "crash anyways" when an exception is thrown in such a case (given that someone catches the exception).
Having said this, nobody will stop you from catching all excpetions. It is just that prior to C++11 you had no way to tell what exception was thrown inside a catch(...) block. C++11 has std::current_exception, though I dont know much about it, so I refer you to documentation.

Catching exceptions in destructors

Is it possible to make a destructor catch exceptions and then re-throw them?
If so, how would I do that, since there isn't a clear place for a try statement?
Basically, I want to ideally do:
CMyObject::~CMyObject()
{
catch(...) // Catch without a try. Possible?
{
LogSomeInfo();
throw; // re-throw the same exception
}
// Normal Destructor operations
}
Background
I have a large, complex application that is throwing an unhandled exception somewhere.
I don't have easy access to main or the top level message-pump or anything similar, so there's no easy place to catch all unhandled exceptions.
I figure any unhandled exception has to pass through a bunch of destructors as the stack is unwound. So, I'm contemplating scattering a bunch of catch statements in destructors. Then at least I'd know what objects are in play when the exception is thrown. But I have no idea if this is possible, or advisable.
EDIT: You can use std::uncaught_exception to check if an exception is currently being thrown (i.e. if stack unwinding is in progress due to an exception). It is not possible to catch that exception or otherwise get access to it from your destructor. So if your logging doesn't need access to the exception itself, you can use
CMyObject::~CMyObject()
{
if(std::uncaught_exception()) {
LogSomeInfo(); // No access to exception.
}
// Normal Destructor operations
}
Note that this question was asked in 2013, meanwhile std::uncaught_exception was replaced with std::uncaught_exceptions (notice the additional s at the end) which returns an int. For a rationale, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152.pdf, so if you are using C++17, you should prefer the new version. The above paper also explains why the old std::uncaught_exception will not work as expected in some situations.
Another option might be std::set_terminate. This is useful if you want to have a method called when an exception is not caught and about to terminate the program. In the terminate handler, I usually print some information about the exception and a (demangled) backtrace of where it originates from to my log file before finally terminating the program. This is compiler and system specific, but a real helper as it saves a lot of time if you write server processes and often the log file is all you get from ops.
You can use std::uncaught_exception() which returns true if and only if there is an exception being processed. It has been available since C++98, and is superseded by std::current_exception which returns a std::exception_ptr.
However you must be careful not to throw another exception in an unguarded context, otherwise std::terminate will be caught. Example:
X::~X() {
if (std::uncaught_exception()) {
try {
LogSomeInfo();
// and do something else...
} catch(...) {}
}
}
A destructor cannot catch the exception that is causing the destruction of the instance.
You can only know if there is any "active exception" (see uncaught_exception) during the destruction (or, in C++17, how many of them there are there with uncaught_exceptions) but it's possible that the exception(s) are indeed going to be handled after that.
Dealing with exceptions is very hard, much harder than someone may think at a first sight and the reason is that exception safety doesn't scale by composition. This in my opinion means that is basically impossible to have non trivial stateful subsystems with strong exception safety (in case of an exception being thrown nothing happened to the internal state). This was discovered long ago (see 1994 Tom Cargill's "Exception handling: A False Sense of Security") but apparently is still ignored by large part of the C++ community.
The only reasonable way to handle exceptions I can think to is to have subsystems with clear well defined interfaces with thick "walls" (no side effect happening inside may escape), and that can be re-initialized to a well known state from scratch if needed when something goes wrong. This not trivial but can be done correctly to a reasonable extent.
In all other cases the global state of the system when an exception is caught is indefinite at best at the point of catch and there are in my opinion few use cases in which you can do anything in such a condition except dying immediately as loudly as possible instead of taking further actions without indeed knowing what is going on (dead programs tell no lie). Even keeping on calling destructors is somewhat questionable in my opinion.
Or you may try to be as functional as possible, but that's not an easy path either (at least for my brain) and it's also moving far away from reality (most computers are mutable objects with many billions of bits of mutable state: you can pretend this is not the case and they're instead mathematical functions with no state and with predictable output dependent on input... but in my opinion you're just deluding yourself).

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.

using catch(...) (ellipsis) for post-mortem analysis

Someone in a different question suggested using catch(...) to capture all otherwise unhandled - unexpected/unforseen exceptions by surrounding the whole main() with the try{}catch(...){} block.
It sounds like an interesting idea that could save a lot of time debugging the program and leave at least a hint of what happened.
The essence of the question is what information can be recovered that way (other than whatever debug globals I leave behind), and how to recover it (how to access and recognize whatever catch was called with)
Also, what caveats are connected with it. In particular:
will it play nice with threads that sprout later?
will it not break handling segfaults (captured elsewhere as signal)
will it not affect other try...catch blocks inevitably nested inside, that are there to handle expected exceptions?
Yes it is a good idea.
If you let an exception escape main it is implementation defined weather the stack is unwound before the application is shut down. So in my opinion it is essential you catch all exceptions in main.
The question then becomes what to do with them.
Some OS (See MS and SE) provide some extra debugging facilities so it is useful to just re-throw the exception after you catch it (because the stack has been unwound now anyway).
int main()
{
try
{
/// All real code
}
// I see little point in catching other exceptions at this point
// (apart from better logging maybe). If the exception could have been caught
// and fixed you should have done it before here.
catch(std::exception const& e)
{
// Log e.what() Slightly better error message than ...
throw;
}
catch(...) // Catch all exceptions. Force the stack to unwind correctly.
{
// You may want to log something it seems polite.
throw; // Re-throw the exception so OS gives you a debug opportunity.
}
}
will it play nice with threads that sprout later?
It should have no affect on threads. Usually you have to manually join any child threads to make sure that they have exited. The exact details of what happens to child threads when main exits is not well defined (so read your documentation) but usually all child threads will die instantly (a nasty and horrible death that does not involve unwinding their stacks).
If you are talking about exceptions in child threads. Again this is not well defined (so read your documentation) but if a thread exits via an exception (ie the function used to start the thread exits because of an exception and not a return) then this usually causes the application to terminate (same affect as above). So it is always best to stop ALL exceptions from exiting a thread.
will it not break handling segfaults (captured elsewhere as signal)
Signals are not affected by the exception handling mechanism.
But because signal handlers may place an odd structure on the stack (for their own return handling back to normal code) it is not a good idea to throw an exception from within a signal handler as this may cause unexpected results (and is definitely not portable).
will it not affect other try...catch blocks inevitably nested inside, that are there to handle expected exceptions?
Should have no effect on other handlers.
As far as I remember, catch(...) on Win32 catches also SEH exceptions, and you do not want to do that. If you get a SEH exception it's because something very scary happened (mainly access violations), so you can't trust your environment anymore. Almost everything you could do may fail with another SEH exception, so it's not even worth trying. Moreover, some SEH exceptions are intended to be caught by the system; more on this here.
So, my advice is to use a base exception class (e.g. std::exception) for all your exceptions, and catch just that type in the "catchall"; your code cannot be prepared to deal with other kind of exceptions, since they are unknown by definition.
A global try catch block is useful for production systems, in order to avoid displaying a nasty message to the user. During development I believe that are best avoided.
Regarding your questions:
I believe that a global catch block won't catch exceptions in another thread. Each thread has its own stack space.
I am not sure about this.
Nested try...catch blocks aren't affected and will execute as usual. An exception propagates up the stack, until it finds a try block.
You could try a solution I use if you're making a .net application. That captures all unhandled exceptions. I generally only enable the code (with #ifndef DEBUG) for production code when I'm not using the debugger.
It's worth pointing out as kgiannakakis mentions that you can't capture exceptions in other threads, but you can use the same try-catch scheme in those threads and post the exceptions back to the main thread where you can re-throw them to get a full stack track of what went wrong.
and how to recover it (how to access
and recognize whatever catch was
called with)
If you mean how to recover the type of exception that was thrown, you can chain catch blocks for specific types (proceeding from more specific to more general) before falling back to catch (...):
try {
...
} catch (const SomeCustomException& e) {
...
} catch (const std::bad_alloc& e) {
...
} catch (const std::runtime_error& e) {
// Show some diagnosic for generic runtime errors...
} catch (const std::exception& e) {
// Show some diagnosic for any other unhandled std::exceptions...
} catch (...) {
// Fallback for unknown errors.
// Possibly rethrow or omit this if you think the OS can do something with it.
}
Note that if you find yourself doing this in multiple places and want to consolidate code (maybe multiple main functions for separate programs), you can write a function:
void MyExceptionHandler() {
try {
throw; // Rethrow the last exception.
} catch (const SomeCustomException& e) {
...
}
...
}
int main(int argc, char** argv) {
try {
...
} catch (...) {
MyExceptionHandler();
}
}
A catch-all will not be terribly useful since there is no type/object information that you can query. However, if you can make sure all exceptions raised by your application are derived from a single base object, you can use a catch block for the base exception. But then that wouldn't be a catch-all.

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)