https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97211
Bug ID: 97211 Summary: __cxa_guard_acquire fails to detect recursive init in multithreaded code Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- In a single-threaded program this detects recursive init: #include <stddef.h> int a() { static int xx = a(); return 1; } extern "C" void* b(void*) { a(); return NULL; } int main() { b(NULL); } terminate called after throwing an instance of '__gnu_cxx::recursive_init_error' what(): std::exception Aborted (core dumped) When we know there are no threads in the program we can assume that attempting to acquire the guard variable when it's already in progress means recursive init. Because no other thread exists, so it must have been the current thread that started it, and we've re-entered the initialization. But if there are multiple threads we just go to sleep waiting forever for initialization to finish: #include <pthread.h> int a() { static int xx = a(); return 1; } extern "C" void* b(void*) { a(); return NULL; } int main() { pthread_t thrd; pthread_create(&thrd, NULL, b, NULL); pthread_join(thrd, NULL); } Clang makes this work by storing the result of SYS_gettid in the last four bytes of the guard variable, so it can detect when the same thread re-enters the guard.