[PATCH] D14288: [tsan] Alternative ThreadState storage for OS X

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 4 08:50:45 PST 2015


kubabrecka updated this revision to Diff 39211.
kubabrecka added a comment.

Updating the patch to also deal with ThreadState cleanup.

Thanks for the explanation of async-signal-safety, I'll take a look at it in another update of this patch.


http://reviews.llvm.org/D14288

Files:
  lib/tsan/rtl/tsan_interceptors.cc
  lib/tsan/rtl/tsan_platform_mac.cc
  lib/tsan/rtl/tsan_rtl.cc
  lib/tsan/rtl/tsan_rtl.h

Index: lib/tsan/rtl/tsan_rtl.h
===================================================================
--- lib/tsan/rtl/tsan_rtl.h
+++ lib/tsan/rtl/tsan_rtl.h
@@ -409,13 +409,20 @@
                        uptr tls_addr, uptr tls_size);
 };
 
-#ifndef SANITIZER_GO
+#if !defined(SANITIZER_GO) && !SANITIZER_MAC
 __attribute__((tls_model("initial-exec")))
 extern THREADLOCAL char cur_thread_placeholder[];
 INLINE ThreadState *cur_thread() {
   return reinterpret_cast<ThreadState *>(&cur_thread_placeholder);
 }
 #endif
+#if !defined(SANITIZER_GO) && SANITIZER_MAC
+ThreadState *cur_thread();
+void cur_thread_finalize();
+#endif
+#if !SANITIZER_MAC
+INLINE void cur_thread_finalize() { }
+#endif
 
 class ThreadContext : public ThreadContextBase {
  public:
Index: lib/tsan/rtl/tsan_rtl.cc
===================================================================
--- lib/tsan/rtl/tsan_rtl.cc
+++ lib/tsan/rtl/tsan_rtl.cc
@@ -44,7 +44,7 @@
 
 namespace __tsan {
 
-#ifndef SANITIZER_GO
+#if !defined(SANITIZER_GO) && !SANITIZER_MAC
 THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(64);
 #endif
 static char ctx_placeholder[sizeof(Context)] ALIGNED(64);
Index: lib/tsan/rtl/tsan_platform_mac.cc
===================================================================
--- lib/tsan/rtl/tsan_platform_mac.cc
+++ lib/tsan/rtl/tsan_platform_mac.cc
@@ -40,6 +40,44 @@
 
 namespace __tsan {
 
+#ifndef SANITIZER_GO
+// On OS X, accessing TLVs via __thread or manually by using pthread_key_* is
+// problematic, because there are several places where interceptors are called
+// when TLVs are not accessible (early process startup, thread cleanup, ...).
+// The following provides a "poor man's TLV" implementation, where we use the
+// shadow memory of the pointer returned by pthread_self() to store a pointer to
+// the ThreadState object. The main thread's ThreadState pointer is stored
+// separately in a static variable, because we need to access it even before the
+// shadow memory is set up.
+static uptr main_thread_identity = 0;
+static ThreadState *main_thread_state = nullptr;
+
+ThreadState *cur_thread() {
+  ThreadState **fake_tls;
+  uptr thread_identity = (uptr)pthread_self();
+  if (thread_identity == main_thread_identity || main_thread_identity == 0) {
+    if (main_thread_identity == 0) main_thread_identity = thread_identity;
+    fake_tls = &main_thread_state;
+  } else {
+    fake_tls = (ThreadState **)MemToShadow(thread_identity);
+  }
+  if (*fake_tls == nullptr) {
+    *fake_tls = (ThreadState *)InternalAlloc(sizeof(ThreadState), nullptr);
+    internal_memset(*fake_tls, 0, sizeof(ThreadState));
+  }
+  return *fake_tls;
+}
+
+void cur_thread_finalize() {
+  ThreadState **fake_tls;
+  uptr thread_identity = (uptr)pthread_self();
+  CHECK_NE(thread_identity, main_thread_identity);
+  fake_tls = (ThreadState **)MemToShadow(thread_identity);
+  InternalFree(*fake_tls, nullptr);
+  *fake_tls = nullptr;
+}
+#endif
+
 uptr GetShadowMemoryConsumption() {
   return 0;
 }
Index: lib/tsan/rtl/tsan_interceptors.cc
===================================================================
--- lib/tsan/rtl/tsan_interceptors.cc
+++ lib/tsan/rtl/tsan_interceptors.cc
@@ -821,6 +821,7 @@
     thr->signal_ctx = 0;
     UnmapOrDie(sctx, sizeof(*sctx));
   }
+  cur_thread_finalize();
 }
 }  // namespace __tsan
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14288.39211.patch
Type: text/x-patch
Size: 3335 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151104/3f4b3eba/attachment.bin>


More information about the llvm-commits mailing list