[compiler-rt] r224423 - [msan] Stop calling pthread_getspecific in signal handlers.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Wed Dec 17 02:30:06 PST 2014


Author: eugenis
Date: Wed Dec 17 04:30:06 2014
New Revision: 224423

URL: http://llvm.org/viewvc/llvm-project?rev=224423&view=rev
Log:
[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.


Modified:
    compiler-rt/trunk/lib/msan/msan_linux.cc
    compiler-rt/trunk/lib/msan/msan_thread.cc

Modified: compiler-rt/trunk/lib/msan/msan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_linux.cc?rev=224423&r1=224422&r2=224423&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_linux.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_linux.cc Wed Dec 17 04:30:06 2014
@@ -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);
 }
 

Modified: compiler-rt/trunk/lib/msan/msan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_thread.cc?rev=224423&r1=224422&r2=224423&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_thread.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_thread.cc Wed Dec 17 04:30:06 2014
@@ -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





More information about the llvm-commits mailing list