diff options
4 files changed, 40 insertions, 4 deletions
diff --git a/compiler-rt/lib/lsan/lsan_interceptors.cc b/compiler-rt/lib/lsan/lsan_interceptors.cc index 454b5561c8a..e169191c7d2 100644 --- a/compiler-rt/lib/lsan/lsan_interceptors.cc +++ b/compiler-rt/lib/lsan/lsan_interceptors.cc @@ -192,9 +192,6 @@ struct ThreadParam { atomic_uintptr_t tid; }; -// PTHREAD_DESTRUCTOR_ITERATIONS from glibc. -const uptr kPthreadDestructorIterations = 4; - extern "C" void *__lsan_thread_start_func(void *arg) { ThreadParam *p = (ThreadParam*)arg; void* (*callback)(void *arg) = p->callback; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 4c0450e8626..af7f2f5441c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -77,6 +77,8 @@ void CacheBinaryName(); // Call cb for each region mapped by map. void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)); +// PTHREAD_DESTRUCTOR_ITERATIONS from glibc. +const uptr kPthreadDestructorIterations = 4; } // namespace __sanitizer #endif // SANITIZER_LINUX diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc index 592d9c3eeaf..95ce09b9fd6 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc @@ -255,6 +255,42 @@ TEST(SanitizerCommon, LibraryNameIs) { } } +pthread_key_t key; +bool destructor_executed; + +extern "C" +void destructor(void *arg) { + uptr iter = reinterpret_cast<uptr>(arg); + if (iter > 1) { + ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void *>(iter - 1))); + return; + } + destructor_executed = true; +} + +extern "C" +void *thread_func(void *arg) { + return reinterpret_cast<void*>(pthread_setspecific(key, arg)); +} + +void SpawnThread(uptr iteration) { + destructor_executed = false; + pthread_t tid; + ASSERT_EQ(0, pthread_create(&tid, 0, &thread_func, + reinterpret_cast<void *>(iteration))); + void *retval; + ASSERT_EQ(0, pthread_join(tid, &retval)); + ASSERT_EQ(0, retval); +} + +TEST(SanitizerCommon, PthreadDestructorIterations) { + ASSERT_EQ(0, pthread_key_create(&key, &destructor)); + SpawnThread(kPthreadDestructorIterations); + EXPECT_TRUE(destructor_executed); + SpawnThread(kPthreadDestructorIterations + 1); + EXPECT_FALSE(destructor_executed); +} + } // namespace __sanitizer #endif // SANITIZER_LINUX diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index 7058f43d2fd..68b23b5afcf 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -853,7 +853,8 @@ extern "C" void *__tsan_thread_start_func(void *arg) { { ThreadState *thr = cur_thread(); ScopedInRtl in_rtl; - if (pthread_setspecific(g_thread_finalize_key, (void*)4)) { + if (pthread_setspecific(g_thread_finalize_key, + (void *)kPthreadDestructorIterations)) { Printf("ThreadSanitizer: failed to set thread key\n"); Die(); } |