[PATCH] D18409: [tsan] Fix fork() and fork-based tests for OS X

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 23 11:16:44 PDT 2016


kubabrecka created this revision.
kubabrecka added reviewers: dvyukov, kcc, glider, samsonov.
kubabrecka added subscribers: llvm-commits, zaks.anna, dcoughlin.

On OS X, fork() under TSan asserts (in debug builds only) because `REAL(fork)` calls some intercepted functions, which check that no internal locks are held via `CheckNoLocks()`.  But the wrapper of fork intentionally holds some locks.  The assert backtrace:

    FATAL: ThreadSanitizer CHECK failed: .../llvm/projects/compiler-rt/lib/tsan/rtl/tsan_mutex.cc:169 "((locked_[i])) == ((0))" (0x224, 0x0)
    frame #6: 0x00000001000b3df1 libclang_rt.tsan_osx_dynamic.dylib`__tsan::TsanCheckFailed(file=".../llvm/projects/compiler-rt/lib/tsan/rtl/tsan_mutex.cc", line=169, cond="((locked_[i])) == ((0))", v1=548, v2=0) + 97 at tsan_rtl_report.cc:45
    frame #7: 0x0000000100009289 libclang_rt.tsan_osx_dynamic.dylib`__sanitizer::CheckFailed(file=".../llvm/projects/compiler-rt/lib/tsan/rtl/tsan_mutex.cc", line=169, cond="((locked_[i])) == ((0))", v1=548, v2=0) + 73 at sanitizer_common.cc:159
    frame #8: 0x000000010008158c libclang_rt.tsan_osx_dynamic.dylib`__tsan::InternalDeadlockDetector::CheckNoLocks(this=0x00000001010465b8) + 140 at tsan_mutex.cc:169
    frame #9: 0x00000001000815c5 libclang_rt.tsan_osx_dynamic.dylib`__tsan::CheckNoLocks(thr=0x0000000100ffe000) + 21 at tsan_mutex.cc:176
    frame #10: 0x000000010003d55e libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor(this=0x00007fff5fbff838) + 174 at tsan_interceptors.cc:302
    frame #11: 0x000000010003d7fe libclang_rt.tsan_osx_dynamic.dylib`__tsan::ScopedInterceptor::~ScopedInterceptor(this=0x00007fff5fbff838) + 14 at tsan_interceptors.cc:291
    frame #12: 0x00000001000bfcaf libclang_rt.tsan_osx_dynamic.dylib`::wrap_OSSpinLockLock(lock=0x0000000100ffd5ac) + 335 at tsan_interceptors_mac.cc:33
    frame #13: 0x00007fff99dd6d7d libsystem_pthread.dylib`_pthread_fork_prepare + 43
    frame #14: 0x00007fff9a4c7a74 libSystem.B.dylib`libSystem_atfork_prepare + 24
    frame #15: 0x00007fff9f21af9c libsystem_c.dylib`fork + 12
    frame #16: 0x0000000100043e5d libclang_rt.tsan_osx_dynamic.dylib`::wrap_fork(fake=17065400) + 125 at tsan_interceptors.cc:2171
    frame #17: 0x0000000100000d98 fork_atexit.cc.tmp`main + 40 at fork_atexit.cc:20 [opt]
    frame #18: 0x00007fff9c4875ad libdyld.dylib`start + 1

This patch fixes that by using `ScopedIgnoreInterceptors` during the call to `REAL(fork)`.  After that, all the fork-based tests seem to pass on OS X, so let's just remove all the `UNSUPPORTED: darwin` annotations we have.


http://reviews.llvm.org/D18409

Files:
  lib/tsan/rtl/tsan_interceptors.cc
  test/tsan/fork_atexit.cc
  test/tsan/fork_deadlock.cc
  test/tsan/fork_multithreaded.cc
  test/tsan/fork_multithreaded3.cc
  test/tsan/vfork.cc

Index: test/tsan/vfork.cc
===================================================================
--- test/tsan/vfork.cc
+++ test/tsan/vfork.cc
@@ -1,5 +1,4 @@
 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// UNSUPPORTED: darwin
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: test/tsan/fork_multithreaded3.cc
===================================================================
--- test/tsan/fork_multithreaded3.cc
+++ test/tsan/fork_multithreaded3.cc
@@ -1,5 +1,4 @@
 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// UNSUPPORTED: darwin
 #include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
Index: test/tsan/fork_multithreaded.cc
===================================================================
--- test/tsan/fork_multithreaded.cc
+++ test/tsan/fork_multithreaded.cc
@@ -1,6 +1,5 @@
 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-DIE
 // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=die_after_fork=0 %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-NODIE
-// UNSUPPORTED: darwin
 #include "test.h"
 #include <errno.h>
 #include <sys/types.h>
Index: test/tsan/fork_deadlock.cc
===================================================================
--- test/tsan/fork_deadlock.cc
+++ test/tsan/fork_deadlock.cc
@@ -1,5 +1,4 @@
 // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=atexit_sleep_ms=50 %run %t 2>&1 | FileCheck %s
-// UNSUPPORTED: darwin
 #include "test.h"
 #include <errno.h>
 #include <sys/types.h>
Index: test/tsan/fork_atexit.cc
===================================================================
--- test/tsan/fork_atexit.cc
+++ test/tsan/fork_atexit.cc
@@ -1,5 +1,4 @@
 // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=atexit_sleep_ms=50 %run %t 2>&1 | FileCheck %s
-// UNSUPPORTED: darwin
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: lib/tsan/rtl/tsan_interceptors.cc
===================================================================
--- lib/tsan/rtl/tsan_interceptors.cc
+++ lib/tsan/rtl/tsan_interceptors.cc
@@ -2168,7 +2168,11 @@
     return REAL(fork)(fake);
   SCOPED_INTERCEPTOR_RAW(fork, fake);
   ForkBefore(thr, pc);
-  int pid = REAL(fork)(fake);
+  int pid;
+  {
+    ScopedIgnoreInterceptors ignore;
+    pid = REAL(fork)(fake);
+  }
   if (pid == 0) {
     // child
     ForkChildAfter(thr, pc);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18409.51450.patch
Type: text/x-patch
Size: 2372 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160323/d5ce072c/attachment.bin>


More information about the llvm-commits mailing list