[cxx-abi-dev] How to detect a forced unwind in a catch block?

Thiago Macieira thiago at kde.org
Sat Sep 3 08:40:32 UTC 2016


Hello

Summary: abi::__foced_unwind is available when #include <cxxabi.h> from GCC 
(libsupc++), but is not documented in https://mentorembedded.github.io/cxx-abi/abi-eh.html nor is it available in other implementations. Should it be 
adde to the spec so we can detect forced unwinds? Or is there another way to 
detect the forced unwinding not caused by an exception?

Background:

30.3.1.2 [thread.thread.constr] p5 says

" If the invocation of INVOKE (DECAY_COPY ( std::forward<F>(f)), DECAY_COPY 
(std::forward<Args>(args))...) terminates with an uncaught exception, 
std::terminate shall be called."

When trying to implement this requirement for QThread, we've run into a snag: 
with glibc's pthread implementation on Linux, pthread_exit() as well as all 
POSIX asynchronous cancellations happen by way of a forced stack unwinding. 
This means the obvious solution to implement the requirement from the standard 
fails:

	try {
		thr->run();
	} catch (...) {
		std::terminate();
	}

That catch (...) block is run by the forced stack unwinding started with 
_Unwind_ForcedUnwind. Since it then calls std::terminate(), the whole 
application terminates instead of just the thread.

Now, the libstdc++ implementation[1][2] handles this gracefully, but does so 
by catching abi::__forced_unwind.

That brings me to my original question in the subject: how can code outside of 
the compiler's own implementations detect a forced stack unwinding not caused 
by a thrown exception in a portable fashion?

Option 1: make abi::__forced_unwind documented and have the other 
implementations (besides GCC) implement it too.

Option 2: add a getter to either the Base ABI for unwinding (_Unwind_*) or the 
C++ ABI to get a flag indicating whether the unwind is forced. In fact, this 
information is already available in the actions parameter to the personality 
routine: https://mentorembedded.github.io/cxx-abi/abi-eh.html#base-personality 
has:
    static const _Unwind_Action _UA_FORCE_UNWIND = 8;

Option 3: change the way that GCC and glibc force unwinding from non-C++ 
contexts.

[1] https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/src/c%2B
%2B11/thread.cc#L77
[2] I don't see any code in libc++ for handling exceptions at all.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



More information about the cxx-abi-dev mailing list