diff --git a/src/exit/exit.c b/src/exit/exit.c index a6869b37..ca11b9ad 100644 --- a/src/exit/exit.c +++ b/src/exit/exit.c @@ -1,6 +1,9 @@ #include #include #include "libc.h" +#include "pthread_impl.h" +#include "atomic.h" +#include "syscall.h" static void dummy() { @@ -26,6 +29,17 @@ weak_alias(libc_exit_fini, __libc_exit_fini); _Noreturn void exit(int code) { + /* Handle potentially concurrent or recursive calls to exit, + * whose behaviors have traditionally been undefined by the + * standards. Using a custom lock here avoids pulling in lock + * machinery and lets us trap recursive calls while supporting + * multiple threads contending to be the one to exit(). */ + static volatile int exit_lock[1]; + int tid = __pthread_self()->tid; + int prev = a_cas(exit_lock, 0, tid); + if (prev == tid) a_crash(); + else if (prev) for (;;) __syscall(SYS_pause); + __funcs_on_exit(); __libc_exit_fini(); __stdio_exit();