[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