[llvm] [Support] On Windows, fix rpmalloc TLS destructor when running inside a DLL (PR #171465)

via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 11 18:54:37 PST 2025


https://github.com/GkvJwa updated https://github.com/llvm/llvm-project/pull/171465

>From 6590a29489bf77fae913c8fb4bd46b69f55404bb Mon Sep 17 00:00:00 2001
From: GkvJwa <gkvjwa at gmail.com>
Date: Fri, 12 Dec 2025 10:52:03 +0800
Subject: [PATCH] [Support] On Windows, fix rpmalloc TLS destructor when
 running inside a DLL

---
 llvm/lib/Support/rpmalloc/rpmalloc.c | 44 ++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/llvm/lib/Support/rpmalloc/rpmalloc.c b/llvm/lib/Support/rpmalloc/rpmalloc.c
index b4282d9257e5f..a0f99f3e0184e 100644
--- a/llvm/lib/Support/rpmalloc/rpmalloc.c
+++ b/llvm/lib/Support/rpmalloc/rpmalloc.c
@@ -969,6 +969,50 @@ static void _rpmalloc_spin(void) {
 }
 
 #if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK)
+
+static void NTAPI RPMallocTlsOnThreadExit(PVOID module, DWORD reason,
+                                          PVOID reserved) {
+  switch (reason) {
+  case DLL_PROCESS_ATTACH:
+    break;
+  case DLL_PROCESS_DETACH:
+    rpmalloc_finalize();
+    break;
+  case DLL_THREAD_ATTACH:
+    break;
+  case DLL_THREAD_DETACH:
+    rpmalloc_thread_finalize(1);
+    break;
+  }
+}
+
+#ifdef _WIN64
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:rpmalloc_tls_thread_exit_callback")
+
+// .CRT$XL* is an array of PIMAGE_TLS_CALLBACK on Windows. It is executed
+// alphabetically (A-Z) during CRT calls. As an allocator, the allocator must be
+// deinitialized last. Therefore, Y(.CRT$XLY) is used here.
+#pragma const_seg(".CRT$XLY")
+
+extern const PIMAGE_TLS_CALLBACK rpmalloc_tls_thread_exit_callback;
+const PIMAGE_TLS_CALLBACK rpmalloc_tls_thread_exit_callback =
+    RPMallocTlsOnThreadExit;
+
+// Reset const section
+#pragma const_seg()
+#else // _WIN64
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_rpmalloc_tls_thread_exit_callback")
+
+#pragma data_seg(".CRT$XLY")
+
+PIMAGE_TLS_CALLBACK rpmalloc_tls_thread_exit_callback = RPMallocTlsOnThreadExit;
+
+// Reset data section
+#pragma data_seg()
+#endif // _WIN64
+
 static void NTAPI _rpmalloc_thread_destructor(void *value) {
 #if ENABLE_OVERRIDE
   // If this is called on main thread it means rpmalloc_finalize



More information about the llvm-commits mailing list