diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2019-01-18 19:46:00 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2019-01-18 19:46:00 +0000 |
commit | 05342ccc9cff16425c0a831fddd510879544a0bf (patch) | |
tree | d86b2dfee6aa9d3a54d6d21aabb6bd7462b6669b /test/tsan | |
parent | 6fc0ad0a5de45f80140620e2dd606f65d547362a (diff) | |
parent | b15181368831966c0ec1824617a4c95853fd1b92 (diff) | |
download | compiler-rt-05342ccc9cff16425c0a831fddd510879544a0bf.tar.gz |
Creating branches/google/stable and tags/google/stable/2019-01-18 from r351319
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/branches/google/stable@351578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/tsan')
-rw-r--r-- | test/tsan/Darwin/ignore-noninstrumented.mm | 5 | ||||
-rw-r--r-- | test/tsan/Darwin/ignored-interceptors.mm | 55 | ||||
-rw-r--r-- | test/tsan/Darwin/objc-synchronize-cycle-tagged.mm | 42 | ||||
-rw-r--r-- | test/tsan/Darwin/objc-synchronize-cycle.mm | 31 | ||||
-rw-r--r-- | test/tsan/Darwin/objc-synchronize-nested-recursive.mm | 35 | ||||
-rw-r--r-- | test/tsan/deadlock_detector_stress_test.cc | 10 | ||||
-rw-r--r-- | test/tsan/ignored-interceptors-mmap.cc | 61 | ||||
-rw-r--r-- | test/tsan/mutex_cycle2.c | 2 | ||||
-rw-r--r-- | test/tsan/sunrpc.cc | 2 |
9 files changed, 150 insertions, 93 deletions
diff --git a/test/tsan/Darwin/ignore-noninstrumented.mm b/test/tsan/Darwin/ignore-noninstrumented.mm index 668a76a46..88d39268f 100644 --- a/test/tsan/Darwin/ignore-noninstrumented.mm +++ b/test/tsan/Darwin/ignore-noninstrumented.mm @@ -1,4 +1,7 @@ -// Check that ignore_noninstrumented_modules=1 suppresses races from system libraries on OS X. +// Check that ignore_noninstrumented_modules=1 suppresses 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 diff --git a/test/tsan/Darwin/ignored-interceptors.mm b/test/tsan/Darwin/ignored-interceptors.mm deleted file mode 100644 index b2e40f07d..000000000 --- a/test/tsan/Darwin/ignored-interceptors.mm +++ /dev/null @@ -1,55 +0,0 @@ -// Check that ignore_interceptors_accesses=1 suppresses 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: %env_tsan_opts=ignore_noninstrumented_modules=0 %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE - -// With ignore_interceptors_accesses=1, no races are reported. -// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0:ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s - -// With ignore_interceptors_accesses=1, races in user's code are still reported. -// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0: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[]) { - fprintf(stderr, "Hello world.\n"); - - // NSUserDefaults uses XPC which triggers the false positive. - NSDictionary *d = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; - - 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); - } - - fprintf(stderr, "Done.\n"); -} - -// CHECK: Hello world. -// CHECK-RACE: SUMMARY: ThreadSanitizer: data race -// CHECK: Done. diff --git a/test/tsan/Darwin/objc-synchronize-cycle-tagged.mm b/test/tsan/Darwin/objc-synchronize-cycle-tagged.mm new file mode 100644 index 000000000..5806e8af9 --- /dev/null +++ b/test/tsan/Darwin/objc-synchronize-cycle-tagged.mm @@ -0,0 +1,42 @@ +// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support +// RUN: %run %t 6 2>&1 | FileCheck %s --check-prefix=SIX +// RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=SEVEN + +#import <Foundation/Foundation.h> + +static bool isTaggedPtr(id obj) { + uintptr_t ptr = (uintptr_t) obj; + return (ptr & 0x8000000000000001ull) != 0; +} + +int main(int argc, char* argv[]) { + assert(argc == 2); + int arg = atoi(argv[1]); + + @autoreleasepool { + NSObject* obj = [NSObject new]; + NSObject* num1 = @7; + NSObject* num2 = [NSNumber numberWithInt:arg]; + + assert(!isTaggedPtr(obj)); + assert(isTaggedPtr(num1) && isTaggedPtr(num2)); + + // obj -> num1 (includes num2) + @synchronized(obj) { + @synchronized(num1) { + } + } + + // num2 -> obj1 + @synchronized(num2) { + @synchronized(obj) { +// SEVEN: ThreadSanitizer: lock-order-inversion (potential deadlock) + } + } + } + + NSLog(@"PASS"); +// SIX-NOT: ThreadSanitizer +// SIX: PASS + return 0; +} diff --git a/test/tsan/Darwin/objc-synchronize-cycle.mm b/test/tsan/Darwin/objc-synchronize-cycle.mm new file mode 100644 index 000000000..fb8163115 --- /dev/null +++ b/test/tsan/Darwin/objc-synchronize-cycle.mm @@ -0,0 +1,31 @@ +// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support +// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: %env_tsan_opts=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s +// RUN: %env_tsan_opts=detect_deadlocks=0 %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED + +#import <Foundation/Foundation.h> + +int main() { + @autoreleasepool { + NSObject* obj1 = [NSObject new]; + NSObject* obj2 = [NSObject new]; + + // obj1 -> obj2 + @synchronized(obj1) { + @synchronized(obj2) { + } + } + + // obj1 -> obj1 + @synchronized(obj2) { + @synchronized(obj1) { +// CHECK: ThreadSanitizer: lock-order-inversion (potential deadlock) + } + } + } + + NSLog(@"PASS"); +// DISABLED-NOT: ThreadSanitizer +// DISABLED: PASS + return 0; +} diff --git a/test/tsan/Darwin/objc-synchronize-nested-recursive.mm b/test/tsan/Darwin/objc-synchronize-nested-recursive.mm new file mode 100644 index 000000000..ab6643e5c --- /dev/null +++ b/test/tsan/Darwin/objc-synchronize-nested-recursive.mm @@ -0,0 +1,35 @@ +// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support +// RUN: %run %t 2>&1 | FileCheck %s + +#import <Foundation/Foundation.h> + +int main() { + @autoreleasepool { + NSObject* obj1 = [NSObject new]; + NSObject* obj2 = [NSObject new]; + + @synchronized(obj1) { + @synchronized(obj1) { + NSLog(@"nested 1-1"); +// CHECK: nested 1-1 + } + } + + @synchronized(obj1) { + @synchronized(obj2) { + @synchronized(obj1) { + @synchronized(obj2) { + NSLog(@"nested 1-2-1-2"); +// CHECK: nested 1-2-1-2 + } + } + } + } + + } + + NSLog(@"PASS"); +// CHECK-NOT: ThreadSanitizer +// CHECK: PASS + return 0; +} diff --git a/test/tsan/deadlock_detector_stress_test.cc b/test/tsan/deadlock_detector_stress_test.cc index bbaaabbb3..f3d2fc712 100644 --- a/test/tsan/deadlock_detector_stress_test.cc +++ b/test/tsan/deadlock_detector_stress_test.cc @@ -1,12 +1,12 @@ // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadMutex -// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOT-SECOND -// RUN: %env_tsan_opts=detect_deadlocks=1:second_deadlock_stack=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SECOND +// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOT-SECOND +// RUN: %env_tsan_opts=second_deadlock_stack=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SECOND // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadSpinLock -// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s +// RUN: %deflake %run %t | FileCheck %s // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRWLock -// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD +// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRecursiveMutex -// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC +// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC #include "test.h" #undef NDEBUG #include <assert.h> diff --git a/test/tsan/ignored-interceptors-mmap.cc b/test/tsan/ignored-interceptors-mmap.cc index 4686e8eb3..bb43250a6 100644 --- a/test/tsan/ignored-interceptors-mmap.cc +++ b/test/tsan/ignored-interceptors-mmap.cc @@ -1,10 +1,12 @@ // RUN: %clangxx_tsan -O0 %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NORMAL -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE +// RUN: %run %t ignore 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE // XFAIL: freebsd,netbsd -#include <errno.h> #include <sys/mman.h> +#include <string.h> +#include <assert.h> +#include <atomic> #include "test.h" @@ -15,48 +17,45 @@ void AnnotateIgnoreWritesBegin(const char *f, int l); void AnnotateIgnoreWritesEnd(const char *f, int l); } -void *global_p; +// Use atomic to ensure we do not have a race for the pointer value itself. We +// only want to check races in the mmap'd memory to isolate the test that mmap +// respects ignore annotations. +std::atomic<int*> global_p; -int mmap_and_ignore_reads_and_writes() { +void mmap_ignored(bool ignore) { const size_t kSize = sysconf(_SC_PAGESIZE); - void *p = mmap(0, kSize, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON, -1, 0); - if (p == MAP_FAILED) - return printf("mmap failed with %d\n", errno); - munmap(p, kSize); - - void *new_p = mmap(p, kSize, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON, -1, 0); - if (p == MAP_FAILED || p != new_p) - return printf("second mmap failed with %d\n", errno); - - AnnotateIgnoreWritesBegin(__FILE__, __LINE__); - global_p = p; - AnnotateIgnoreWritesEnd(__FILE__, __LINE__); + + if (ignore) AnnotateIgnoreWritesBegin(__FILE__, __LINE__); + void *p = mmap(0, kSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); + if (ignore) AnnotateIgnoreWritesEnd(__FILE__, __LINE__); + + // Use relaxed to retain the race between the mmap call and the memory write + global_p.store((int *)p, std::memory_order_relaxed); barrier_wait(&barrier); - return 0; } -void *Thread(void *a) { +void *WriteToMemory(void *unused) { barrier_wait(&barrier); - - ((int*)global_p)[1] = 10; - printf("Read the zero value from mmapped memory %d\n", ((int*)global_p)[1]); + global_p[0] = 7; return 0; } -int main() { +// Create race between allocating (mmap) and writing memory +int main(int argc, const char *argv[]) { + bool ignore = (argc > 1) && (strcmp(argv[1], "ignore") == 0); + barrier_init(&barrier, 2); pthread_t t; - pthread_create(&t, 0, Thread, 0); - if (mmap_and_ignore_reads_and_writes()) - return 1; + pthread_create(&t, 0, WriteToMemory, 0); + mmap_ignored(ignore); pthread_join(t, 0); + + assert(global_p[0] == 7); printf("OK\n"); return 0; } -// CHECK-NORMAL: WARNING: ThreadSanitizer: data race -// CHECK-NORMAL: OK -// CHECK-IGNORE_NOT: WARNING: ThreadSanitizer: data race +// CHECK-RACE: WARNING: ThreadSanitizer: data race +// CHECK-RACE: OK +// CHECK-IGNORE-NOT: WARNING: ThreadSanitizer: data race // CHECK-IGNORE: OK diff --git a/test/tsan/mutex_cycle2.c b/test/tsan/mutex_cycle2.c index 32659d4ee..0dc96d07c 100644 --- a/test/tsan/mutex_cycle2.c +++ b/test/tsan/mutex_cycle2.c @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: not %run %t 2>&1 | FileCheck %s // RUN: %env_tsan_opts=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s // RUN: %env_tsan_opts=detect_deadlocks=0 %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED // RUN: echo "deadlock:main" > %t.supp diff --git a/test/tsan/sunrpc.cc b/test/tsan/sunrpc.cc index 5cfb5344e..8e32d6d30 100644 --- a/test/tsan/sunrpc.cc +++ b/test/tsan/sunrpc.cc @@ -1,3 +1,5 @@ +// REQUIRES: sunrpc + // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s #include <pthread.h> |