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

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.

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

Will main() catch exceptions thrown from threads?

I have a pretty large application that dynamically loads shared objects and executes code in the shared object. As a precaution, I put a try/catch around almost everything in main. I created a catch for 3 things: myException (an in house exception), std::exception, and ... (catch all exceptions).
As part of the shared objects execution, many pthreads are created. When a thread throws an exception, it is not caught by main. Is this the standard behavior? How can I catch all exceptions, no matter what thread they are thrown from?
Will main() catch exceptions thrown from threads?
No
When a thread throws an exception, it is not caught by main. Is this the standard behavior?
Yes, this is standard behaviour.
To catch an exception originating in thread X, you have to have the try-catch clause in thread X (for example, around everything in the thread function, similarly to what you already do in main).
For a related question, see How can I propagate exceptions between threads?
Your question is asking for something that isn't conceptually possible.
Try blocks are defined as dynamic constructs of the stack. A try block catches exceptions thrown by code reached dynamically, by call, from its contents.
When you create a new thread, you create a brand-new stack, that is not at all part of the dynamic context of the try block, even if the call to pthread_create is inside the try.
No, main will not catch exceptions thrown from other threads. You would need to use a non-standard, platform specific facility that addresses unhandled exceptions in order to aggregate the handling the way you are describing.
When I build such applications, I make sure each active object has its own top-level exception handling block, precisely to prevent the entire application from exploding if one thread fails. Using a platform-specific catch all I think begs for your overall code / solution to be sloppy. I would not use such a thing.
Consider that throwing an exception unwinds the stack. Each thread has its own stack. You will have to place a try/catch block in each thread function (i.e. in the entry point of each thread).

Is it "legal" for C++ runtime to call terminate() when the C++ code is used inside some non-C++ program?

In certain cases - especially when an exception escapes a destructor during stack unwinding - C++ runtime calls terminate() which must do something reasonable post-mortem and then exit the program. When a question "why so harsh" arises the answer is usually "there's nothing more reasonable to do in such error situations". That sounds reasonable if the whole program is in C++.
Now what if the C++ code is in a library and the program that uses the library is not in C++? This happens quite often - for example I might have a native C++ COM component consumed by a .NET program. Once terminate() is called inside the component code the .NET program suddenly ends abnormally. The program author will first of all think "I don't care of C++, why the hell is this library make my program exit?"
How do I handle the latter scenario when developing libraries in C++? Is it reasonable that terminate() unexpectedly ends the program? Is there a better way to handle such situations?
Why is the C++ runtime calling terminate()? It doesn't do it at random, or due to circumstances which cannot be defined and/or avoided when the code is written. It does it because your code does something that is defined to result in a call to terminate(), such as throwing an exception from a destructor during stack unwinding.
There is a list in the C++ standard of all the situations which are defined to result in call to terminate(). If you don't want terminate() to be called, don't do any of those things in your code. The same applies to unexpected(), abort(), and so on.
I don't think this is any different really from the fact that you have to avoid undefined behavior, or in general avoid writing code which is wrong. You also have to avoid behavior which is defined but undesirable.
Perhaps you have a particular example where it is difficult to avoid a call to terminate(), but throwing an exception from a destructor during stack unwinding isn't it. Just don't throw exceptions out of destructors, ever. This means designing your destructors such that if they do something which might fail, the destructor catches the exception and your code continues in a defined state.
There are some situations where your system will impolitely hack your process away at the knees because of something that your C++ code does (although not by calling terminate()). For example, if the system is overcommitting memory and the VMM can't honour the promises malloc/new have made, then your process might be killed. But that's a system feature, and probably applies equally to the other language that's calling your C++. I don't think there's anything you can (or need to) do about it, as long as your caller is aware that your library might allocate memory. In that circumstance it's not your code's fault the process died, it's the defined response of the operating system to low-memory conditions.
I think the more fundamental issue isn't specifically what terminate does, but the library's design. The library may be designed to be used only with C++ in which case exceptions can be caught and handled as appropriate within the app.
If the library is intended to be used in conjunction with non-C++ apps, it needs to provide an interface that ensures no exceptions leave the library, for example an interface that does a catch(...).
Suppose you have a function in C++ called cppfunc and you are invoking it from another langugage (such as C or .NET). I suggest you create a wrapper function, let's say exportedfunc, like so:
int exportedfunc(resultype* outresult, paramtype1 param1, /* ... */)
{
try {
*outresult = cppfunc(param1,param2,/* ... */);
return 0; // indicate success
}catch( ... ) { // may want to have other handlers
/* possibly set other error status info */
return -1; // indicate failure
}
}
Basically, you need to ensure that exceptions do not cross language boundaries... so you need to wrap your C++ functions with a function that catches all exceptions and reports a status code or does something acceptable other than invoking std::terminate.
The default terminate handler will call abort. If you don't want this behavior, define your own terminate handler and set it using set_terminate.

When is a C++ terminate handler the Right Thing(TM)?

