summaryrefslogtreecommitdiff
path: root/lib/msan/msan_linux.cc
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-12-17 10:30:06 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-12-17 10:30:06 +0000
commit1c1cd425b9fed0590bdaf3bae08672f04e01bfa5 (patch)
tree297afcb10ac10ebc4669636f3d1c92fb4ae778eb /lib/msan/msan_linux.cc
parent494372c77fdeb6bc4d16edc118fb6e9cc200474a (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.cc19
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);
}