https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78015
Bug ID: 78015 Summary: pthread_cancel while some exception is pending results in std::terminate () Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- #include <pthread.h> #include <unistd.h> namespace __cxxabiv1 { class __forced_unwind { virtual ~__forced_unwind() throw(); virtual void __pure_dummy() = 0; }; } int a; extern "C" void * fun (void *) { #ifdef WORKAROUND try { throw 1; } catch (int &) #endif { try { char buf[10]; for (;;) read (4, buf, 0); } catch (__cxxabiv1::__forced_unwind &) { a = 5; throw; } } return NULL; } int main () { pthread_t thread; pthread_create (&thread, NULL, fun, NULL); pthread_cancel (thread); pthread_join (thread, NULL); } fails with std::terminate (), while works with -DWORKAROUND. The problem is in __cxa_begin_catch: 51 // Note that this use of "header" is a lie. It's fine so long as we only 52 // examine header->unwindHeader though. 53 if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 54 { 55 if (prev != 0) 56 std::terminate (); With -DWORKAROUND, prev is NULL and thus we handle it fine as forced unwinding exception. But without that, prev is non-NULL here. I don't know what exactly should we do instead if prev is non-NULL, whether to somehow destruct the previous exception, or just continue normally and destruct it when the forced unwinding finishes, or when.