The C++ standard provides the std::set_terminate function which lets you specify what function std::terminate should actually call. std::terminate should only get called in dire circumstances, and sure enough the situations the standard describes for when it's called are dire (e.g. an uncaught exception). When std::terminate does get called the situation seems analagous to being out of memory -- there's not really much you can sensibly do.
I've read that it can be used to make sure resources are freed -- but for the majority of resources this should be handled automatically by the OS when the process exits (e.g. file handles). Theoretically I can see a case for if say, you needed to send a server a specific message when exiting due to a crash. But the majority of the time the OS handling should be sufficient.
When is using a terminate handler the Right Thing(TM)?
Update: People interested in what can be done with custom terminate handlers might find this non-portable trick useful.
This is just optimistic:
but for the majority of resources this should be handled automatically by the OS when the process exits
About the only resources that the OS handles automatically are "File Handles" and "Memory" (And this may vary across OS's).
Practically all other resources (and if somebody has a list of resources that are automatically handled by OS's I
would love that) need to be manually released by the OS.
Your best bet is to avoid exit using terminate() and try a controlled shut down by forcing the stack to unwind correctly.
This will make sure that all destructors are called correctly and your resources are released (via destructors).
About the only thing I would do is log the problem. So that when it does happened I could go back and fix the code so that it does not happen again. I like my code to unwind the stack nicely for resource deallocation, but this is an opinion some people like abrupt halts when things go badly.
My list of when terminate is called:
In general it is called when the exception handling mechanism cannot find a handler for a thrown exception. Some specific examples are:
An exception escapes main()
Note: It is implementation defined whether the stack is unwound here.
Thus I always catch in main and then rethrow (if I do not explicitly handle).
That way I guarantee unwinding of the stack (across all platforms) and still get the benefits of the OS exception handling mechanism.
Two exceptions propagating simultaneously.
An exception escapes a desatructor while another exception is propagating.
The expression being thrown generates an exception
An exception before or after main.
If an exception escapes the constructor/destructor of a global object.
If an exception escapes the destructor of a function static variable.
(ie be careful with constructors/destructors of nonlocal static object)
An exception escapes a function registered with atexit().
A rethrow when no exception is currently propagating.
An unlisted exception escapes a method/function that has exception specifier list.
via unexpected.
Similar to a statement made in Martin York's answer, about the only thing I do in a custom terminate handler is log the problem so I can identify and correct the offending code. This is the only instance I find that using a custom terminate handler is the Right Thing.
Since it is implementation-defined whether or not the stack is unwound before std::terminate() is called, I sometimes add code to generate a backtrace in order to locate an uncaught exception1.
1) This seems to work for me when using GCC on Linux platforms.
I think the right question would be how to avoid the calls to terminate handler, rather than when to use it.

Why does my program terminate when an exception is thrown by a destructor?

I am not getting why if there is an active exception then if an exception is raised again, it leads to termination of program. Could someone explain?
What is it suppose to do? It can't "double catch" or anything, nor does it make sense to simply ignore one. The standard specifies that if, during stack unwinding, another exception escapes, then terminate shall be called.
There is more discussion in the C++ FAQ. One "solution" is to wrap your destructor code in a try/catch block, and simply don't let exceptions escape.
Another is to come up with some sort of custom exception chaining scheme. You'd do the above, but instead of ignoring an exception, you would append it to the currently thrown exception, and at the catch site handle both by hand.
The best solution, I think, it to try to remove the exceptional code from your destructor.
The reason is simple... if an exception is thrown during exception propagation, then which exception should be propagated? The original exception or the new exception? If the new exception is propagated and then handled, how will the program know that the other exception occurred? Or will the original exception be ignored? This and many other complications lead to the simple rule that only one exception may be propagated at a time, and multiple failures will result in the application being terminated.
Quoth the standard (15.2.3):
The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called ``stack unwinding.'' [Note: If a destructor called during stack unwinding exits with an exception, terminate is called (except.terminate). So destructors should generally catch exceptions and not let them propagate out of the destructor.
--- end note]
Basically C++ (as most other popular programming languages) has no good support for handling multiple errors using exceptions. Exceptions, as a mechanism, is simply deficient in that respect.
The FAQ has some suggestion on How to handle a destructor that fails?
Stroustroup has this to say on the matter (TCPL 14.7):
The reason for terminate() is that exception handling must occasionally be abandoned for less subtle error-handling techniques. For example, terminate() could be used to abort a process or maybe to re-initialize a system. The intent is for terminate() to be a drastic measure to applied when the error-recovery strategy implemented by the exception-handling mechanism has failed and it is time to go to another level of a fault tolerance strategy.
See also previous related discussion on SO: basically any question about exceptions and destructors.
This post has an explanation of the problem:
http://web.tiscali.it/fanelia/cpp-faq-en/exceptions.html#faq-17.3
When you throw an exception, it keeps unwinding the stack until it reaches an appropriate catch block. As part of the stack unwinding process, destructors are called for every object in each frame's scope.
Now, when a destructor throws an exception in this case, there's a dilemma -- which catch block is the program supposed to stop at? The original exception, or the new exception? Either way, there's an unprocessed exception involved.
Program's aren't good at making decisions like this, so the standard says it won't even try to resolve the issue and just gives up.
Check out the FAQ-Lite entry explaining this exact situation for further details.
Item 8 of Effective C++ says that you shouldn't ever allow an exception to leave a destructor.