pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

compiler-rt-netbsd: Attempt to fix Thread Joined/Exited race



Module Name:	pkgsrc-wip
Committed By:	Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By:	kamil
Date:		Tue Nov 21 14:57:29 2017 +0100
Changeset:	1f91f058b7ca7125054f80ed99aec0565d8936e4

Modified Files:
	compiler-rt-netbsd/distinfo
Added Files:
	compiler-rt-netbsd/patches/patch-lib_lsan_lsan__interceptors.cc
	compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.cc
	compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.h
	compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.cc
	compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.h
	compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__interceptors.cc
	compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl.h
	compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl__thread.cc

Log Message:
compiler-rt-netbsd: Attempt to fix Thread Joined/Exited race

Backported from upstream patch:

Prevent Thread Exited/Joined events race
https://reviews.llvm.org/D40294

We shall get the following results for check-tsan.

Testing Time: 48.84s
********************
Failing Tests (13):
    ThreadSanitizer-x86_64 :: deadlock_detector_stress_test.cc
    ThreadSanitizer-x86_64 :: dtls.c
    ThreadSanitizer-x86_64 :: exceptions.cc
    ThreadSanitizer-x86_64 :: ignore_lib5.cc
    ThreadSanitizer-x86_64 :: ignored-interceptors-mmap.cc
    ThreadSanitizer-x86_64 :: longjmp3.cc
    ThreadSanitizer-x86_64 :: longjmp4.cc
    ThreadSanitizer-x86_64 :: mutex_lock_destroyed.cc
    ThreadSanitizer-x86_64 :: signal_errno.cc
    ThreadSanitizer-x86_64 :: signal_malloc.cc
    ThreadSanitizer-x86_64 :: signal_sync2.cc
    ThreadSanitizer-x86_64 :: signal_thread.cc
    ThreadSanitizer-x86_64 :: vfork.cc

  Expected Passes    : 245
  Expected Failures  : 1
  Unsupported Tests  : 83
  Unexpected Failures: 13

However something is still wrong and there are races.
Improper usage of atomic operations?

Sponsored by <The NetBSD Foundation>

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=1f91f058b7ca7125054f80ed99aec0565d8936e4

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 compiler-rt-netbsd/distinfo                        |  8 ++++
 .../patches/patch-lib_lsan_lsan__interceptors.cc   | 17 ++++++++
 .../patches/patch-lib_lsan_lsan__thread.cc         | 13 ++++++
 .../patches/patch-lib_lsan_lsan__thread.h          | 13 ++++++
 ...anitizer__common_sanitizer__thread__registry.cc | 46 ++++++++++++++++++++++
 ...sanitizer__common_sanitizer__thread__registry.h | 35 ++++++++++++++++
 .../patch-lib_tsan_rtl_tsan__interceptors.cc       | 42 ++++++++++++++++++++
 .../patches/patch-lib_tsan_rtl_tsan__rtl.h         | 13 ++++++
 .../patch-lib_tsan_rtl_tsan__rtl__thread.cc        | 18 +++++++++
 9 files changed, 205 insertions(+)

diffs:
diff --git a/compiler-rt-netbsd/distinfo b/compiler-rt-netbsd/distinfo
index e6091f5dca..231b469f34 100644
--- a/compiler-rt-netbsd/distinfo
+++ b/compiler-rt-netbsd/distinfo
@@ -2,6 +2,14 @@ $NetBSD: distinfo,v 1.35 2015/09/11 01:21:57 tnn Exp $
 
 SHA1 (patch-cmake_config-ix.cmake) = a1814db3e044ce3954655fea1e157a96bfa8df2f
 SHA1 (patch-lib_fuzzer_tests_CMakeLists.txt) = 38ca750154dfc9843a56748078235824b772a147
