Ian, Thanks very much for taking the time to explain the situation, however dissapointing it might be :) 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. Regards, Mike ________________________________________ From: Ian Lance Taylor [iant@xxxxxxxxxx] Sent: Tuesday, May 15, 2012 1:14 AM To: Mike Dalpee Cc: gcc-help@xxxxxxxxxxx Subject: Re: GCC 4.6.2 C++ thread cancellation issue Mike Dalpee <mikedalpee@xxxxxxxxxxxx> writes: > 1) Cancelling a thread that is in a function that has an empty throw > clause (throw()). The runtime appears to treat abi::__forcedUnwind as > an unexpected exception and the following message appears on the > console: > > terminate called without an active exception > > If the throw clause names any exception (i.e, is not empty) or has not > throw clause at all, no abort occurs. Thanks for the test cases. I see this as well. As you know, pthread_cancel is implemented by raising an exception in the thread being cancelled. The behaviour matches a comment in libstdc++-v3/libsupc++/eh_personality.cc: // ??? How do foreign exceptions fit in? As far as I can // see we can't match because there's no __cxa_exception // object to stuff bits in for __cxa_call_unexpected to use. // Allow them iff the exception spec is non-empty. I.e. // a throw() specification results in __unexpected. A "foreign" exception is an exception that is not created by C++ code. I think this has to be described as a bug but I think it could be quite difficult to fix. Normally a function with an empty throw specification can not throw an exception, and it is possible that calling code is optimized under that assumption. > 1) Cancelling a thread that is already in an exception handler and > then attempting to rethrow abi:: __forcedUnwind. The runtime appears > to treat the rethrow as a "stacked foreign exception" (from comments > in the relevant libsup++ code.) I set up this circumstance by throwing > an int and then calling a function in the exception handler (for int) > that sits at a cancellation point. The following message appears on > the console: > > terminate called after throwing an instance of 'int' > > If the rethrow of abi:: __forcedUnwind is removed, no abort occurs. I see this failure as well. As you say, the relevant comment is in libstdc++-v3/libsupc++/eh_catch.cc: // Foreign exceptions can't be stacked here. If the exception stack is // empty, then fine. Otherwise we really have no choice but to terminate. // Note that this use of "header" is a lie. It's fine so long as we only // examine header->unwindHeader though. In this case there is an exception stacked--the 1 thrown by ThreadRun. This is another bug, and it looks like it might also be hard to fix. Sorry to not have any useful information here. Basically, I think you've found bugs, and I don't think they will be fixed anytime soon. Ian