[libc-commits] [libc] ae4b59f - [libc] Fix exit not calling new handlers registered from a call to atexit in atexit handler

Alex Brachet via libc-commits libc-commits at lists.llvm.org
Tue Mar 15 08:18:55 PDT 2022


Author: Alex Brachet
Date: 2022-03-15T15:18:41Z
New Revision: ae4b59f1798b479a71ab2a80bfe7e36812c87816

URL: https://github.com/llvm/llvm-project/commit/ae4b59f1798b479a71ab2a80bfe7e36812c87816
DIFF: https://github.com/llvm/llvm-project/commit/ae4b59f1798b479a71ab2a80bfe7e36812c87816.diff

LOG: [libc] Fix exit not calling new handlers registered from a call to atexit in atexit handler

Added: 
    

Modified: 
    libc/src/stdlib/atexit.cpp
    libc/test/src/stdlib/atexit_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/stdlib/atexit.cpp b/libc/src/stdlib/atexit.cpp
index 1548ea15c35b7..e1746aa4d96bf 100644
--- a/libc/src/stdlib/atexit.cpp
+++ b/libc/src/stdlib/atexit.cpp
@@ -27,8 +27,10 @@ namespace internal {
 
 void call_exit_callbacks() {
   handler_list_mtx.lock();
-  for (auto callback : exit_callbacks) {
+  while (!exit_callbacks.empty()) {
     handler_list_mtx.unlock();
+    auto *callback = exit_callbacks.back();
+    exit_callbacks.pop_back();
     callback();
     handler_list_mtx.lock();
   }

diff  --git a/libc/test/src/stdlib/atexit_test.cpp b/libc/test/src/stdlib/atexit_test.cpp
index bce69d88dc26e..877222fa59b71 100644
--- a/libc/test/src/stdlib/atexit_test.cpp
+++ b/libc/test/src/stdlib/atexit_test.cpp
@@ -78,17 +78,12 @@ TEST(LlvmLibcAtExit, Many) {
   EXPECT_EXITS(test, 0);
 }
 
-// POSIX doesn't specify if an atexit handler can call atexit, it only says it
-// is undefined for a handler to call exit(3). The current implementation will
-// end up invoking the newly registered function, although glibc does, other
-// libc's do not. This just tests that we don't deadlock when an exit handler
-// calls atexit.
 TEST(LlvmLibcAtExit, HandlerCallsAtExit) {
   auto test = [] {
     __llvm_libc::atexit(+[] {
-      __llvm_libc::atexit(+[] { __builtin_trap(); });
-      __llvm_libc::exit(0);
+      __llvm_libc::atexit(+[] { __llvm_libc::exit(1); });
     });
+    __llvm_libc::exit(0);
   };
-  EXPECT_EXITS(test, 0);
+  EXPECT_EXITS(test, 1);
 }


        


More information about the libc-commits mailing list