+SHA1 (patch-lib_lsan_lsan__interceptors.cc) = 996b0d8634bba7c3eca69c5eb175284e5f834e5c
+SHA1 (patch-lib_lsan_lsan__thread.cc) = 5cfc982f13ad8171fcd2859f2e37edef2f0e41b2
+SHA1 (patch-lib_lsan_lsan__thread.h) = 5fbcc7fe73e619d88912413d99af2f4878ffeae6
 SHA1 (patch-lib_msan_msan.h) = ce3f544490aebc1db73be9e3388f0a9d31d5b369
+SHA1 (patch-lib_sanitizer__common_sanitizer__thread__registry.cc) = 38be2aa0785c5a17e682f36717fae45cf8596fbe
+SHA1 (patch-lib_sanitizer__common_sanitizer__thread__registry.h) = 8b6ab550a34b4e8526a18e45ef6fc05af64e4c2a
+SHA1 (patch-lib_tsan_rtl_tsan__interceptors.cc) = 89c53c5ce07400a0854cf09e8cc42956826563df
 SHA1 (patch-lib_tsan_rtl_tsan__rtl.cc) = bc3d6aa81515ac4a4fc5b504e93b3ac8de355371
+SHA1 (patch-lib_tsan_rtl_tsan__rtl.h) = fbab7ceae96a0a2bf9ec7449dd29a8c0e1613943
 SHA1 (patch-lib_tsan_rtl_tsan__rtl__amd64.S) = 6df0f2af44ebfec76d3b237c984eff63ee93b30f
