[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