summaryrefslogtreecommitdiffstats
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
commit372deb091ef44158d60bb4cc28f9110ab948ed2f (patch)
tree5485a8c26f2a4b92ee445e99837b409c925e3e46
parent508dd9b94c7c310a42982fae9b22fc21ebcdd482 (diff)
downloadbcm5719-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.cc19
-rw-r--r--compiler-rt/lib/msan/msan_thread.cc11
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
OpenPOWER on IntegriCloud