[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