Which kind of code is considered exception safe? - c++

A code which handles the exceptions well is called an exception safe code? Is this correct?
From here: https://codereview.stackexchange.com/a/9759/11619
You use lock/unlock pairs for the mutex. This is not exception safe.
So I would create an object that will do the lock in the constructor
and unlock in the destructor then use this to lock your mutexs. This
will make your code more exception safe.
class MutexLocker
{
pthread_mutex_t& mutex;
MutextLocker(pthread_mutex_t& mutex)
: mutex(mutex)
{
pthread_mutex_lock(&mutex);
}
~MutexLocker()
{
pthread_mutex_unlock(&mutex);
}
};
In which way is the above shown code exception safe? I don't see any exception handling over there.
Or does exception safe code mean where we can "add" the exception handling? So, the above shown code can be made exception safe by adding exception handling, but it isn't now?

Exception Safety is not about handling exceptions, it is about guaranteeing a number of properties about the program even in the presence of exceptions.
You can usually speak about the exception safety level of a given method:
No Guarantee: this method is exception unsafe, that is no guarantee is made, at all.
Basic Exception Guarantee: in case of exception no resource is leaked and the classes involved are still usable (but their state is unspecified), that is no memory leak, no file handle leak, no mutex leak and the invariants of the instances involved are still verified.
Strong Exception Guarantee: in case of exception, all state is reversed to what it was prior to beginning. This is a transaction like semantic.
NoThrow Guarantee: this method does not throw, it always succeeds.
In general, the NoThrow Guarantee only applies to the simplest methods (ie .size() on a vector for example) and the Strong Exception Guarantee may be costly to implement (being able to revert the effect or operating on a copy of the state may not be cheap).
On the other hand, the Basic Exception Guarantee is just that: Basic. Without it, safely operating a program is just impossible, so this is the least guarantee that is acceptable. If you leak resources or leave classes in an unusable state, the program may not be able to operate further.
This is why there is such an emphasis on RAII whenever exceptions are mentionned. Because RAII guarantees automatic cleanup of resources (memory, mutexes, files) whatever the path execution (regular return or exception) it is particularly desirable. However, RAII itself is not sufficient.
Related: Herb Sutter's GotW entry about Exception Safety and Exception Specifications.

the MutexLocker destructor is always called, also when an exception was raised in the block where it was constructed.
that is what makes a construct using your MutexLocker exception safe.

You don't have to handle an exception to be exception safe. You just have to survive when an exception is thrown.
The MutexLocker helps you do this by unlocking the mutex when you leave the scope. It doesn't matter if you leave by a return statement or because an exception is thrown.

"Exception safe" is a fairly overloaded term, but I would use it to describe sections of code which can have exceptions thrown through them and still maintain certain invariants (such as - nothing changes, no resources are leaked, all objects keep a valid state).
As an example, your void * printHello (void* threadId) function is correct (in that it always matches pthread_mutex_lock (&demoMutex) with pthread_mutex_unlock (&demoMutex)), but if someone changed the section in the middle so that it could throw an exception (for example, by setting the throw flags on std::cout), then your code would then permanently lock demoMutex, with no hope for it ever being released. This would constitute a bug in your program. void * printHello (void* threadId) is said to be "exception unsafe" because of this way in which bugs can easily be introduced into your program by adding exception handling to seemingly unrelated parts.
Using a RAII class to manage resources a good way to go about writing exception safe code (and is the resource management style to use in C++), because it avoids the need for duplicate manual cleanup in catch(...) blocks, and it enforces the cleanup of resources by using the type system.

A code which handles the exceptions well is called an exception safe code?
Yes, but you do not say what well is. This is a good read on exception safety.
In which way is the above shown code exception safe?
That code is not exception safe in itself. That is meant to be used in a exception safe code. For example :
void bar()
{
throw std::runtime_error( "lala" );
}
void foo()
{
pthread_mutex_lock(&mutex);
bar();
// OPS! mutex not unlocked
pthread_mutex_unlock(&mutex);
}
This problem is solved by using the class that automatically unlock the exception. Next example has exception handling with strong guarantees :
void foo()
{
MutexLocker locker( mutex );
try {
bar();
} catch ( const std::runtime_error & )
{
// revert changes
}
}

The code you provided serves the purpose well. Simply because when execution leaves the block in which the MutexLocker object is defined, the object is destroyed and the mutex is released as per its destructor. This holds no matter the reason for the exit.
You don't have to code this class yourself though. The C++ standard specifies a class named lock_guard that does exactly that.
http://en.cppreference.com/w/cpp/thread/lock_guard

Related

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

Is it appropriate to throw from destructor in this case

