[llvm-branch-commits] [sanitizer] Switch from lazy `ThreadDescriptorSize` (PR #108923)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Sep 16 20:53:02 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Vitaly Buka (vitalybuka)

<details>
<summary>Changes</summary>

`ThreadDescriptorSize` uses `dlsym` which may use
malloc in unexpected time.

It's relatively easy to init size with regular
init.

This reverts commit 9f40cadf1bfd2cc5baf3058b13a554c7535f9acf.


---
Full diff: https://github.com/llvm/llvm-project/pull/108923.diff


2 Files Affected:

- (modified) compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp (+15-15) 
- (modified) compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp (+2) 


``````````diff
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index 6b43fea507a401..aa156acd7b657a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -224,7 +224,7 @@ static void GetGLibcVersion(int *major, int *minor, int *patch) {
 // to get the pointer to thread-specific data keys in the thread control block.
 #  if (SANITIZER_FREEBSD || SANITIZER_GLIBC) && !SANITIZER_GO
 // sizeof(struct pthread) from glibc.
-static atomic_uintptr_t thread_descriptor_size;
+static uptr thread_descriptor_size;
 
 // FIXME: Implementation is very GLIBC specific, but it's used by FREEBSD.
 static uptr ThreadDescriptorSizeFallback() {
@@ -305,20 +305,7 @@ static uptr ThreadDescriptorSizeFallback() {
 #    endif
 }
 
-uptr ThreadDescriptorSize() {
-  uptr val = atomic_load_relaxed(&thread_descriptor_size);
-  if (val)
-    return val;
-  // _thread_db_sizeof_pthread is a GLIBC_PRIVATE symbol that is exported in
-  // glibc 2.34 and later.
-  if (unsigned *psizeof = static_cast<unsigned *>(
-          dlsym(RTLD_DEFAULT, "_thread_db_sizeof_pthread")))
-    val = *psizeof;
-  if (!val)
-    val = ThreadDescriptorSizeFallback();
-  atomic_store_relaxed(&thread_descriptor_size, val);
-  return val;
-}
+uptr ThreadDescriptorSize() { return thread_descriptor_size; }
 
 #    if SANITIZER_GLIBC
 __attribute__((unused)) static size_t g_tls_size;
@@ -330,6 +317,15 @@ void InitTlsSize() {
   GetGLibcVersion(&major, &minor, &patch);
   g_use_dlpi_tls_data = major == 2 && minor >= 25;
 
+  if (major == 2 && minor >= 34) {
+    // _thread_db_sizeof_pthread is a GLIBC_PRIVATE symbol that is exported in
+    // glibc 2.34 and later.
+    if (unsigned *psizeof = static_cast<unsigned *>(
+            dlsym(RTLD_DEFAULT, "_thread_db_sizeof_pthread"))) {
+      thread_descriptor_size = *psizeof;
+    }
+  }
+
 #      if defined(__aarch64__) || defined(__x86_64__) || \
           defined(__powerpc64__) || defined(__loongarch__)
   auto *get_tls_static_info = (void (*)(size_t *, size_t *))dlsym(
@@ -339,7 +335,11 @@ void InitTlsSize() {
   if (get_tls_static_info)
     get_tls_static_info(&g_tls_size, &tls_align);
 #      endif
+
 #    endif  // SANITIZER_GLIBC
+
+  if (!thread_descriptor_size)
+    thread_descriptor_size = ThreadDescriptorSizeFallback();
 }
 
 #    if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 || \
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp
index 338c4d3bab2b04..b286ab72a5c795 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp
@@ -202,6 +202,8 @@ TEST(SanitizerLinux, ThreadDescriptorSize) {
   void *result;
   ASSERT_EQ(0, pthread_create(&tid, 0, thread_descriptor_size_test_func, 0));
   ASSERT_EQ(0, pthread_join(tid, &result));
+  EXPECT_EQ(0u, ThreadDescriptorSize());
+  InitTlsSize();
   EXPECT_EQ((uptr)result, ThreadDescriptorSize());
 }
 #  endif

``````````

</details>


https://github.com/llvm/llvm-project/pull/108923


More information about the llvm-branch-commits mailing list