diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-12-17 10:30:06 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-12-17 10:30:06 +0000 |
| commit | 372deb091ef44158d60bb4cc28f9110ab948ed2f (patch) | |
| tree | 5485a8c26f2a4b92ee445e99837b409c925e3e46 | |
| parent | 508dd9b94c7c310a42982fae9b22fc21ebcdd482 (diff) | |
| download | bcm5719-llvm-372deb091ef44158d60bb4cc28f9110ab948ed2f.tar.gz bcm5719-llvm-372deb091ef44158d60bb4cc28f9110ab948ed2f.zip | |
[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
| -rw-r--r-- | compiler-rt/lib/msan/msan_linux.cc | 19 | ||||
| -rw-r--r-- | 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 0b67b531d51..e17252535ae 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 f29a4b053a3..e15a247c6bb 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<MsanThread *>(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 |

