[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