[compiler-rt] r257760 - [tsan] Introduce a "ignore_interceptors_accesses" option

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 14 04:24:38 PST 2016


Author: kuba.brecka
Date: Thu Jan 14 06:24:37 2016
New Revision: 257760

URL: http://llvm.org/viewvc/llvm-project?rev=257760&view=rev
Log:
[tsan] Introduce a "ignore_interceptors_accesses" option

On OS X, TSan already passes all unit and lit tests, but for real-world applications (even very simple ones), we currently produce a lot of false positive reports about data races. This makes TSan useless at this point, because the noise dominates real bugs. This introduces a runtime flag, "ignore_interceptors_accesses", off by default, which makes TSan ignore all memory accesses that happen from interceptors. This will significantly lower the coverage and miss a lot of bugs, but it eliminates most of the current false positives on OS X.

Differential Revision: http://reviews.llvm.org/D15189


Added:
    compiler-rt/trunk/test/tsan/Darwin/ignored-interceptors.mm
Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=257760&r1=257759&r2=257760&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Jan 14 06:24:37 2016
@@ -143,6 +143,14 @@
 #define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
 #endif
 
+#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
+#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
+#endif
+
+#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
+#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
+#endif
+
 struct FileMetadata {
   // For open_memstream().
   char **addr;
@@ -3304,7 +3312,9 @@ INTERCEPTOR(char **, backtrace_symbols,
 INTERCEPTOR(void, _exit, int status) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
+  COMMON_INTERCEPTOR_USER_CALLBACK_START();
   int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
+  COMMON_INTERCEPTOR_USER_CALLBACK_END();
   if (status == 0) status = status1;
   REAL(_exit)(status);
 }

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc?rev=257760&r1=257759&r2=257760&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc Thu Jan 14 06:24:37 2016
@@ -76,3 +76,5 @@ TSAN_FLAG(int, io_sync, 1,
 TSAN_FLAG(bool, die_after_fork, true,
           "Die after multi-threaded fork if the child creates new threads.")
 TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
+TSAN_FLAG(bool, ignore_interceptors_accesses, false,
+          "Ignore reads and writes from all interceptors.")

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=257760&r1=257759&r2=257760&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Thu Jan 14 06:24:37 2016
@@ -286,9 +286,11 @@ ScopedInterceptor::ScopedInterceptor(Thr
     thr_->in_ignored_lib = true;
     ThreadIgnoreBegin(thr_, pc_);
   }
+  if (flags()->ignore_interceptors_accesses) ThreadIgnoreBegin(thr_, pc_);
 }
 
 ScopedInterceptor::~ScopedInterceptor() {
+  if (flags()->ignore_interceptors_accesses) ThreadIgnoreEnd(thr_, pc_);
   if (in_ignored_lib_) {
     thr_->in_ignored_lib = false;
     ThreadIgnoreEnd(thr_, pc_);
@@ -301,6 +303,7 @@ ScopedInterceptor::~ScopedInterceptor()
 }
 
 void ScopedInterceptor::UserCallbackStart() {
+  if (flags()->ignore_interceptors_accesses) ThreadIgnoreEnd(thr_, pc_);
   if (in_ignored_lib_) {
     thr_->in_ignored_lib = false;
     ThreadIgnoreEnd(thr_, pc_);
@@ -312,6 +315,7 @@ void ScopedInterceptor::UserCallbackEnd(
     thr_->in_ignored_lib = true;
     ThreadIgnoreBegin(thr_, pc_);
   }
+  if (flags()->ignore_interceptors_accesses) ThreadIgnoreBegin(thr_, pc_);
 }
 
 #define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
@@ -2413,6 +2417,12 @@ static void HandleRecvmsg(ThreadState *t
     *begin = *end = 0;                                                         \
   }
 
+#define COMMON_INTERCEPTOR_USER_CALLBACK_START() \
+  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START()
+
+#define COMMON_INTERCEPTOR_USER_CALLBACK_END() \
+  SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END()
+
 #include "sanitizer_common/sanitizer_common_interceptors.inc"
 
 #define TSAN_SYSCALL() \

Added: compiler-rt/trunk/test/tsan/Darwin/ignored-interceptors.mm
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/Darwin/ignored-interceptors.mm?rev=257760&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/Darwin/ignored-interceptors.mm (added)
+++ compiler-rt/trunk/test/tsan/Darwin/ignored-interceptors.mm Thu Jan 14 06:24:37 2016
@@ -0,0 +1,56 @@
+// Check that ignore_interceptors_accesses=1 supresses reporting races from
+// system libraries on OS X. There are currently false positives coming from
+// libxpc, libdispatch, CoreFoundation and others, because these libraries use
+// TSan-invisible atomics as synchronization.
+
+// RUN: %clang_tsan %s -o %t -framework Foundation
+
+// Check that without the flag, there are false positives.
+// RUN: %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RACE
+
+// With ignore_interceptors_accesses=1, no races are reported.
+// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
+
+// With ignore_interceptors_accesses=1, races in user's code are still reported.
+// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t race 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RACE
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+void *Thread1(void *x) {
+  barrier_wait(&barrier);
+  global = 42;
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  global = 43;
+  barrier_wait(&barrier);
+  return NULL;
+}
+
+int main(int argc, char *argv[]) {
+  NSLog(@"Hello world.");
+  
+  // NSUserDefaults uses XPC which triggers the false positive.
+  NSDictionary *d = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
+  NSLog(@"d = %@", d);
+
+  if (argc > 1 && strcmp(argv[1], "race") == 0) {
+    barrier_init(&barrier, 2);
+    pthread_t t[2];
+    pthread_create(&t[0], NULL, Thread1, NULL);
+    pthread_create(&t[1], NULL, Thread2, NULL);
+    pthread_join(t[0], NULL);
+    pthread_join(t[1], NULL);
+  }
+
+  NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK-RACE: SUMMARY: ThreadSanitizer: data race
+// CHECK: Done.




More information about the llvm-commits mailing list