From 372deb091ef44158d60bb4cc28f9110ab948ed2f Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Wed, 17 Dec 2014 10:30:06 +0000 Subject: [PATCH] [msan] Stop calling pthread_getspecific in signal handlers. pthread_getspecific is not async-signal-safe. MsanThread pointer is now stored in a TLS variable, and the TSD slot is used only for its destructor, and never from a signal handler. This should fix intermittent CHECK failures in MsanTSDSet. llvm-svn: 224423 --- compiler-rt/lib/msan/msan_linux.cc | 19 ++++++++++++++----- compiler-rt/lib/msan/msan_thread.cc | 11 ----------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/compiler-rt/lib/msan/msan_linux.cc b/compiler-rt/lib/msan/msan_linux.cc index 0b67b53..e172525 100644 --- a/compiler-rt/lib/msan/msan_linux.cc +++ b/compiler-rt/lib/msan/msan_linux.cc @@ -157,20 +157,26 @@ void InstallAtExitHandler() { static pthread_key_t tsd_key; static bool tsd_key_inited = false; + void MsanTSDInit(void (*destructor)(void *tsd)) { CHECK(!tsd_key_inited); tsd_key_inited = true; CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); } -void *MsanTSDGet() { - CHECK(tsd_key_inited); - return pthread_getspecific(tsd_key); +static THREADLOCAL MsanThread* msan_current_thread; + +MsanThread *GetCurrentThread() { + return msan_current_thread; } -void MsanTSDSet(void *tsd) { +void SetCurrentThread(MsanThread *t) { + // Make sure we do not reset the current MsanThread. + CHECK_EQ(0, msan_current_thread); + msan_current_thread = t; + // Make sure that MsanTSDDtor gets called at the end. CHECK(tsd_key_inited); - pthread_setspecific(tsd_key, tsd); + pthread_setspecific(tsd_key, (void *)t); } void MsanTSDDtor(void *tsd) { @@ -180,6 +186,9 @@ void MsanTSDDtor(void *tsd) { CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); return; } + msan_current_thread = nullptr; + // Make sure that signal handler can not see a stale current thread pointer. + atomic_signal_fence(memory_order_seq_cst); MsanThread::TSDDtor(tsd); } diff --git a/compiler-rt/lib/msan/msan_thread.cc b/compiler-rt/lib/msan/msan_thread.cc index f29a4b0..e15a247 100644 --- a/compiler-rt/lib/msan/msan_thread.cc +++ b/compiler-rt/lib/msan/msan_thread.cc @@ -79,15 +79,4 @@ thread_return_t MsanThread::ThreadStart() { return res; } -MsanThread *GetCurrentThread() { - return reinterpret_cast(MsanTSDGet()); -} - -void SetCurrentThread(MsanThread *t) { - // Make sure we do not reset the current MsanThread. - CHECK_EQ(0, MsanTSDGet()); - MsanTSDSet(t); - CHECK_EQ(t, MsanTSDGet()); -} - } // namespace __msan -- 2.7.4