Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 994
SF. Avatar asked Feb 02 '10 09:02

SF.


1 Answers

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.

like image 61
Martin York Avatar answered Sep 29 '22 23:09

Martin York