I have a class that distributes work given by the user to several threads. Something like (simplified):
class MT {
public:
MT();
void work1(/*args*/);
void work2(/*args*/);
void work3(/*args*/);
//waits until all threads complete, returns whether the work has been completed
//successfully, throws any exceptions that have been raised in the threads.
bool is_ok();
~MT();
private:
// thread pool
}
The user uses the class as follows:
void foo()
{
MT mt;
mt.work1(/*userdata*/);
mt.work2(/*userdata*/);
mt.work1(/*userdata*/);
status = mt.is_ok();
if (status) {
mt.work3(/*userdata*/);
//...
}
//...
}
The class is never part of some object, always stored on the stack.
The Problem
I want to somehow emit any exceptions that have been raised while doing work in other threads. Unfortunately, I know whether a thread has successfully completed only after joining it. Thus, I must choose between the following two alternatives:
Join the threads in the destructor of MT and throw exceptions that arose while doing work, if any. If more than one exception has been thrown, pick the one that came from the earliest task. If the destructor is called doing stack unwinding (we can check this using std::uncaught_exception, swallow any exceptions to prevent terminate().
Instruct the user to always call is_ok before the destructor.
I think the first option is cleaner, since the user is not required to call anything. However, throwing from destructor is usually very strongly discouraged. The presented arguments are:
Throwing from destructors is dangerous, because this might happed during stack unwinding and lead to terminate().
Even if the above is addressed, throwing or not throwing depending on whether stack is being unwound is a substantial change of behavior and should be discouraged.
Exceptions signify that a postcondition have not been met. The postcondition of a destructor is resource cleanup, this must be possible in any circumstances.
Somehow I am inclined to think that the above arguments don't apply here:
I handle the stack unwinding problem properly
Due to the usage pattern, any exceptions that exit from foo means that work has been failed. Throwing or not throwing in the destructor is not a substantial change of behavior.
The postconditions of the destructor are not only resource cleanup, but also that the work has been completed successfully. Thus an exception should be appropriate.
Questions
Do you think throwing from destructor is appropriate in this case?
No, don't throw from the destructor. Call is_ok, catch and ignore. Same as close() for streams.
The user can call is_ok if they want to be sure that the work has been completed, and it will throw an exception on failure.
In practice this is rarely inconvenient. It will be if the user writes a function with multiple return points, but (unfortunately) that's a problem they just have to deal with because C++ doesn't provide a means for you to do it for them. If you think this is anti-social, well, look at what happens if you destroy a std::thread in C++11 without first either joining it or detaching it. You're beating that :-)
So, user calls is_ok on all non-error exit paths. User doesn't bother calling it when there's already an exception, because they can't deal with another one anyway. Again, this is the same as close() for streams: if you want to see errors from writing your buffered stream then you just have to close or flush explicitly.
Even if the above is addressed, throwing or not throwing depending on
whether stack is being unwound is a substantial change of behavior and
should be discouraged.
It's also not possible to do correctly, at least in C++03. I don't know whether C++11 changes anything in this respect, but std::uncaught_exception does not tell you what you need to know, as Herb Sutter explains.
From your link to cppreference.com:
Any exception thrown while std::uncaught_exception() == true calls std::terminate.
I'm pretty sure this is false. terminate is called if an exception escapes a destructor that is called as part of stack unwinding, but it isn't called just because a destructor throws and catches an exception during unwinding.
If the caller thinks they can do something useful with an exception thrown in a destructor, then they can write a helper class that calls is_ok in its destructor, and put that over your object. If you think there's something useful that your class can do with the same exception then you can do something other than merely ignore it in your destructor, but you still shouldn't allow it to leave the destructor.

Any pitfalls with allocating exceptions on the heap?

Question says it all: Are there any pitfalls with allocating exceptions on the heap?
I am asking because allocating exceptions on the heap, in combination with the polymorphic exception idiom, solve the problem of transporting exceptions between threads (for the sake of discussion, assume that I can't use exception_ptr). Or at least I think it does...
Some of my thoughts:
The handler of the exception will have to catch the exception and know how to delete it. This can be solved by actually throwing an auto_ptr with the appropriate deleter.
Are there other ways to transport exceptions across threads?
Are there any pitfalls with allocating exceptions on the heap?
One obvious pitfall is that a heap allocation might fail.
Interestingly, when an exception is thrown it actually throws a copy of the exception object that is the argument of throw. When using gcc, it creates that copy in the heap but with a twist. If heap allocation fails it uses a static emergency buffer instead of heap:
extern "C" void *
__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw()
{
void *ret;
thrown_size += sizeof (__cxa_refcounted_exception);
ret = malloc (thrown_size);
if (! ret)
{
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
bitmask_type used = emergency_used;
unsigned int which = 0;
if (thrown_size > EMERGENCY_OBJ_SIZE)
goto failed;
while (used & 1)
{
used >>= 1;
if (++which >= EMERGENCY_OBJ_COUNT)
goto failed;
}
emergency_used |= (bitmask_type)1 << which;
ret = &emergency_buffer[which][0];
failed:;
if (!ret)
std::terminate ();
}
}
So, one possibility is to replicate this functionality to protect from heap allocation failures of your exceptions.
The handler of the exception will have to catch the exception and know how to delete it. This can be solved by actually throwing an auto_ptr with the appropriate deleter.
Not sure if using auto_ptr<> is a good idea. This is because copying auto_ptr<> destroys the original, so that after catching by value as in catch(std::auto_ptr<std::exception> e) a subsequent throw; with no argument to re-throw the original exception may throw a NULL auto_ptr<> because it was copied from (I didn't try that).
I would probably throw a plain pointer for this reason, like throw new my_exception(...) and catch it by value and manually delete it. Because manual memory management leaves a way to leak memory I would create a small library for transporting exceptions between threads and put such low level code in there, so that the rest of the code doesn't have to be concerned with memory management issues.
Another issue is that requiring a special syntax for throw, like throw new exception(...), may be a bit too intrusive, that is, there may be existing code or third party libraries that can't be changed that throw in a standard manner like throw exception(...). It may be a good idea just to stick to the standard throw syntax and catch all possible exception types (which must be known in advance, and as a fall-back just slice the exception and only copy a base class sub-object) in a top-level thread catch block, copy that exception and re-throw the copy in the other thread (probably on join or in the function that extracts the other's thread result, although the thread that throws may be stand-alone and yield no result at all, but that is a completely another issue and we assume we deal with some kind of worker thread with limited lifetime). This way the exception handler in the other thread can catch the exception in a standard way by reference or by value without having to deal with the heap. I would probably choose this path.
You may also take a look at Boost: Transporting of Exceptions Between Threads.
There are two evident one:
One - easy - is that doing throw new myexception risk to throw a bad_alloc (not bad_alloc*), hence catch exception* doesn't catch the eventual impossible to allocate exception. And throwing new(nothrow) myexception may throw ... a null pointer.
Another - more a design issue - is "who has to catch". If it is not yourself, consider a situation where your client, that may also be a client of somebody else, has - depending on who's throwing - to decide if delete or not. May result in a mess.
A typical way to solve the problem is throwing a static variable by reference (or address): doesn't need to be deleted and doesn't require to be copied when going down in the unrolled stack
If the reason you're throwing an exception is that there's a problem with the heap (out of memory or otherwise) allocating your exception on the heap will just cause more problems.
There is another catch when throwing std::auto_ptr<SomeException>, and also boost shared pointers: while runtime_error is derived from exception, auto_ptr<runtime_error> is not derived from auto_ptr<exception>.
As a result, a catch(auto_ptr<exception> &) won't catch an auto_ptr<runtime_error>.

Destructor that calls a function that can throw exception in C++

I know that I shouldn't throw exceptions from a destructor.
If my destructor calls a function that can throw an exception, is it OK if I catch it in the destructor and don't throw it further? Or can it cause abort anyway and I shouldn't call such functions from a destructor at all?
Yes, that's legal. An exception must not escape from the destructor, but whatever happens inside the destructor, or in functions it calls, is up to you.
(Technically, an exception can escape from a destructor call as well. If that happens during stack unwinding because another exception was thrown, std::terminate is called. So it is well-defined by the standard, but it's a really bad idea.)
Yes.
Look at the std::fstream class in the standard library for an example.
close() could potentially throw an exception.
The destroctor can call close() but the destructor does not throw (it will swallow any exceptions).
The concept is that if the destructor calls any methods that can throw then these methods should be public. Thus if the user of your object wants to check for exceptions they can use the public methods and handle the exception. If they do not care about the exception then just let the destructor handle the problem.
Going back to the std::fstream example.
{
std::fstream text("Plop");
// Load Text.
// I don't care if the close fails.
// So let the destructor handle it and discard exceptions
}
{
// If this fails to write I should at least warn the user.
// So in this case I will explicitly try and close it.
try
{
std::ofstram password("/etc/password");
// Update the password file.
password.close();
}
catch(...)
{
Message.ShowDialog("You failed to update the Password File");
}
}
You can find some examples here: https://software.intel.com/sites/products/documentation/doclib/iss/2013/sa-ptr/sa-ptr_win_lin/GUID-D2983B74-74E9-4868-90E0-D65A80F8F69F.htm
If an exception leaves destructor during stack unwinding of another exception being propagated, then std::terminate() is called.
When no stack unwinding is in progress, an exception can leave destructor without std::terminate() getting called. However, for objects allocated on heap this will result in memory leak because "operator delete" will not be called for the object who throws exception out of its destructor. Surprisingly, the destructor of base class still gets called in this case: What happens to base class destructor if a derived class destructor throws an exception
If the exception is catched inside the destructor (so that the exception does not leave the destructor), then no problem even if stack unwinding of another exception is in progress. This case is described more deeply here: http://bin-login.name/ftp/pub/docs/programming_languages/cpp/cffective_cpp/MEC/MI11_FR.HTM
Simple answer, never allow an exception from a dtor!
The complicated answer. You only get really nailed if the exception escapes the dtor while another exception is active. The normal case for this is when you are already unwinding the stack from another exception and the object in question is destroyed. In that case if the exception escapes the dtor then std::terminate is called, note you can put in your own handler for std::terminate by calling std::set_terminate. The default implementation of std::terminate is to call abort.
To complicate things more, most functions that want to make any guarantee about their exception safety, mainly the basic guarantee or the strong guarantee, rely on the underlying types to themselves not throw in their dtor*
The real question is, what state would your program be in when this error occurs? How can you recover? Where should this recovery be handled? You need to look at your specific case and work these issues out. Sometimes it's just fine to catch the exception and ignore it. Other times you need to raise some red flags.
So the answer is: it allowed by C++ to throw an exception in a dtor, but you shouldn't ever allow it to escape.
*Here's a brief synopsis of the exception guarantees (here's a much longer article)
Recap: Briefly define the Abrahams exception safety guarantees (basic,
strong, and nothrow).
The basic guarantee is that failed
operations may alter program state,
but no leaks occur and affected
objects/modules are still destructible
and usable, in a consistent (but not
necessarily predictable) state.
The strong guarantee involves
transactional commit/rollback
semantics: failed operations guarantee
program state is unchanged with
respect to the objects operated upon.
This means no side effects that affect
the objects, including the validity or
contents of related helper objects
such as iterators pointing into
containers being manipulated.
The nothrow guarantee means that
failed operations will not happen. The
operation will not throw an exception.
You may find this page from C++ FAQ Lite to be informative. The basic answer is, "don't do it." Where exactly do you plan to catch this exception? Whatever you plan on doing when you catch that exception, just do it with a function call instead or something (e.g. log it or set a flag to warn the user or whatever). Throwing exceptions from the destructor runs the risk of causing your entire program to terminate.

Unlocking the critical section in case of non-C++ exceptions

I have a object of CCriticalSection in my class to synchronize the exceptions to a method. I use it with CSingleLock object like this:
void f()
{
try
{
CSingleLock lock(&m_synchronizer, TRUE);
.....
.....
}
catch(SomeException )
{
}
catch(...)
{
}
}
The critical section object is properly unlocked if any of the statement throws a C++ exception, however if I get any other type of exception (something like a access violation) is there any way I can unlock my critical section? I don't think RAII will help here as the stack unwinding doesn't happen. Is there any thing I can do to prevent the critical section being in locked state after exiting the function f?
EDIT Update
The destructor of CSingleLock will indeed unlock the underlying critical section. Access violations and the like are called SEH exceptions. As to whether or not the destructor will run in the face of an SEH exception is very environment specific. There are tricks you can do to make this type of scenario work.
For instance, one option is to translate all SEH exceptions into a corresponding C++ exception. I blogged recently on the technique to accomplish this. Once they're all C++ exceptions then the destructor being called is guaranteed.
http://blogs.msdn.com/jaredpar/archive/2008/01/11/mixing-seh-and-c-exceptions.aspx
But another question is why bother doing this? Once you're faced with at access violation the only thing your program can reliably do is crash.
Assuming you're using MSVC try compiling with the /EHa command line option which maps Windows' structured exceptions to C++ exceptions (the C++ docs sometimes call them 'asynchronous' exceptions).
You should read up on the implications of this - I don't use the option myself, and I'm not sure what the drawbacks might be.
You could also try using the __try, __except, __finally keywords to handle SEH yourself.
RAII does help here. The most important thing to not here is "going out of scope" is not necessarily just stack unwinding. When the try block is exited, either normally or through an exception, the destructor will be called. Anytime your variable goes out of scope its destructor is invoked.
Edit
Hmm it appears the question has been edited to focus on SEH (non C++ exceptions). In this case the destructor code might not be fired. However, as others have pointed out, most of the non-C++ exceptions are equivalent to application crashes. It may not be reasonable to react to these exceptions in any sane way other than to crash. In this case your app is exited and your critical section will be destroyed anyway.
See #JaredPar's answer for a good solution for translating C SEH exceptions to C++ exceptions for Windows.
If you really need your application to survive when a particular area of code performs an access violation, you should consider having that code in a separate process.
If code is trying to read or write to places it's not allowed, what's to stop it writing into other parts of your application's memory, causing all sorts of nasty problems?
AFAIK, you NEVER should use CCriticalSection nor any MFC synchronization object.