https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66146
--- Comment #2 from Andrey V <andrey.vul at gmail dot com> --- Replacing throw/try/catch with longjmp/setjmp for non-returning function exit, like so: #include <stdio.h> #include <pthread.h> #include <setjmp.h> pthread_once_t flag_ = PTHREAD_ONCE_INIT; int call_count = 0; jmp_buf catch_; void func_() { printf("Inside func_ call_count %d\n", call_count); if (++call_count < 2) longjmp(catch_, 1); } int main() { int signo; printf("Before calling call_once flag_: %d\n", *(int*)&flag_); signo = setjmp(catch_); if (!signo) pthread_once(&flag_, func_); else printf("Inside catch all excepton flag_: %d\n", *(int*)&flag_); printf("before the 2nd call to call_once flag_: %d\n", *(int*)&flag_); pthread_once(&flag_, func_); } , the invalid behavior isn't triggered. It appears that pthread_once doesn't take kindly to exceptions in the once_func.