+SHA1 (patch-lib_tsan_rtl_tsan__rtl__thread.cc) = 80538a9300eb81a1eec353c51fa420d6dcf012b2
diff --git a/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__interceptors.cc b/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__interceptors.cc
new file mode 100644
index 0000000000..6d39f7db2b
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__interceptors.cc
@@ -0,0 +1,17 @@
+$NetBSD$
+
+--- lib/lsan/lsan_interceptors.cc.orig	2017-10-17 18:35:51.000000000 +0000
++++ lib/lsan/lsan_interceptors.cc
+@@ -389,10 +389,10 @@ INTERCEPTOR(int, pthread_create, void *t
+ 
+ INTERCEPTOR(int, pthread_join, void *th, void **ret) {
+   ENSURE_LSAN_INITED;
+-  int tid = ThreadTid((uptr)th);
++  ThreadContextBase *tctx = ThreadTctx((uptr)th);
+   int res = REAL(pthread_join)(th, ret);
+   if (res == 0)
+-    ThreadJoin(tid);
++    ThreadJoin(tctx->tid);
+   return res;
+ }
+ 
diff --git a/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.cc b/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.cc
new file mode 100644
index 0000000000..9bd2cb204d
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.cc
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- lib/lsan/lsan_thread.cc.orig	2017-10-17 18:35:51.000000000 +0000
++++ lib/lsan/lsan_thread.cc
+@@ -111,7 +111,7 @@ static bool FindThreadByUid(ThreadContex
+   return false;
+ }
+ 
+-u32 ThreadTid(uptr uid) {
++ThreadContextBase *ThreadTctx(uptr uid) {
+   return thread_registry->FindThread(FindThreadByUid, (void*)uid);
+ }
+ 
diff --git a/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.h b/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.h
new file mode 100644
index 0000000000..594e2aa677
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_lsan_lsan__thread.h
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- lib/lsan/lsan_thread.h.orig	2017-10-17 18:35:51.000000000 +0000
++++ lib/lsan/lsan_thread.h
+@@ -49,7 +49,7 @@ void ThreadStart(u32 tid, tid_t os_id, b
+ void ThreadFinish();
+ u32 ThreadCreate(u32 tid, uptr uid, bool detached);
+ void ThreadJoin(u32 tid);
+-u32 ThreadTid(uptr uid);
++ThreadContextBase *ThreadTctx(uptr uid);
+ 
+ u32 GetCurrentThread();
+ void SetCurrentThread(u32 tid);
diff --git a/compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.cc b/compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.cc
new file mode 100644
index 0000000000..71f64c615a
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.cc
@@ -0,0 +1,46 @@
+$NetBSD$
+
+--- lib/sanitizer_common/sanitizer_thread_registry.cc.orig	2017-10-17 18:35:46.000000000 +0000
++++ lib/sanitizer_common/sanitizer_thread_registry.cc
+@@ -21,6 +21,7 @@ ThreadContextBase::ThreadContextBase(u32
+       status(ThreadStatusInvalid),
+       detached(false), workerthread(false), parent_tid(0), next(0) {
+   name[0] = '\0';
++  atomic_store_relaxed(&thread_destroyed, 0);
+ }
+ 
+ ThreadContextBase::~ThreadContextBase() {
+@@ -88,6 +89,14 @@ void ThreadContextBase::Reset() {
+   OnReset();
+ }
+ 
++void ThreadContextBase::SetDestroyed() {
++  atomic_store(&thread_destroyed, 1, memory_order_release);
++}
++
++bool ThreadContextBase::GetDestroyed() {
++  return !!atomic_load(&thread_destroyed, memory_order_acquire);
++}
++
+ // ThreadRegistry implementation.
+ 
+ const u32 ThreadRegistry::kUnknownTid = ~0U;
+@@ -170,14 +179,15 @@ void ThreadRegistry::RunCallbackForEachT
+   }
+ }
+ 
+-u32 ThreadRegistry::FindThread(FindThreadCallback cb, void *arg) {
++ThreadContextBase *
++ThreadRegistry::FindThread(FindThreadCallback cb, void *arg) {
+   BlockingMutexLock l(&mtx_);
+   for (u32 tid = 0; tid < n_contexts_; tid++) {
+     ThreadContextBase *tctx = threads_[tid];
+     if (tctx != 0 && cb(tctx, arg))
+-      return tctx->tid;
++      return tctx;
+   }
+-  return kUnknownTid;
++  return 0;
+ }
+ 
+ ThreadContextBase *
diff --git a/compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.h b/compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.h
new file mode 100644
index 0000000000..944291dad1
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_sanitizer__common_sanitizer__thread__registry.h
@@ -0,0 +1,35 @@
+$NetBSD$
+
+--- lib/sanitizer_common/sanitizer_thread_registry.h.orig	2017-10-17 18:35:46.000000000 +0000
++++ lib/sanitizer_common/sanitizer_thread_registry.h
+@@ -50,6 +50,8 @@ class ThreadContextBase {
+   u32 parent_tid;
+   ThreadContextBase *next;  // For storing thread contexts in a list.
+ 
++  atomic_uint32_t thread_destroyed; // To address race of Joined vs Finished
++
+   void SetName(const char *new_name);
+ 
+   void SetDead();
+@@ -60,6 +62,9 @@ class ThreadContextBase {
+                   u32 _parent_tid, void *arg);
+   void Reset();
+ 
++  void SetDestroyed();
++  bool GetDestroyed();
++
+   // The following methods may be overriden by subclasses.
+   // Some of them take opaque arg that may be optionally be used
+   // by subclasses.
+@@ -102,9 +107,9 @@ class ThreadRegistry {
+   void RunCallbackForEachThreadLocked(ThreadCallback cb, void *arg);
+ 
+   typedef bool (*FindThreadCallback)(ThreadContextBase *tctx, void *arg);
+-  // Finds a thread using the provided callback. Returns kUnknownTid if no
++  // Finds a thread using the provided callback. Returns NULL if no
+   // thread is found.
+-  u32 FindThread(FindThreadCallback cb, void *arg);
++  ThreadContextBase *FindThread(FindThreadCallback cb, void *arg);
+   // Should be guarded by ThreadRegistryLock. Return 0 if no thread
+   // is found.
+   ThreadContextBase *FindThreadContextLocked(FindThreadCallback cb,
diff --git a/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__interceptors.cc b/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__interceptors.cc
new file mode 100644
index 0000000000..31ca496831
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__interceptors.cc
@@ -0,0 +1,42 @@
+$NetBSD$
+
+--- lib/tsan/rtl/tsan_interceptors.cc.orig	2017-11-21 09:38:56.000000000 +0000
++++ lib/tsan/rtl/tsan_interceptors.cc
+@@ -868,6 +868,7 @@ void DestroyThreadState() {
+   }
+   DTLS_Destroy();
+   cur_thread_finalize();
++  thr->tctx->SetDestroyed();
+ }
+ }  // namespace __tsan
+ 
+@@ -982,12 +983,14 @@ TSAN_INTERCEPTOR(int, pthread_create,
+ 
+ TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
+   SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret);
+-  int tid = ThreadTid(thr, pc, (uptr)th);
++  ThreadContextBase *tctx = ThreadTctx(thr, pc, (uptr)th);
+   ThreadIgnoreBegin(thr, pc);
+   int res = BLOCK_REAL(pthread_join)(th, ret);
+   ThreadIgnoreEnd(thr, pc);
+   if (res == 0) {
+-    ThreadJoin(thr, pc, tid);
++    while (!tctx->GetDestroyed())
++       internal_sched_yield();
++    ThreadJoin(thr, pc, tctx->tid);
+   }
+   return res;
+ }
+@@ -996,10 +999,10 @@ DEFINE_REAL_PTHREAD_FUNCTIONS
+ 
+ TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
+   SCOPED_TSAN_INTERCEPTOR(pthread_detach, th);
+-  int tid = ThreadTid(thr, pc, (uptr)th);
++  ThreadContextBase *tctx = ThreadTctx(thr, pc, (uptr)th);
+   int res = REAL(pthread_detach)(th);
+   if (res == 0) {
+-    ThreadDetach(thr, pc, tid);
++    ThreadDetach(thr, pc, tctx->tid);
+   }
+   return res;
+ }
diff --git a/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl.h b/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl.h
new file mode 100644
index 0000000000..9e8c44c61e
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl.h
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- lib/tsan/rtl/tsan_rtl.h.orig	2017-11-16 17:55:36.000000000 +0000
++++ lib/tsan/rtl/tsan_rtl.h
+@@ -757,7 +757,7 @@ void FuncExit(ThreadState *thr);
+ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
+ void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread);
+ void ThreadFinish(ThreadState *thr);
+-int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
++ThreadContextBase *ThreadTctx(ThreadState *thr, uptr pc, uptr uid);
+ void ThreadJoin(ThreadState *thr, uptr pc, int tid);
+ void ThreadDetach(ThreadState *thr, uptr pc, int tid);
+ void ThreadFinalize(ThreadState *thr);
diff --git a/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl__thread.cc b/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl__thread.cc
new file mode 100644
index 0000000000..2e326a1bb4
--- /dev/null
+++ b/compiler-rt-netbsd/patches/patch-lib_tsan_rtl_tsan__rtl__thread.cc
@@ -0,0 +1,18 @@
+$NetBSD$
+
+--- lib/tsan/rtl/tsan_rtl_thread.cc.orig	2017-10-17 18:35:43.000000000 +0000
++++ lib/tsan/rtl/tsan_rtl_thread.cc
+@@ -293,9 +293,10 @@ static bool FindThreadByUid(ThreadContex
+   return false;
+ }
+ 
+-int ThreadTid(ThreadState *thr, uptr pc, uptr uid) {
+-  int res = ctx->thread_registry->FindThread(FindThreadByUid, (void*)uid);
+-  DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, res);
++ThreadContextBase *ThreadTctx(ThreadState *thr, uptr pc, uptr uid) {
++  ThreadContextBase *res;
++  res = ctx->thread_registry->FindThread(FindThreadByUid, (void*)uid);
++  DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, res->tid);
+   return res;
+ }
+ 


Home | Main Index | Thread Index | Old Index