https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128197
LIU Hao <lh_mouse at 126 dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lh_mouse at 126 dot com
--- Comment #4 from LIU Hao <lh_mouse at 126 dot com> ---
It's a known limitation of Microsoft UCRT: When a thread calls `exit()` or
returns from main, it acquires the exit lock to execute callbacks that have
been registered by `atexit()`, so if another thread tries to register one it'll
have to wait forever -- until the process exits. In your program,
`std::jthread::join()` in the global dtor effects a circular wait on that.
You may read UCRT source code to confirm that. I won't copy it here since it's
illegal; but UCRT source code can be installed with Visual Studio for free.
This can be solved with my GCC builds: https://gcc-mcf.lhmouse.com/
The thread which runs atexit callbacks does not hold a global lock, so the
deadlock is averted.