I’m pretty good with exception handling in C/C++ – I know all about creating custom classes from std::exception, when to throw, when to fall back on simpler things like UNIX errno, etc. I do have one thing I’m always a little foggy about though when it comes to accessing COTS code.
If I call a function from a COTS library like so:
void DoSomething()
{
try
{
CallCotsFunction();
}
catch (CotsException& ce)
{
//Cots error caught
}
catch (...)
{
//Unknown error caught.
}
}
If CallCotsFunction() has poor exception handling or no exception handling and performs a divide-by-zero or something, will it get propagated up to my exception handlers?
If CallCotsFunction() causes a sig-11 or something of that sort will it get caught, or are all bets off with something that severe?
On Linux, unix signals do not normally trigger exception handlers. Additionally, it is, generally speaking, unsafe to throw an exception from a signal handler (at a minimum, you must compile with
-fnon-call-exceptions; even then I’ve seen mixed reports).Note also that you should always catch exceptions by reference, to avoid slicing:
In short: If your third-party library lets a C++ exception propagate up without being caught, yes, it’ll hit your application. If it’s derived from std::exception or some other common type, you should be able to catch it. If it’s some internal type not exposed to you, you won’t be able to catch it by name (but
catch (...)should catch it). CPU exceptions (divide by zero, segfaults, etc) will not automatically trigger C++ exceptions, unless you or the library installs a signal handler to convert it; in which case the code triggering the signal MUST be built with-fnon-call-exceptionsfor stack unwind to work properly.In general, if the library triggers a fault such as SIGFPU or SIGSEGV, the results of trying to recover with an exception are unpredictable; the library may not be expecting to unwind its stack at that point, and with SIGSEGV, you may have heap corruption that causes the exception-throwing system itself to fault. I would not recommend trying to recover in this way – just let the process die.