RE: GCC 4.6.2 C++ thread cancellation issue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Just to be clear, I am using pthread's synchronous cancellation feature - i.e., cancellation can only occur at known "cancellation points", which are places at which the thread is waiting to be rescheduled.  So the cancellation is not asynchrounous with respect to thread execution.

Stack unwinding/destructor excecution does occur in the Solaris C++ implementation from the scope enclosing the cancellation point. In my view, this behavior is required to compose a correctly running program.  A very common approach to resource management in C++ programs is to use a constructor to "acquire" a resource and the destructor to "release" it.  Since a thread is just one part of a running program, being able to cancel a thread without running destructors would be (and for me, is) very bad, as it would hang acquired resources out to dry (such as a mutex lock, for instance) with disastrous results (deadlocks).  

Again in my view, the use of catch(...) is an undesireable practice; if you need something to happen no matter how a scope is exitted (like Java's finalize), its much better to encapsulate that behaviour in an object's destructor.  But, if catch(...) must be used, it should be oblivious to the pthread_cancellation mechanism.  Othewise, you put it on the programmer to cooperate with your cancellation mechanism (like g++ does, requiring the "special" exception to be caught and rethrown), and if they do not do so unfailingly, then bad things will likely occur (like an abort, in the g++ case).  It also means any vendor library that was developed without this requirement in mind would be completely unreliable when used in a threaded environment.  Simply untenable.

Anyway, I will do what you suggest and post the examples to bugzilla.  Thanks again for your time and observations.
________________________________________
From: Ian Lance Taylor [iant@xxxxxxxxxx]
Sent: Tuesday, May 15, 2012 11:00 AM
To: Mike Dalpee
Cc: gcc-help@xxxxxxxxxxx
Subject: Re: GCC 4.6.2 C++ thread cancellation issue

Mike Dalpee <mikedalpee@xxxxxxxxxxxx> writes:

> But here's the thing.  With Solaris C++, thread cancellation just worked - when a thread is cancelled, the stack is unwound, destructors run, and there is no visibility outside the runtime of the mechanism used to accomplish that.  I guess I don't see why the g++ runtime could not do the same thing, and rather than exposing the "foreign" thread cancellation exception abi::__forced_unwind to the outside world, thereby requiring special handling for it to even have a chance of  working properly, instead keep it hidden and treat it as a one-of-a-kind, special "foreign" exception that just causes stack unwinding/destructor execution.
>
> Of course, I realize this is likely the topic of much debate, and gcc's implemention is probably an attempt to be compliant with the evolving c++ standard.  But clearly, g++'s approach is highly flawed, so perhaps the standard needs to be driven in a way such that g++ can ultimately provide the Solaris-style thread cancellation semantics.
>
> Unfortunately for me, this really causes huge problems with my porting efforts.  In effect, it means there is no reliable way to cancel a thread that is written is C++ and uses exception handlers.  Not sure how I am going to overcome that.

I agree that this is a real bug.  On the other hand I've always
considered asynchronous thread cancellation to be a rather shaky
proposition.  Apparently Solaris has managed to do a good implementation
of it, but it's never going to be portable.

The root issue here is that glibc implements thread cancellation as an
exception, using the language independent exception mechanisms.  Those
mechanisms are designed to let one language catch an exception thrown by
another language, which is not what you want to have happen here.  In
fact this exception should not be caught at all.

Glibc does this because it lets it rely on the existing exception
mechanisms to efficiently implement pthread_cleanup_push.  It also lets
pthread_cancel run C++ destructors; I don't know if that is a good idea
or not.  Does that happen on Solaris?  I don't know if this is covered
by any OS or language standards.  C++ did not discuss threads at all
before C++11, and as far as I know C++11 has no asynchronous thread
cancellation facility.  It's a collision of paradigms and I don't know
what the right answer is.

If pthread_cancel is going to run C++ destructors, then the next
question is whether a catch(...) should catch a cancellation.  I can see
arguments both ways on that question.

If pthread_cancel is not going to run C++ destructors, matters are a
little simpler.  We would just need a way for glibc to create an
exception that C++ will ignore.

I would encourage you to file your two test cases as two separate bugs
in http://gcc.gnu.org/bugzilla so that these issues are not forgotten.

Ian



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux