[compiler-rt] 999313d - [sanitizer] Switch from lazy `ThreadDescriptorSize` (#108923)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 18 16:45:46 PDT 2024


Author: Vitaly Buka
Date: 2024-09-18T16:45:43-07:00
New Revision: 999313debe8a87760b128e4469f17ec0ce1a4a8f

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

LOG: [sanitizer] Switch from lazy `ThreadDescriptorSize` (#108923)

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

It's relatively easy to init size from the main init.

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
    compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp

Removed: 
    


################################################################################
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


        


More information about the llvm-commits mailing list