[libc-commits] [libc] [libc] Delete teardown_main_tls and all its uses (PR #174374)
Petr Hosek via libc-commits
libc-commits at lists.llvm.org
Mon Jan 5 01:34:21 PST 2026
https://github.com/petrhosek created https://github.com/llvm/llvm-project/pull/174374
teardown_main_tls is called right before the main process exit to unmap the TLS but that's unnecesary since the process is terminating anyway, this just introduces extra system call. This can be potentially harmful in case one of the other threads tries the access the memory that has been unmapped. Other C library implementations don't unmap TLS either so this makes LLVM libc's behavior more consistent.
Fixes #173409
>From e1be921c0573ea17a74be79d95eee36bec5d1261 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 5 Jan 2026 01:25:37 -0800
Subject: [PATCH] [libc] Delete teardown_main_tls and all its uses
teardown_main_tls is called right before the main process exit to unmap
the TLS but that's unnecesary since the process is terminating anyway,
this just introduces extra system call. This can be potentially harmful
in case one of the other threads tries the access the memory that has
been unmapped. Other C library implementations don't unmap TLS either so
this makes LLVM libc's behavior more consistent.
Fixes #173409
---
libc/src/stdlib/atexit.cpp | 6 +-----
libc/src/stdlib/quick_exit.cpp | 3 ---
libc/startup/gpu/amdgpu/start.cpp | 3 ---
libc/startup/gpu/nvptx/start.cpp | 3 ---
libc/startup/linux/do_start.cpp | 3 ---
5 files changed, 1 insertion(+), 17 deletions(-)
diff --git a/libc/src/stdlib/atexit.cpp b/libc/src/stdlib/atexit.cpp
index 799aad136bda5..c8a15dd3cfef2 100644
--- a/libc/src/stdlib/atexit.cpp
+++ b/libc/src/stdlib/atexit.cpp
@@ -16,7 +16,6 @@ namespace LIBC_NAMESPACE_DECL {
constinit ExitCallbackList atexit_callbacks;
Mutex handler_list_mtx(false, false, false, false);
-[[gnu::weak]] extern void teardown_main_tls();
extern "C" {
@@ -25,11 +24,8 @@ int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {
}
void __cxa_finalize(void *dso) {
- if (!dso) {
+ if (!dso)
call_exit_callbacks(atexit_callbacks);
- if (teardown_main_tls)
- teardown_main_tls();
- }
}
} // extern "C"
diff --git a/libc/src/stdlib/quick_exit.cpp b/libc/src/stdlib/quick_exit.cpp
index 29110b33afcf5..a5abf3e05d1a1 100644
--- a/libc/src/stdlib/quick_exit.cpp
+++ b/libc/src/stdlib/quick_exit.cpp
@@ -16,12 +16,9 @@
namespace LIBC_NAMESPACE_DECL {
extern ExitCallbackList at_quick_exit_callbacks;
-[[gnu::weak]] extern void teardown_main_tls();
[[noreturn]] LLVM_LIBC_FUNCTION(void, quick_exit, (int status)) {
call_exit_callbacks(at_quick_exit_callbacks);
- if (teardown_main_tls)
- teardown_main_tls();
internal::exit(status);
}
diff --git a/libc/startup/gpu/amdgpu/start.cpp b/libc/startup/gpu/amdgpu/start.cpp
index 48f095d924931..446eead4e3935 100644
--- a/libc/startup/gpu/amdgpu/start.cpp
+++ b/libc/startup/gpu/amdgpu/start.cpp
@@ -18,9 +18,6 @@ extern "C" void __cxa_finalize(void *dso);
namespace LIBC_NAMESPACE_DECL {
-// FIXME: Factor this out into common logic so we don't need to stub it here.
-void teardown_main_tls() {}
-
// FIXME: Touch this symbol to force this to be linked in statically.
volatile void *dummy = &LIBC_NAMESPACE::rpc::client;
diff --git a/libc/startup/gpu/nvptx/start.cpp b/libc/startup/gpu/nvptx/start.cpp
index ce8f5bbb6d4eb..be71bafa7c458 100644
--- a/libc/startup/gpu/nvptx/start.cpp
+++ b/libc/startup/gpu/nvptx/start.cpp
@@ -20,9 +20,6 @@ namespace LIBC_NAMESPACE_DECL {
DataEnvironment app;
-// FIXME: Factor this out into common logic so we don't need to stub it here.
-void teardown_main_tls() {}
-
// FIXME: Touch this symbol to force this to be linked in statically.
volatile void *dummy = &LIBC_NAMESPACE::rpc::client;
diff --git a/libc/startup/linux/do_start.cpp b/libc/startup/linux/do_start.cpp
index a67bf188b1ae3..12493d8e66ef0 100644
--- a/libc/startup/linux/do_start.cpp
+++ b/libc/startup/linux/do_start.cpp
@@ -63,9 +63,6 @@ static void call_fini_array_callbacks() {
static ThreadAttributes main_thread_attrib;
static TLSDescriptor tls;
-// We separate teardown_main_tls from callbacks as callback function themselves
-// may require TLS.
-void teardown_main_tls() { cleanup_tls(tls.addr, tls.size); }
[[noreturn]] void do_start() {
auto tid = syscall_impl<long>(SYS_gettid);
More information about the libc-commits
mailing list