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 | 1c1cd425b9fed0590bdaf3bae08672f04e01bfa5 (patch) | |
tree | 297afcb10ac10ebc4669636f3d1c92fb4ae778eb /lib/msan/msan_linux.cc | |
parent | 494372c77fdeb6bc4d16edc118fb6e9cc200474a (diff) |
[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.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@224423 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/msan/msan_linux.cc')
-rw-r--r-- | lib/msan/msan_linux.cc | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc index 0b67b531d..e17252535 100644 --- a/lib/msan/msan_linux.cc +++ b/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); } |