aboutsummaryrefslogtreecommitdiff
path: root/test/tsan
diff options
context:
space:
mode:
Diffstat (limited to 'test/tsan')
-rw-r--r--test/tsan/CMakeLists.txt5
-rw-r--r--test/tsan/Darwin/gcd-async-norace.mm26
-rw-r--r--test/tsan/Darwin/gcd-async-race.mm38
-rw-r--r--test/tsan/Darwin/gcd-groups-norace.mm53
-rw-r--r--test/tsan/Darwin/gcd-groups-stress.mm43
-rw-r--r--test/tsan/Darwin/gcd-once.mm55
-rw-r--r--test/tsan/Darwin/gcd-semaphore-norace.mm29
-rw-r--r--test/tsan/Darwin/gcd-serial-queue-norace.mm40
-rw-r--r--test/tsan/Darwin/gcd-sync-norace.mm32
-rw-r--r--test/tsan/Darwin/gcd-sync-race.mm44
-rw-r--r--test/tsan/Darwin/lit.local.cfg9
-rw-r--r--test/tsan/Darwin/objc-race.mm55
-rw-r--r--test/tsan/Darwin/objc-simple.mm13
-rw-r--r--test/tsan/Darwin/osspinlock-norace.cc30
-rw-r--r--test/tsan/Darwin/symbolizer-atos.cc26
-rw-r--r--test/tsan/Darwin/symbolizer-dladdr.cc27
-rw-r--r--test/tsan/Linux/check_memcpy.cc15
-rw-r--r--test/tsan/allocator_returns_null.cc10
-rw-r--r--test/tsan/atomic_free3.cc28
-rw-r--r--test/tsan/barrier.cc3
-rw-r--r--test/tsan/bench_acquire_only.cc3
-rw-r--r--test/tsan/bench_acquire_release.cc3
-rw-r--r--test/tsan/bench_local_mutex.cc3
-rw-r--r--test/tsan/bench_mutex.cc3
-rw-r--r--test/tsan/bench_release_only.cc3
-rw-r--r--test/tsan/bench_rwmutex.cc3
-rw-r--r--test/tsan/bench_single_writer.cc3
-rw-r--r--test/tsan/bench_ten_mutexes.cc3
-rw-r--r--test/tsan/cond_cancel.c8
-rw-r--r--test/tsan/cond_version.c3
-rw-r--r--test/tsan/deadlock_detector_stress_test.cc34
-rw-r--r--test/tsan/dl_iterate_phdr.cc3
-rw-r--r--test/tsan/dlclose.cc4
-rw-r--r--test/tsan/fd_tid_recycled.cc54
-rw-r--r--test/tsan/fork_atexit.cc3
-rw-r--r--test/tsan/fork_deadlock.cc3
-rw-r--r--test/tsan/fork_multithreaded.cc3
-rw-r--r--test/tsan/fork_multithreaded3.cc1
-rw-r--r--test/tsan/free_race.c2
-rw-r--r--test/tsan/getline_nohang.cc2
-rw-r--r--test/tsan/global_race.cc6
-rw-r--r--test/tsan/global_race2.cc6
-rw-r--r--test/tsan/global_race3.cc6
-rw-r--r--test/tsan/halt_on_error.cc2
-rw-r--r--test/tsan/ignore_lib0.cc5
-rw-r--r--test/tsan/ignore_lib1.cc4
-rw-r--r--test/tsan/ignore_lib2.cc2
-rw-r--r--test/tsan/ignore_lib3.cc5
-rw-r--r--test/tsan/inlined_memcpy_race.cc2
-rw-r--r--test/tsan/java_race_pc.cc4
-rw-r--r--test/tsan/lit.cfg28
-rw-r--r--test/tsan/load_shared_lib.cc2
-rw-r--r--test/tsan/malloc_overflow.cc2
-rw-r--r--test/tsan/map32bit.cc7
-rw-r--r--test/tsan/memcmp_race.cc42
-rw-r--r--test/tsan/memcpy_race.cc6
-rw-r--r--test/tsan/mmap_large.cc6
-rw-r--r--test/tsan/mop_with_offset.cc4
-rw-r--r--test/tsan/mop_with_offset2.cc4
-rw-r--r--test/tsan/mutex_cycle2.c8
-rw-r--r--test/tsan/mutexset1.cc2
-rw-r--r--test/tsan/mutexset2.cc2
-rw-r--r--test/tsan/mutexset3.cc4
-rw-r--r--test/tsan/mutexset4.cc4
-rw-r--r--test/tsan/mutexset5.cc4
-rw-r--r--test/tsan/mutexset6.cc16
-rw-r--r--test/tsan/mutexset8.cc2
-rw-r--r--test/tsan/pie_test.cc12
-rw-r--r--test/tsan/pthread_atfork_deadlock.c2
-rw-r--r--test/tsan/race_on_barrier.c4
-rw-r--r--test/tsan/race_on_barrier2.c4
-rw-r--r--test/tsan/race_on_heap.cc3
-rw-r--r--test/tsan/race_on_mutex.c7
-rw-r--r--test/tsan/race_on_speculative_load.cc2
-rw-r--r--test/tsan/race_stress.cc25
-rw-r--r--test/tsan/race_top_suppression.cc2
-rw-r--r--test/tsan/race_top_suppression1.cc2
-rw-r--r--test/tsan/real_deadlock_detector_stress_test.cc9
-rw-r--r--test/tsan/setuid2.c12
-rw-r--r--test/tsan/signal_cond.cc14
-rw-r--r--test/tsan/signal_errno.cc6
-rw-r--r--test/tsan/signal_longjmp.cc14
-rw-r--r--test/tsan/signal_recursive.cc2
-rw-r--r--test/tsan/signal_reset.cc1
-rw-r--r--test/tsan/signal_sync.cc1
-rw-r--r--test/tsan/signal_thread.cc1
-rw-r--r--test/tsan/stack_sync_reuse.cc8
-rw-r--r--test/tsan/suppressions_global.cc2
-rw-r--r--test/tsan/suppressions_race.cc2
-rw-r--r--test/tsan/suppressions_race2.cc2
-rw-r--r--test/tsan/test.h75
-rwxr-xr-xtest/tsan/test_output.sh66
-rw-r--r--test/tsan/thread_name2.cc5
-rw-r--r--test/tsan/tls_race.cc6
-rw-r--r--test/tsan/tls_race2.cc7
-rw-r--r--test/tsan/vfork.cc1
-rw-r--r--test/tsan/virtual_inheritance_compile_bug.cc2
-rw-r--r--test/tsan/vptr_benign_race.cc20
98 files changed, 1010 insertions, 219 deletions
diff --git a/test/tsan/CMakeLists.txt b/test/tsan/CMakeLists.txt
index 2996c1d80fbd..01e80388bb95 100644
--- a/test/tsan/CMakeLists.txt
+++ b/test/tsan/CMakeLists.txt
@@ -1,12 +1,13 @@
set(TSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
-if(NOT ${LLVM_NATIVE_ARCH} STREQUAL "Mips")
+if(${COMPILER_RT_DEFAULT_TARGET_ARCH} MATCHES "x86_64")
list(APPEND TSAN_TEST_DEPS GotsanRuntimeCheck)
endif()
if(NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND TSAN_TEST_DEPS tsan)
endif()
if(COMPILER_RT_HAS_LIBCXX_SOURCES AND
- COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang")
+ COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang"
+ AND NOT APPLE)
list(APPEND TSAN_TEST_DEPS libcxx_tsan)
set(TSAN_HAS_LIBCXX True)
else()
diff --git a/test/tsan/Darwin/gcd-async-norace.mm b/test/tsan/Darwin/gcd-async-norace.mm
new file mode 100644
index 000000000000..b987e00656fb
--- /dev/null
+++ b/test/tsan/Darwin/gcd-async-norace.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+
+ global = 42;
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ global = 43;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-async-race.mm b/test/tsan/Darwin/gcd-async-race.mm
new file mode 100644
index 000000000000..31163f972896
--- /dev/null
+++ b/test/tsan/Darwin/gcd-async-race.mm
@@ -0,0 +1,38 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &global);
+ barrier_init(&barrier, 2);
+
+ global = 42;
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ global = 43;
+ barrier_wait(&barrier);
+ });
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ barrier_wait(&barrier);
+ global = 44;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'global' at [[ADDR]] (global_race.cc.exe+0x{{[0-9,a-f]+}})
+// CHECK: Done.
diff --git a/test/tsan/Darwin/gcd-groups-norace.mm b/test/tsan/Darwin/gcd-groups-norace.mm
new file mode 100644
index 000000000000..fb4d804ed8c7
--- /dev/null
+++ b/test/tsan/Darwin/gcd-groups-norace.mm
@@ -0,0 +1,53 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &global);
+
+ dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+ global = 42;
+
+ dispatch_group_t g = dispatch_group_create();
+ dispatch_group_async(g, q, ^{
+ global = 43;
+ });
+ dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
+
+ global = 44;
+
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ global = 45;
+ dispatch_group_leave(g);
+ });
+ dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
+
+ global = 46;
+
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ global = 47;
+ dispatch_group_leave(g);
+ });
+ dispatch_group_notify(g, q, ^{
+ global = 48;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-groups-stress.mm b/test/tsan/Darwin/gcd-groups-stress.mm
new file mode 100644
index 000000000000..62a80085ed8d
--- /dev/null
+++ b/test/tsan/Darwin/gcd-groups-stress.mm
@@ -0,0 +1,43 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+void notify_callback(void *context) {
+ // Do nothing.
+}
+
+int main() {
+ NSLog(@"Hello world.");
+
+ dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+
+ for (int i = 0; i < 300000; i++) {
+ dispatch_group_t g = dispatch_group_create();
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ dispatch_group_leave(g);
+ });
+ dispatch_group_notify(g, q, ^{
+ // Do nothing.
+ });
+ dispatch_release(g);
+ }
+
+ for (int i = 0; i < 300000; i++) {
+ dispatch_group_t g = dispatch_group_create();
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ dispatch_group_leave(g);
+ });
+ dispatch_group_notify_f(g, q, nullptr, &notify_callback);
+ dispatch_release(g);
+ }
+
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
+// CHECK-NOT: CHECK failed
diff --git a/test/tsan/Darwin/gcd-once.mm b/test/tsan/Darwin/gcd-once.mm
new file mode 100644
index 000000000000..17757d203751
--- /dev/null
+++ b/test/tsan/Darwin/gcd-once.mm
@@ -0,0 +1,55 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+static const long kNumThreads = 4;
+
+long global;
+long global2;
+
+static dispatch_once_t once_token;
+static dispatch_once_t once_token2;
+
+void f(void *) {
+ global2 = 42;
+ usleep(100000);
+}
+
+void *Thread(void *a) {
+ barrier_wait(&barrier);
+
+ dispatch_once(&once_token, ^{
+ global = 42;
+ usleep(100000);
+ });
+ long x = global;
+
+ dispatch_once_f(&once_token2, NULL, f);
+ long x2 = global2;
+
+ fprintf(stderr, "global = %ld\n", x);
+ fprintf(stderr, "global2 = %ld\n", x2);
+ return 0;
+}
+
+int main() {
+ fprintf(stderr, "Hello world.\n");
+ barrier_init(&barrier, kNumThreads);
+
+ pthread_t t[kNumThreads];
+ for (int i = 0; i < kNumThreads; i++) {
+ pthread_create(&t[i], 0, Thread, 0);
+ }
+ for (int i = 0; i < kNumThreads; i++) {
+ pthread_join(t[i], 0);
+ }
+
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-semaphore-norace.mm b/test/tsan/Darwin/gcd-semaphore-norace.mm
new file mode 100644
index 000000000000..cd52a79ca65a
--- /dev/null
+++ b/test/tsan/Darwin/gcd-semaphore-norace.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+
+ global = 42;
+
+ dispatch_semaphore_t sem = dispatch_semaphore_create(0);
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+
+ global = 43;
+ dispatch_semaphore_signal(sem);
+ });
+
+ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
+ global = 44;
+
+ NSLog(@"Done.");
+ return 0;
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-serial-queue-norace.mm b/test/tsan/Darwin/gcd-serial-queue-norace.mm
new file mode 100644
index 000000000000..8f6de27695a5
--- /dev/null
+++ b/test/tsan/Darwin/gcd-serial-queue-norace.mm
@@ -0,0 +1,40 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &global);
+
+ dispatch_queue_t q1 = dispatch_queue_create("my.queue1", DISPATCH_QUEUE_CONCURRENT);
+ dispatch_queue_t q2 = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_SERIAL);
+
+ global = 42;
+ for (int i = 0; i < 10; i++) {
+ dispatch_async(q1, ^{
+ for (int i = 0; i < 100; i++) {
+ dispatch_sync(q2, ^{
+ global++;
+ });
+ }
+ });
+ }
+
+ dispatch_barrier_async(q1, ^{
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-sync-norace.mm b/test/tsan/Darwin/gcd-sync-norace.mm
new file mode 100644
index 000000000000..f21cfdedbce1
--- /dev/null
+++ b/test/tsan/Darwin/gcd-sync-norace.mm
@@ -0,0 +1,32 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+long global;
+
+static const long nIter = 1000;
+
+int main() {
+ NSLog(@"Hello world.");
+
+ global = 42;
+ for (int i = 0; i < nIter; i++) {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ global = i;
+
+ if (i == nIter - 1) {
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ }
+ });
+ });
+ }
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-sync-race.mm b/test/tsan/Darwin/gcd-sync-race.mm
new file mode 100644
index 000000000000..62901d9b2612
--- /dev/null
+++ b/test/tsan/Darwin/gcd-sync-race.mm
@@ -0,0 +1,44 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &global);
+ barrier_init(&barrier, 2);
+
+ dispatch_queue_t q1 = dispatch_queue_create("my.queue1", DISPATCH_QUEUE_CONCURRENT);
+ dispatch_queue_t q2 = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_CONCURRENT);
+
+ global = 42;
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ dispatch_sync(q1, ^{
+ global = 43;
+ barrier_wait(&barrier);
+ });
+ });
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ dispatch_sync(q2, ^{
+ barrier_wait(&barrier);
+ global = 44;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'global' at [[ADDR]] (global_race.cc.exe+0x{{[0-9,a-f]+}})
+// CHECK: Done.
diff --git a/test/tsan/Darwin/lit.local.cfg b/test/tsan/Darwin/lit.local.cfg
new file mode 100644
index 000000000000..a85dfcd24c08
--- /dev/null
+++ b/test/tsan/Darwin/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Darwin']:
+ config.unsupported = True
diff --git a/test/tsan/Darwin/objc-race.mm b/test/tsan/Darwin/objc-race.mm
new file mode 100644
index 000000000000..bd93d2f1c2ea
--- /dev/null
+++ b/test/tsan/Darwin/objc-race.mm
@@ -0,0 +1,55 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+@interface MyClass : NSObject {
+ long instance_variable;
+}
+- (void)method:(long)value;
+@end
+
+@implementation MyClass
+
+- (void)method:(long)value {
+ self->instance_variable = value;
+}
+
+@end
+
+int main() {
+ NSLog(@"Hello world.");
+ barrier_init(&barrier, 2);
+
+ MyClass *my_object = [MyClass new];
+ [my_object method:42];
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ [my_object method:43];
+ barrier_wait(&barrier);
+ });
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ barrier_wait(&barrier);
+ [my_object method:44];
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+ return 0;
+}
+
+// CHECK: Hello world.
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write of size 8
+// CHECK: #0 -[MyClass method:]
+// CHECK: Write of size 8
+// CHECK: #0 -[MyClass method:]
+// CHECK: Location is heap block
+// CHECK: Done.
diff --git a/test/tsan/Darwin/objc-simple.mm b/test/tsan/Darwin/objc-simple.mm
new file mode 100644
index 000000000000..a4bf1f1beaa0
--- /dev/null
+++ b/test/tsan/Darwin/objc-simple.mm
@@ -0,0 +1,13 @@
+// Test that a simple Obj-C program runs and exits without any warnings.
+
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+int main() {
+ NSLog(@"Hello world");
+}
+
+// CHECK: Hello world
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/osspinlock-norace.cc b/test/tsan/Darwin/osspinlock-norace.cc
new file mode 100644
index 000000000000..2ac3989c223e
--- /dev/null
+++ b/test/tsan/Darwin/osspinlock-norace.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include <libkern/OSAtomic.h>
+#include <pthread.h>
+#include <stdio.h>
+
+int Global;
+OSSpinLock lock;
+
+void *Thread(void *x) {
+ OSSpinLockLock(&lock);
+ Global++;
+ OSSpinLockUnlock(&lock);
+ return NULL;
+}
+
+int main() {
+ fprintf(stderr, "Hello world.\n");
+
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread, NULL);
+ pthread_create(&t[1], NULL, Thread, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/symbolizer-atos.cc b/test/tsan/Darwin/symbolizer-atos.cc
new file mode 100644
index 000000000000..960fecc98641
--- /dev/null
+++ b/test/tsan/Darwin/symbolizer-atos.cc
@@ -0,0 +1,26 @@
+// RUN: %clangxx_tsan %s -o %t
+// RUN: %env_tsan_opts=verbosity=2:external_symbolizer_path=/usr/bin/atos %deflake %run %t | FileCheck %s
+#include "../test.h"
+
+int GlobalData[10];
+
+void *Thread(void *a) {
+ barrier_wait(&barrier);
+ GlobalData[2] = 42;
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ print_address("addr=", 1, GlobalData);
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ GlobalData[2] = 43;
+ barrier_wait(&barrier);
+ pthread_join(t, 0);
+}
+
+// CHECK: Using atos at user-specified path: /usr/bin/atos
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'GlobalData' at [[ADDR]] ({{.*}}+0x{{[0-9,a-f]+}})
diff --git a/test/tsan/Darwin/symbolizer-dladdr.cc b/test/tsan/Darwin/symbolizer-dladdr.cc
new file mode 100644
index 000000000000..3b213dda85d4
--- /dev/null
+++ b/test/tsan/Darwin/symbolizer-dladdr.cc
@@ -0,0 +1,27 @@
+// RUN: %clangxx_tsan %s -o %t
+// RUN: %env_tsan_opts=verbosity=2:external_symbolizer_path= %deflake %run %t | FileCheck %s
+#include "../test.h"
+
+int GlobalData[10];
+
+void *Thread(void *a) {
+ barrier_wait(&barrier);
+ GlobalData[2] = 42;
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ print_address("addr=", 1, GlobalData);
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ GlobalData[2] = 43;
+ barrier_wait(&barrier);
+ pthread_join(t, 0);
+}
+
+// CHECK: External symbolizer is explicitly disabled.
+// CHECK: Using dladdr symbolizer.
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'GlobalData' at [[ADDR]] ({{.*}}+0x{{[0-9,a-f]+}})
diff --git a/test/tsan/Linux/check_memcpy.cc b/test/tsan/Linux/check_memcpy.cc
new file mode 100644
index 000000000000..8ad04c07cf51
--- /dev/null
+++ b/test/tsan/Linux/check_memcpy.cc
@@ -0,0 +1,15 @@
+// Test that verifies TSan runtime doesn't contain compiler-emitted
+// memcpy/memmove calls. It builds the binary with TSan and passes it to
+// check_memcpy.sh script.
+
+// RUN: %clangxx_tsan -O1 %s -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+int main() {
+ return 0;
+}
+
+// CHECK-NOT: callq {{.*<(__interceptor_)?mem(cpy|set)>}}
+// tail calls:
+// CHECK-NOT: jmpq {{.*<(__interceptor_)?mem(cpy|set)>}}
+
diff --git a/test/tsan/allocator_returns_null.cc b/test/tsan/allocator_returns_null.cc
index cde706bc8a1d..66930076ac3a 100644
--- a/test/tsan/allocator_returns_null.cc
+++ b/test/tsan/allocator_returns_null.cc
@@ -4,11 +4,11 @@
//
// RUN: %clangxx_tsan -O0 %s -o %t
// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH
-// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH
-// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH
-// RUN: TSAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH
+// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
+// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH
+// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH
+// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH
+// RUN: %env_tsan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH
#include <limits.h>
#include <stdlib.h>
diff --git a/test/tsan/atomic_free3.cc b/test/tsan/atomic_free3.cc
new file mode 100644
index 000000000000..f2875aeb656f
--- /dev/null
+++ b/test/tsan/atomic_free3.cc
@@ -0,0 +1,28 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "test.h"
+
+// Test for https://github.com/google/sanitizers/issues/602
+
+void *Thread(void *a) {
+ __atomic_store_n((int*)a, 1, __ATOMIC_RELAXED);
+ return 0;
+}
+
+int main() {
+ int *a = new int(0);
+ pthread_t t;
+ pthread_create(&t, 0, Thread, a);
+ while (__atomic_load_n(a, __ATOMIC_RELAXED) == 0)
+ sched_yield();
+ delete a;
+ pthread_join(t, 0);
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write
+// CHECK: #0 operator delete
+// CHECK: #1 main
+
+// CHECK: Previous atomic write
+// CHECK: #0 __tsan_atomic32_store
+// CHECK: #1 Thread
diff --git a/test/tsan/barrier.cc b/test/tsan/barrier.cc
index d8c2b6ffe514..de2756de2a12 100644
--- a/test/tsan/barrier.cc
+++ b/test/tsan/barrier.cc
@@ -2,6 +2,9 @@
// CHECK-NOT: ThreadSanitizer: data race
// CHECK: DONE
+// pthread barriers are not available on OS X
+// UNSUPPORTED: darwin
+
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
diff --git a/test/tsan/bench_acquire_only.cc b/test/tsan/bench_acquire_only.cc
index 5cd6bd74ebee..0ed21b4612ab 100644
--- a/test/tsan/bench_acquire_only.cc
+++ b/test/tsan/bench_acquire_only.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
int x;
diff --git a/test/tsan/bench_acquire_release.cc b/test/tsan/bench_acquire_release.cc
index 9e53a7b26efa..3799452a1629 100644
--- a/test/tsan/bench_acquire_release.cc
+++ b/test/tsan/bench_acquire_release.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
int x;
diff --git a/test/tsan/bench_local_mutex.cc b/test/tsan/bench_local_mutex.cc
index 0fa1db0c883c..15f83bc8b282 100644
--- a/test/tsan/bench_local_mutex.cc
+++ b/test/tsan/bench_local_mutex.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
pthread_mutex_t *mtx;
diff --git a/test/tsan/bench_mutex.cc b/test/tsan/bench_mutex.cc
index 324d53fd7f28..58aa86a787d3 100644
--- a/test/tsan/bench_mutex.cc
+++ b/test/tsan/bench_mutex.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
pthread_mutex_t mtx;
diff --git a/test/tsan/bench_release_only.cc b/test/tsan/bench_release_only.cc
index 0a86f73f249e..7f26041afc49 100644
--- a/test/tsan/bench_release_only.cc
+++ b/test/tsan/bench_release_only.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
int *x;
diff --git a/test/tsan/bench_rwmutex.cc b/test/tsan/bench_rwmutex.cc
index 818ee8c82bc1..2b3dcb012e50 100644
--- a/test/tsan/bench_rwmutex.cc
+++ b/test/tsan/bench_rwmutex.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
pthread_rwlock_t mtx;
diff --git a/test/tsan/bench_single_writer.cc b/test/tsan/bench_single_writer.cc
index 0d3810a03ad0..3d2ea150b5fb 100644
--- a/test/tsan/bench_single_writer.cc
+++ b/test/tsan/bench_single_writer.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
int x;
diff --git a/test/tsan/bench_ten_mutexes.cc b/test/tsan/bench_ten_mutexes.cc
index 876f1365ee43..e7fa05ea8203 100644
--- a/test/tsan/bench_ten_mutexes.cc
+++ b/test/tsan/bench_ten_mutexes.cc
@@ -1,6 +1,9 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// bench.h needs pthread barriers which are not available on OS X
+// UNSUPPORTED: darwin
+
#include "bench.h"
const int kMutex = 10;
diff --git a/test/tsan/cond_cancel.c b/test/tsan/cond_cancel.c
index ddfb745174f6..fb6a66136b8a 100644
--- a/test/tsan/cond_cancel.c
+++ b/test/tsan/cond_cancel.c
@@ -1,6 +1,14 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
// CHECK-NOT: WARNING
// CHECK: OK
+// This test is failing on powerpc64 (VMA=44). After calling pthread_cancel,
+// the Thread-specific data destructors are not called, so the destructor
+// "thread_finalize" (defined in tsan_interceptors.cc) can not set the status
+// of the thread to "ThreadStatusFinished" failing a check in "SetJoined"
+// (defined in sanitizer_thread_registry.cc). It might seem a bug on glibc,
+// however the same version GLIBC-2.17 will not make fail the test on
+// powerpc64 BE (VMA=46)
+// XFAIL: powerpc64-unknown-linux-gnu
#include "test.h"
diff --git a/test/tsan/cond_version.c b/test/tsan/cond_version.c
index 2282c3ad738d..6bae776e6a4e 100644
--- a/test/tsan/cond_version.c
+++ b/test/tsan/cond_version.c
@@ -3,6 +3,9 @@
// previously there were issues with versioned symbols.
// CHECK: OK
+// OS X doesn't have pthread_condattr_setclock.
+// UNSUPPORTED: darwin
+
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
diff --git a/test/tsan/deadlock_detector_stress_test.cc b/test/tsan/deadlock_detector_stress_test.cc
index c77ffe555ce5..bbaaabbb3c14 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: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOT-SECOND
-// RUN: TSAN_OPTIONS="detect_deadlocks=1 second_deadlock_stack=1" %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SECOND
+// 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: %clangxx_tsan %s -o %t -DLockType=PthreadSpinLock
-// RUN: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s
+// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s
// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRWLock
-// RUN: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD
+// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD
// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRecursiveMutex
-// RUN: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC
+// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC
#include "test.h"
#undef NDEBUG
#include <assert.h>
@@ -56,6 +56,7 @@ class PthreadRecursiveMutex : public PthreadMutex {
static bool supports_recursive_lock() { return true; }
};
+#ifndef __APPLE__
class PthreadSpinLock {
public:
PthreadSpinLock() { assert(0 == pthread_spin_init(&mu_, 0)); }
@@ -76,6 +77,9 @@ class PthreadSpinLock {
pthread_spinlock_t mu_;
char padding_[64 - sizeof(pthread_spinlock_t)];
};
+#else
+class PthreadSpinLock : public PthreadMutex { };
+#endif
class PthreadRWLock {
public:
@@ -95,7 +99,7 @@ class PthreadRWLock {
private:
pthread_rwlock_t mu_;
- char padding_[64 - sizeof(pthread_rwlock_t)];
+ char padding_[256 - sizeof(pthread_rwlock_t)];
};
class LockTest {
@@ -148,7 +152,7 @@ class LockTest {
fprintf(stderr, "Starting Test1\n");
// CHECK: Starting Test1
Init(5);
- fprintf(stderr, "Expecting lock inversion: %p %p\n", A(0), A(1));
+ print_address("Expecting lock inversion: ", 2, A(0), A(1));
// CHECK: Expecting lock inversion: [[A1:0x[a-f0-9]*]] [[A2:0x[a-f0-9]*]]
Lock_0_1();
Lock_1_0();
@@ -174,7 +178,7 @@ class LockTest {
fprintf(stderr, "Starting Test2\n");
// CHECK: Starting Test2
Init(5);
- fprintf(stderr, "Expecting lock inversion: %p %p %p\n", A(0), A(1), A(2));
+ print_address("Expecting lock inversion: ", 3, A(0), A(1), A(2));
// CHECK: Expecting lock inversion: [[A1:0x[a-f0-9]*]] [[A2:0x[a-f0-9]*]] [[A3:0x[a-f0-9]*]]
Lock2(0, 1);
Lock2(1, 2);
@@ -498,6 +502,19 @@ class LockTest {
delete [] l;
}
+ void Test19() {
+ if (test_number > 0 && test_number != 19) return;
+ fprintf(stderr, "Starting Test19: lots of lock inversions\n");
+ const int kNumLocks = 45;
+ Init(kNumLocks);
+ for (int i = 0; i < kNumLocks; i++) {
+ for (int j = 0; j < kNumLocks; j++)
+ L((i + j) % kNumLocks);
+ for (int j = 0; j < kNumLocks; j++)
+ U((i + j) % kNumLocks);
+ }
+ }
+
private:
void Lock2(size_t l1, size_t l2) { L(l1); L(l2); U(l2); U(l1); }
@@ -602,6 +619,7 @@ int main(int argc, char **argv) {
LockTest().Test16();
LockTest().Test17();
LockTest().Test18();
+ LockTest().Test19();
fprintf(stderr, "ALL-DONE\n");
// CHECK: ALL-DONE
}
diff --git a/test/tsan/dl_iterate_phdr.cc b/test/tsan/dl_iterate_phdr.cc
index b230a920ac4f..b9ce615f82fe 100644
--- a/test/tsan/dl_iterate_phdr.cc
+++ b/test/tsan/dl_iterate_phdr.cc
@@ -1,7 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// If we mention TSAN_OPTIONS, the test won't run from test_output.sh script.
+// dl_iterate_phdr doesn't exist on OS X.
+// UNSUPPORTED: darwin
#ifdef BUILD_SO
diff --git a/test/tsan/dlclose.cc b/test/tsan/dlclose.cc
index 1a93fe6617e1..d497fd704e4f 100644
--- a/test/tsan/dlclose.cc
+++ b/test/tsan/dlclose.cc
@@ -1,10 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// If we mention TSAN_OPTIONS, the test won't run from test_output.sh script.
-
// Test case for
-// https://code.google.com/p/thread-sanitizer/issues/detail?id=80
+// https://github.com/google/sanitizers/issues/487
#ifdef BUILD_SO
diff --git a/test/tsan/fd_tid_recycled.cc b/test/tsan/fd_tid_recycled.cc
new file mode 100644
index 000000000000..d31478728bc0
--- /dev/null
+++ b/test/tsan/fd_tid_recycled.cc
@@ -0,0 +1,54 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "test.h"
+
+int fds[2];
+
+void *ThreadCreatePipe(void *x) {
+ pipe(fds);
+ return NULL;
+}
+
+void *ThreadDummy(void *x) {
+ return NULL;
+}
+
+void *ThreadWrite(void *x) {
+ write(fds[1], "a", 1);
+ barrier_wait(&barrier);
+ return NULL;
+}
+
+void *ThreadClose(void *x) {
+ barrier_wait(&barrier);
+ close(fds[0]);
+ close(fds[1]);
+ return NULL;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ pthread_t t_create;
+ pthread_create(&t_create, NULL, ThreadCreatePipe, NULL);
+ pthread_join(t_create, NULL);
+
+ for (int i = 0; i < 100; i++) {
+ pthread_t t_dummy;
+ pthread_create(&t_dummy, NULL, ThreadDummy, NULL);
+ pthread_join(t_dummy, NULL);
+ }
+
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, ThreadWrite, NULL);
+ pthread_create(&t[1], NULL, ThreadClose, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+}
+
+// CHECK-NOT: CHECK failed
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write of size 8
+// CHECK: #0 close
+// CHECK: #1 ThreadClose
+// CHECK: Previous read of size 8
+// CHECK: #0 write
+// CHECK: #1 ThreadWrite
diff --git a/test/tsan/fork_atexit.cc b/test/tsan/fork_atexit.cc
index 6801d3ffff7e..51a64fc264d1 100644
--- a/test/tsan/fork_atexit.cc
+++ b/test/tsan/fork_atexit.cc
@@ -1,4 +1,5 @@
-// RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="atexit_sleep_ms=50" %run %t 2>&1 | FileCheck %s
+// 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>
diff --git a/test/tsan/fork_deadlock.cc b/test/tsan/fork_deadlock.cc
index 9418800bd336..22bed086f7d0 100644
--- a/test/tsan/fork_deadlock.cc
+++ b/test/tsan/fork_deadlock.cc
@@ -1,4 +1,5 @@
-// RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="atexit_sleep_ms=50" %run %t 2>&1 | FileCheck %s
+// 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>
diff --git a/test/tsan/fork_multithreaded.cc b/test/tsan/fork_multithreaded.cc
index 3ddb417c7cb5..b345f58ad0c3 100644
--- a/test/tsan/fork_multithreaded.cc
+++ b/test/tsan/fork_multithreaded.cc
@@ -1,5 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-DIE
-// RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="die_after_fork=0" %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-NODIE
+// 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>
diff --git a/test/tsan/fork_multithreaded3.cc b/test/tsan/fork_multithreaded3.cc
index a651b3c18b4e..5b8c13eb8b85 100644
--- a/test/tsan/fork_multithreaded3.cc
+++ b/test/tsan/fork_multithreaded3.cc
@@ -1,4 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
diff --git a/test/tsan/free_race.c b/test/tsan/free_race.c
index 63cee8c4adc5..d508552c9801 100644
--- a/test/tsan/free_race.c
+++ b/test/tsan/free_race.c
@@ -1,6 +1,6 @@
// RUN: %clang_tsan -O1 %s -o %t
// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOZUPP
-// RUN: TSAN_OPTIONS="suppressions='%s.supp' print_suppressions=1" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUPP
+// RUN: %env_tsan_opts=suppressions='%s.supp':print_suppressions=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUPP
#include "test.h"
diff --git a/test/tsan/getline_nohang.cc b/test/tsan/getline_nohang.cc
index 89afbe1a66a8..d103839b8bd0 100644
--- a/test/tsan/getline_nohang.cc
+++ b/test/tsan/getline_nohang.cc
@@ -1,7 +1,7 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t
// Make sure TSan doesn't deadlock on a file stream lock at program shutdown.
-// See https://code.google.com/p/thread-sanitizer/issues/detail?id=47
+// See https://github.com/google/sanitizers/issues/454
#ifdef __FreeBSD__
#define _WITH_GETLINE // to declare getline()
#endif
diff --git a/test/tsan/global_race.cc b/test/tsan/global_race.cc
index 3128ec411749..a35299619e9d 100644
--- a/test/tsan/global_race.cc
+++ b/test/tsan/global_race.cc
@@ -11,9 +11,7 @@ void *Thread(void *a) {
int main() {
barrier_init(&barrier, 2);
- fprintf(stderr, "addr=");
- print_address(GlobalData);
- fprintf(stderr, "\n");
+ print_address("addr=", 1, GlobalData);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
GlobalData[2] = 43;
@@ -23,5 +21,5 @@ int main() {
// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
// CHECK: WARNING: ThreadSanitizer: data race
-// CHECK: Location is global 'GlobalData' of size 40 at [[ADDR]] (global_race.cc.exe+0x{{[0-9,a-f]+}})
+// CHECK: Location is global 'GlobalData' {{(of size 40 )?}}at [[ADDR]] (global_race.cc.exe+0x{{[0-9,a-f]+}})
diff --git a/test/tsan/global_race2.cc b/test/tsan/global_race2.cc
index 4ab2842e7eef..95dff1997808 100644
--- a/test/tsan/global_race2.cc
+++ b/test/tsan/global_race2.cc
@@ -11,9 +11,7 @@ void *Thread(void *a) {
int main() {
barrier_init(&barrier, 2);
- fprintf(stderr, "addr2=");
- print_address(&x);
- fprintf(stderr, "\n");
+ print_address("addr2=", 1, &x);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
x = 0;
@@ -23,5 +21,5 @@ int main() {
// CHECK: addr2=[[ADDR2:0x[0-9,a-f]+]]
// CHECK: WARNING: ThreadSanitizer: data race
-// CHECK: Location is global 'x' of size 4 at [[ADDR2]] ({{.*}}+0x{{[0-9,a-f]+}})
+// CHECK: Location is global 'x' {{(of size 4 )?}}at [[ADDR2]] ({{.*}}+0x{{[0-9,a-f]+}})
diff --git a/test/tsan/global_race3.cc b/test/tsan/global_race3.cc
index 1531d7830f78..e0d59d284420 100644
--- a/test/tsan/global_race3.cc
+++ b/test/tsan/global_race3.cc
@@ -16,9 +16,7 @@ void *Thread(void *a) {
int main() {
barrier_init(&barrier, 2);
- fprintf(stderr, "addr3=");
- print_address(XXX::YYY::ZZZ);
- fprintf(stderr, "\n");
+ print_address("addr3=", 1, XXX::YYY::ZZZ);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
XXX::YYY::ZZZ[0] = 0;
@@ -28,4 +26,4 @@ int main() {
// CHECK: addr3=[[ADDR3:0x[0-9,a-f]+]]
// CHECK: WARNING: ThreadSanitizer: data race
-// CHECK: Location is global 'XXX::YYY::ZZZ' of size 40 at [[ADDR3]] ({{.*}}+0x{{[0-9,a-f]+}})
+// CHECK: Location is global 'XXX::YYY::ZZZ' {{(of size 40 )?}}at [[ADDR3]] ({{.*}}+0x{{[0-9,a-f]+}})
diff --git a/test/tsan/halt_on_error.cc b/test/tsan/halt_on_error.cc
index e55454b57c1d..5d481c3cbcd6 100644
--- a/test/tsan/halt_on_error.cc
+++ b/test/tsan/halt_on_error.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS halt_on_error=1" %deflake %run %t | FileCheck %s
+// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=halt_on_error=1 %deflake %run %t | FileCheck %s
#include "test.h"
int X;
diff --git a/test/tsan/ignore_lib0.cc b/test/tsan/ignore_lib0.cc
index 63c9340e99ac..c72aa496a1cd 100644
--- a/test/tsan/ignore_lib0.cc
+++ b/test/tsan/ignore_lib0.cc
@@ -3,11 +3,14 @@
// RUN: echo running w/o suppressions:
// RUN: LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
// RUN: echo running with suppressions:
-// RUN: LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
+// RUN: LD_LIBRARY_PATH=%T${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
// Tests that interceptors coming from a library specified in called_from_lib
// suppression are ignored.
+// Some aarch64 kernels do not support non executable write pages
+// REQUIRES: stable-runtime
+
#ifndef LIB
extern "C" void libfunc();
diff --git a/test/tsan/ignore_lib1.cc b/test/tsan/ignore_lib1.cc
index ef1f973795ed..e6a13a394395 100644
--- a/test/tsan/ignore_lib1.cc
+++ b/test/tsan/ignore_lib1.cc
@@ -3,11 +3,13 @@
// RUN: echo running w/o suppressions:
// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOSUPP
// RUN: echo running with suppressions:
-// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
+// RUN: %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WITHSUPP
// Tests that interceptors coming from a dynamically loaded library specified
// in called_from_lib suppression are ignored.
+// REQUIRES: stable-runtime
+
#ifndef LIB
#include <dlfcn.h>
diff --git a/test/tsan/ignore_lib2.cc b/test/tsan/ignore_lib2.cc
index ad3107cf53a2..4f584b14664a 100644
--- a/test/tsan/ignore_lib2.cc
+++ b/test/tsan/ignore_lib2.cc
@@ -1,7 +1,7 @@
// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib2_0.so
// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib2_1.so
// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %deflake %run %t | FileCheck %s
+// RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t | FileCheck %s
// Tests that called_from_lib suppression matched against 2 libraries
// causes program crash (this is not supported).
diff --git a/test/tsan/ignore_lib3.cc b/test/tsan/ignore_lib3.cc
index 96bf313f43a1..3f7be5cf8233 100644
--- a/test/tsan/ignore_lib3.cc
+++ b/test/tsan/ignore_lib3.cc
@@ -1,10 +1,13 @@
// RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %T/libignore_lib3.so
// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %deflake %run %t | FileCheck %s
+// RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t | FileCheck %s
// Tests that unloading of a library matched against called_from_lib suppression
// causes program crash (this is not supported).
+// Some aarch64 kernels do not support non executable write pages
+// REQUIRES: stable-runtime
+
#ifndef LIB
#include <dlfcn.h>
diff --git a/test/tsan/inlined_memcpy_race.cc b/test/tsan/inlined_memcpy_race.cc
index e3ed07abcf89..720f2bfcac8c 100644
--- a/test/tsan/inlined_memcpy_race.cc
+++ b/test/tsan/inlined_memcpy_race.cc
@@ -32,6 +32,6 @@ int main() {
// CHECK: #0 memset
// CHECK: #1 MemSetThread
// CHECK: Previous write
-// CHECK: #0 memcpy
+// CHECK: #0 {{(memcpy|memmove)}}
// CHECK: #1 MemCpyThread
diff --git a/test/tsan/java_race_pc.cc b/test/tsan/java_race_pc.cc
index 015a0b1f43c6..0745ade6c479 100644
--- a/test/tsan/java_race_pc.cc
+++ b/test/tsan/java_race_pc.cc
@@ -1,4 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// This test fails on powerpc64 on both VMA (44 and 46).
+// The Tsan report is returning wrong information about
+// the location of the race.
+// XFAIL: powerpc64
#include "java.h"
void foobar() {
diff --git a/test/tsan/lit.cfg b/test/tsan/lit.cfg
index d27500f8e3ea..2be10dae1c85 100644
--- a/test/tsan/lit.cfg
+++ b/test/tsan/lit.cfg
@@ -18,9 +18,19 @@ config.name = 'ThreadSanitizer'
config.test_source_root = os.path.dirname(__file__)
# Setup environment variables for running ThreadSanitizer.
-tsan_options = "atexit_sleep_ms=0"
+default_tsan_opts = "atexit_sleep_ms=0"
-config.environment['TSAN_OPTIONS'] = tsan_options
+if config.host_os == 'Darwin':
+ # On Darwin, we default to `abort_on_error=1`, which would make tests run
+ # much slower. Let's override this and run lit tests with 'abort_on_error=0'.
+ default_tsan_opts += ':abort_on_error=0'
+
+# Platform-specific default TSAN_OPTIONS for lit tests.
+if default_tsan_opts:
+ config.environment['TSAN_OPTIONS'] = default_tsan_opts
+ default_tsan_opts += ':'
+config.substitutions.append(('%env_tsan_opts=',
+ 'env TSAN_OPTIONS=' + default_tsan_opts))
# GCC driver doesn't add necessary compile/link flags with -fsanitize=thread.
if config.compiler_id == 'GNU':
@@ -34,7 +44,8 @@ clang_tsan_cflags = ["-fsanitize=thread",
"-m64"] + config.debug_info_flags + extra_cflags
clang_tsan_cxxflags = config.cxx_mode_flags + clang_tsan_cflags
# Add additional flags if we're using instrumented libc++.
-if config.has_libcxx:
+# Instrumented libcxx currently not supported on Darwin.
+if config.has_libcxx and config.host_os != 'Darwin':
# FIXME: Dehardcode this path somehow.
libcxx_path = os.path.join(config.compiler_rt_obj_root, "lib",
"tsan", "libcxx_tsan")
@@ -58,8 +69,13 @@ config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os)))
config.substitutions.append( ("%deflake ", os.path.join(os.path.dirname(__file__), "deflake.bash")) )
# Default test suffixes.
-config.suffixes = ['.c', '.cc', '.cpp']
+config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm']
-# ThreadSanitizer tests are currently supported on FreeBSD and Linux only.
-if config.host_os not in ['FreeBSD', 'Linux']:
+# ThreadSanitizer tests are currently supported on FreeBSD, Linux and Darwin.
+if config.host_os not in ['FreeBSD', 'Linux', 'Darwin']:
config.unsupported = True
+
+# Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL
+# because the test hangs.
+if config.target_arch != 'aarch64':
+ config.available_features.add('stable-runtime')
diff --git a/test/tsan/load_shared_lib.cc b/test/tsan/load_shared_lib.cc
index b7934b82df73..f02280895f83 100644
--- a/test/tsan/load_shared_lib.cc
+++ b/test/tsan/load_shared_lib.cc
@@ -3,7 +3,7 @@
// symbolized correctly.
// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so
-// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t -rdynamic && %deflake %run %t | FileCheck %s
#ifdef BUILD_SO
diff --git a/test/tsan/malloc_overflow.cc b/test/tsan/malloc_overflow.cc
index dadc94484f01..b2f9b0f57798 100644
--- a/test/tsan/malloc_overflow.cc
+++ b/test/tsan/malloc_overflow.cc
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: TSAN_OPTIONS=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_tsan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/tsan/map32bit.cc b/test/tsan/map32bit.cc
index d9a04655ddca..0411f29a9504 100644
--- a/test/tsan/map32bit.cc
+++ b/test/tsan/map32bit.cc
@@ -5,10 +5,15 @@
#include <sys/mman.h>
// Test for issue:
-// https://code.google.com/p/thread-sanitizer/issues/detail?id=5
+// https://github.com/google/sanitizers/issues/412
// MAP_32BIT flag for mmap is supported only for x86_64.
// XFAIL: mips64
+// XFAIL: aarch64
+// XFAIL: powerpc64
+
+// MAP_32BIT doesn't exist on OS X.
+// UNSUPPORTED: darwin
void *Thread(void *ptr) {
*(int*)ptr = 42;
diff --git a/test/tsan/memcmp_race.cc b/test/tsan/memcmp_race.cc
new file mode 100644
index 000000000000..b76f427e121c
--- /dev/null
+++ b/test/tsan/memcmp_race.cc
@@ -0,0 +1,42 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "test.h"
+#include <string.h>
+
+char *data0 = new char[10];
+char *data1 = new char[10];
+char *data2 = new char[10];
+
+void *Thread1(void *x) {
+ static volatile int size = 1;
+ static volatile int sink;
+ sink = memcmp(data0+5, data1, size);
+ barrier_wait(&barrier);
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ static volatile int size = 4;
+ barrier_wait(&barrier);
+ memcpy(data0+5, data2, size);
+ return NULL;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ print_address("addr=", 1, &data0[5]);
+ 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);
+ return 0;
+}
+
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write of size 1 at [[ADDR]] by thread T2:
+// CHECK: #0 {{(memcpy|memmove)}}
+// CHECK: #1 Thread2
+// CHECK: Previous read of size 1 at [[ADDR]] by thread T1:
+// CHECK: #0 memcmp
+// CHECK: #1 Thread1
diff --git a/test/tsan/memcpy_race.cc b/test/tsan/memcpy_race.cc
index d49577306d6c..4a098c0405fc 100644
--- a/test/tsan/memcpy_race.cc
+++ b/test/tsan/memcpy_race.cc
@@ -22,7 +22,7 @@ void *Thread2(void *x) {
int main() {
barrier_init(&barrier, 2);
- fprintf(stderr, "addr=%p\n", &data[5]);
+ print_address("addr=", 1, &data[5]);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
@@ -34,8 +34,8 @@ int main() {
// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 1 at [[ADDR]] by thread T2:
-// CHECK: #0 memcpy
+// CHECK: #0 {{(memcpy|memmove)}}
// CHECK: #1 Thread2
// CHECK: Previous write of size 1 at [[ADDR]] by thread T1:
-// CHECK: #0 memcpy
+// CHECK: #0 {{(memcpy|memmove)}}
// CHECK: #1 Thread1
diff --git a/test/tsan/mmap_large.cc b/test/tsan/mmap_large.cc
index 098530475df5..764e954f2b8e 100644
--- a/test/tsan/mmap_large.cc
+++ b/test/tsan/mmap_large.cc
@@ -14,15 +14,17 @@
int main() {
#ifdef __x86_64__
const size_t kLog2Size = 39;
-#elif defined(__mips64)
+#elif defined(__mips64) || defined(__aarch64__)
const size_t kLog2Size = 32;
+#elif defined(__powerpc64__)
+ const size_t kLog2Size = 39;
#endif
const uintptr_t kLocation = 0x40ULL << kLog2Size;
void *p = mmap(
reinterpret_cast<void*>(kLocation),
1ULL << kLog2Size,
PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
+ MAP_PRIVATE|MAP_ANON|MAP_NORESERVE,
-1, 0);
fprintf(stderr, "DONE %p %d\n", p, errno);
return p == MAP_FAILED;
diff --git a/test/tsan/mop_with_offset.cc b/test/tsan/mop_with_offset.cc
index c67e81e09cda..e2496d099ef1 100644
--- a/test/tsan/mop_with_offset.cc
+++ b/test/tsan/mop_with_offset.cc
@@ -18,8 +18,8 @@ void *Thread2(void *x) {
int main() {
barrier_init(&barrier, 2);
int *data = new int(42);
- fprintf(stderr, "ptr1=%p\n", data);
- fprintf(stderr, "ptr2=%p\n", (char*)data + 2);
+ print_address("ptr1=", 1, data);
+ print_address("ptr2=", 1, (char*)data + 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, data);
pthread_create(&t[1], NULL, Thread2, data);
diff --git a/test/tsan/mop_with_offset2.cc b/test/tsan/mop_with_offset2.cc
index 460267359cec..73c53f51233a 100644
--- a/test/tsan/mop_with_offset2.cc
+++ b/test/tsan/mop_with_offset2.cc
@@ -18,8 +18,8 @@ void *Thread2(void *x) {
int main() {
barrier_init(&barrier, 2);
int *data = new int(42);
- fprintf(stderr, "ptr1=%p\n", data);
- fprintf(stderr, "ptr2=%p\n", (char*)data + 2);
+ print_address("ptr1=", 1, data);
+ print_address("ptr2=", 1, (char*)data + 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, data);
pthread_create(&t[1], NULL, Thread2, data);
diff --git a/test/tsan/mutex_cycle2.c b/test/tsan/mutex_cycle2.c
index 85d19a0d0c35..32659d4eec0d 100644
--- a/test/tsan/mutex_cycle2.c
+++ b/test/tsan/mutex_cycle2.c
@@ -1,11 +1,11 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: not %run %t 2>&1 | FileCheck %s
-// RUN: TSAN_OPTIONS=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s
-// RUN: TSAN_OPTIONS=detect_deadlocks=0 %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
+// 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
-// RUN: TSAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %env_tsan_opts=suppressions='%t.supp' %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
// RUN: echo "deadlock:zzzz" > %t.supp
-// RUN: TSAN_OPTIONS="suppressions='%t.supp'" not %run %t 2>&1 | FileCheck %s
+// RUN: %env_tsan_opts=suppressions='%t.supp' not %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
diff --git a/test/tsan/mutexset1.cc b/test/tsan/mutexset1.cc
index 407cfe5bd9f1..8403b3401743 100644
--- a/test/tsan/mutexset1.cc
+++ b/test/tsan/mutexset1.cc
@@ -26,7 +26,7 @@ int main() {
// CHECK: Previous write of size 4 at {{.*}} by thread T2:
// CHECK: Mutex [[M1]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset1.cc:[[@LINE+1]]
+ // CHECK: #1 main {{.*}}mutexset1.cc:[[@LINE+1]]
pthread_mutex_init(&mtx, 0);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
diff --git a/test/tsan/mutexset2.cc b/test/tsan/mutexset2.cc
index 2a3e5bb95e87..5f7c0c41bb06 100644
--- a/test/tsan/mutexset2.cc
+++ b/test/tsan/mutexset2.cc
@@ -26,7 +26,7 @@ int main() {
// CHECK: (mutexes: write [[M1:M[0-9]+]]):
// CHECK: Mutex [[M1]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset2.cc:[[@LINE+1]]
+ // CHECK: #1 main {{.*}}mutexset2.cc:[[@LINE+1]]
pthread_mutex_init(&mtx, 0);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
diff --git a/test/tsan/mutexset3.cc b/test/tsan/mutexset3.cc
index ce64cf86e37c..24a9d9bf01ce 100644
--- a/test/tsan/mutexset3.cc
+++ b/test/tsan/mutexset3.cc
@@ -29,10 +29,10 @@ int main() {
// CHECK: Previous write of size 4 at {{.*}} by thread T2:
// CHECK: Mutex [[M1]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset3.cc:[[@LINE+4]]
+ // CHECK: #1 main {{.*}}mutexset3.cc:[[@LINE+4]]
// CHECK: Mutex [[M2]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset3.cc:[[@LINE+2]]
+ // CHECK: #1 main {{.*}}mutexset3.cc:[[@LINE+2]]
pthread_mutex_init(&mtx1, 0);
pthread_mutex_init(&mtx2, 0);
pthread_t t[2];
diff --git a/test/tsan/mutexset4.cc b/test/tsan/mutexset4.cc
index b961efd2136c..5d8ea9e400da 100644
--- a/test/tsan/mutexset4.cc
+++ b/test/tsan/mutexset4.cc
@@ -29,10 +29,10 @@ int main() {
// CHECK: (mutexes: write [[M1:M[0-9]+]], write [[M2:M[0-9]+]]):
// CHECK: Mutex [[M1]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset4.cc:[[@LINE+4]]
+ // CHECK: #1 main {{.*}}mutexset4.cc:[[@LINE+4]]
// CHECK: Mutex [[M2]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset4.cc:[[@LINE+2]]
+ // CHECK: #1 main {{.*}}mutexset4.cc:[[@LINE+2]]
pthread_mutex_init(&mtx1, 0);
pthread_mutex_init(&mtx2, 0);
pthread_t t[2];
diff --git a/test/tsan/mutexset5.cc b/test/tsan/mutexset5.cc
index 8ef9af0ced52..b5f4e7794929 100644
--- a/test/tsan/mutexset5.cc
+++ b/test/tsan/mutexset5.cc
@@ -30,10 +30,10 @@ int main() {
// CHECK: (mutexes: write [[M2:M[0-9]+]]):
// CHECK: Mutex [[M1]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset5.cc:[[@LINE+4]]
+ // CHECK: #1 main {{.*}}mutexset5.cc:[[@LINE+4]]
// CHECK: Mutex [[M2]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset5.cc:[[@LINE+5]]
+ // CHECK: #1 main {{.*}}mutexset5.cc:[[@LINE+5]]
pthread_mutex_init(&mtx1, 0);
pthread_mutex_init(&mtx2, 0);
pthread_t t[2];
diff --git a/test/tsan/mutexset6.cc b/test/tsan/mutexset6.cc
index f4251db6970e..ca349aaeee7a 100644
--- a/test/tsan/mutexset6.cc
+++ b/test/tsan/mutexset6.cc
@@ -3,7 +3,7 @@
int Global;
pthread_mutex_t mtx1;
-pthread_spinlock_t mtx2;
+pthread_mutex_t mtx2;
pthread_rwlock_t mtx3;
void *Thread1(void *x) {
@@ -17,10 +17,10 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
pthread_mutex_lock(&mtx1);
pthread_mutex_unlock(&mtx1);
- pthread_spin_lock(&mtx2);
+ pthread_mutex_lock(&mtx2);
pthread_rwlock_rdlock(&mtx3);
Global--;
- pthread_spin_unlock(&mtx2);
+ pthread_mutex_unlock(&mtx2);
pthread_rwlock_unlock(&mtx3);
barrier_wait(&barrier);
return NULL;
@@ -34,13 +34,13 @@ int main() {
// CHECK: Previous write of size 4 at {{.*}} by thread T2
// CHECK: (mutexes: write [[M2:M[0-9]+]], read [[M3:M[0-9]+]]):
// CHECK: Mutex [[M1]] (0x{{.*}}) created at:
- // CHECK: #1 main {{.*}}/mutexset6.cc:[[@LINE+5]]
+ // CHECK: #1 main {{.*}}mutexset6.cc:[[@LINE+5]]
// CHECK: Mutex [[M2]] (0x{{.*}}) created at:
- // CHECK: #1 main {{.*}}/mutexset6.cc:[[@LINE+4]]
+ // CHECK: #1 main {{.*}}mutexset6.cc:[[@LINE+4]]
// CHECK: Mutex [[M3]] (0x{{.*}}) created at:
- // CHECK: #1 main {{.*}}/mutexset6.cc:[[@LINE+3]]
+ // CHECK: #1 main {{.*}}mutexset6.cc:[[@LINE+3]]
pthread_mutex_init(&mtx1, 0);
- pthread_spin_init(&mtx2, 0);
+ pthread_mutex_init(&mtx2, 0);
pthread_rwlock_init(&mtx3, 0);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
@@ -48,6 +48,6 @@ int main() {
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
pthread_mutex_destroy(&mtx1);
- pthread_spin_destroy(&mtx2);
+ pthread_mutex_destroy(&mtx2);
pthread_rwlock_destroy(&mtx3);
}
diff --git a/test/tsan/mutexset8.cc b/test/tsan/mutexset8.cc
index 40d5d043dedd..69854e2ffa0a 100644
--- a/test/tsan/mutexset8.cc
+++ b/test/tsan/mutexset8.cc
@@ -26,7 +26,7 @@ int main() {
// CHECK: Previous write of size 4 at {{.*}} by thread T2:
// CHECK: Mutex [[M1]] (0x{{.*}}) created at:
// CHECK: #0 pthread_mutex_init
- // CHECK: #1 main {{.*}}/mutexset8.cc
+ // CHECK: #1 main {{.*}}mutexset8.cc
mtx = new pthread_mutex_t;
pthread_mutex_init(mtx, 0);
pthread_t t[2];
diff --git a/test/tsan/pie_test.cc b/test/tsan/pie_test.cc
new file mode 100644
index 000000000000..8635f9cd403f
--- /dev/null
+++ b/test/tsan/pie_test.cc
@@ -0,0 +1,12 @@
+// Check if tsan work with PIE binaries.
+// RUN: %clang_tsan %s -pie -fpic -o %t && %run %t
+
+// Some kernels might map PIE segments outside the current segment
+// mapping defined for x86 [1].
+// [1] https://git.kernel.org/linus/d1fd836dcf00d2028c700c7e44d2c23404062c90
+
+// UNSUPPORTED: x86
+
+int main(void) {
+ return 0;
+}
diff --git a/test/tsan/pthread_atfork_deadlock.c b/test/tsan/pthread_atfork_deadlock.c
index 4aeec82b6850..01107ee6692c 100644
--- a/test/tsan/pthread_atfork_deadlock.c
+++ b/test/tsan/pthread_atfork_deadlock.c
@@ -1,6 +1,6 @@
// RUN: %clang_tsan -O1 %s -lpthread -o %t && %deflake %run %t | FileCheck %s
// Regression test for
-// https://code.google.com/p/thread-sanitizer/issues/detail?id=61
+// https://github.com/google/sanitizers/issues/468
// When the data race was reported, pthread_atfork() handler used to be
// executed which caused another race report in the same thread, which resulted
// in a deadlock.
diff --git a/test/tsan/race_on_barrier.c b/test/tsan/race_on_barrier.c
index cf8a4cb99274..66fd339eb95b 100644
--- a/test/tsan/race_on_barrier.c
+++ b/test/tsan/race_on_barrier.c
@@ -1,4 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+
+// pthread barriers are not available on OS X
+// UNSUPPORTED: darwin
+
#include "test.h"
pthread_barrier_t B;
diff --git a/test/tsan/race_on_barrier2.c b/test/tsan/race_on_barrier2.c
index 98c028e19fdd..49adb6231230 100644
--- a/test/tsan/race_on_barrier2.c
+++ b/test/tsan/race_on_barrier2.c
@@ -1,4 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+
+// pthread barriers are not available on OS X
+// UNSUPPORTED: darwin
+
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
diff --git a/test/tsan/race_on_heap.cc b/test/tsan/race_on_heap.cc
index a66e0c4f93f7..6c2defc835a6 100644
--- a/test/tsan/race_on_heap.cc
+++ b/test/tsan/race_on_heap.cc
@@ -2,6 +2,7 @@
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
+#include "test.h"
void *Thread1(void *p) {
*(int*)p = 42;
@@ -26,7 +27,7 @@ int main() {
pthread_t t[2];
pthread_create(&t[0], 0, AllocThread, 0);
pthread_join(t[0], &p);
- fprintf(stderr, "addr=%p\n", p);
+ print_address("addr=", 1, p);
pthread_create(&t[0], 0, Thread1, (char*)p + 16);
pthread_create(&t[1], 0, Thread2, (char*)p + 16);
pthread_join(t[0], 0);
diff --git a/test/tsan/race_on_mutex.c b/test/tsan/race_on_mutex.c
index 7bd461bf3731..d998fdca2df3 100644
--- a/test/tsan/race_on_mutex.c
+++ b/test/tsan/race_on_mutex.c
@@ -1,4 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// This test fails on powerpc64 (VMA=46).
+// The size of the write reported by Tsan for T1 is 8 instead of 1.
+// XFAIL: powerpc64-unknown-linux-gnu
#include "test.h"
pthread_mutex_t Mtx;
@@ -35,7 +38,7 @@ int main() {
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK-NEXT: Atomic read of size 1 at {{.*}} by thread T2:
// CHECK-NEXT: #0 pthread_mutex_lock
-// CHECK-NEXT: #1 Thread2{{.*}} {{.*}}race_on_mutex.c:18{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #1 Thread2{{.*}} {{.*}}race_on_mutex.c:21{{(:3)?}} ({{.*}})
// CHECK: Previous write of size 1 at {{.*}} by thread T1:
// CHECK-NEXT: #0 pthread_mutex_init {{.*}} ({{.*}})
-// CHECK-NEXT: #1 Thread1{{.*}} {{.*}}race_on_mutex.c:8{{(:3)?}} ({{.*}})
+// CHECK-NEXT: #1 Thread1{{.*}} {{.*}}race_on_mutex.c:11{{(:3)?}} ({{.*}})
diff --git a/test/tsan/race_on_speculative_load.cc b/test/tsan/race_on_speculative_load.cc
index b50b69677d4b..dd40daeb5c19 100644
--- a/test/tsan/race_on_speculative_load.cc
+++ b/test/tsan/race_on_speculative_load.cc
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t | FileCheck %s
-// Regtest for https://code.google.com/p/thread-sanitizer/issues/detail?id=40
+// Regtest for https://github.com/google/sanitizers/issues/447
// This is a correct program and tsan should not report a race.
#include "test.h"
diff --git a/test/tsan/race_stress.cc b/test/tsan/race_stress.cc
new file mode 100644
index 000000000000..38acefce6e46
--- /dev/null
+++ b/test/tsan/race_stress.cc
@@ -0,0 +1,25 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+const int kThreads = 16;
+const int kIters = 1000;
+
+volatile int X = 0;
+
+void *thr(void *arg) {
+ for (int i = 0; i < kIters; i++)
+ X++;
+ return 0;
+}
+
+int main() {
+ pthread_t th[kThreads];
+ for (int i = 0; i < kThreads; i++)
+ pthread_create(&th[i], 0, thr, 0);
+ for (int i = 0; i < kThreads; i++)
+ pthread_join(th[i], 0);
+ fprintf(stderr, "DONE\n");
+}
+
+// CHECK: ThreadSanitizer: data race
+// CHECK: DONE
diff --git a/test/tsan/race_top_suppression.cc b/test/tsan/race_top_suppression.cc
index 7d42dbf3b4bf..bd5c1bd5f445 100644
--- a/test/tsan/race_top_suppression.cc
+++ b/test/tsan/race_top_suppression.cc
@@ -1,6 +1,6 @@
// RUN: echo "race_top:TopFunction" > %t.supp
// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%t.supp'" %run %t 2>&1 | FileCheck %s
+// RUN: %env_tsan_opts=suppressions='%t.supp' %run %t 2>&1 | FileCheck %s
// RUN: rm %t.supp
#include "test.h"
diff --git a/test/tsan/race_top_suppression1.cc b/test/tsan/race_top_suppression1.cc
index 881e661ba789..e34385a9b59c 100644
--- a/test/tsan/race_top_suppression1.cc
+++ b/test/tsan/race_top_suppression1.cc
@@ -1,6 +1,6 @@
// RUN: echo "race_top:TopFunction" > %t.supp
// RUN: %clangxx_tsan -O1 %s -o %t
-// RUN: TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%t.supp'" %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %env_tsan_opts=suppressions='%t.supp' %deflake %run %t 2>&1 | FileCheck %s
// RUN: rm %t.supp
#include "test.h"
diff --git a/test/tsan/real_deadlock_detector_stress_test.cc b/test/tsan/real_deadlock_detector_stress_test.cc
index 67c878f45084..feb1117e80ab 100644
--- a/test/tsan/real_deadlock_detector_stress_test.cc
+++ b/test/tsan/real_deadlock_detector_stress_test.cc
@@ -8,6 +8,7 @@
#include <errno.h>
#include <vector>
#include <algorithm>
+#include <sys/time.h>
const int kThreads = 4;
const int kMutexes = 16 << 10;
@@ -59,7 +60,7 @@ void *Thread(void *seed) {
for (;;) {
int old = __atomic_load_n(&m->state, __ATOMIC_RELAXED);
if (old == kStateLocked) {
- pthread_yield();
+ sched_yield();
continue;
}
int newv = old + 1;
@@ -165,9 +166,9 @@ void *Thread(void *seed) {
}
int main() {
- timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- unsigned s = (unsigned)ts.tv_nsec;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ unsigned s = tv.tv_sec + tv.tv_usec;
fprintf(stderr, "seed %d\n", s);
srand(s);
for (int i = 0; i < kMutexes; i++)
diff --git a/test/tsan/setuid2.c b/test/tsan/setuid2.c
index 67a6fd14dbcb..9dbb6577e1c6 100644
--- a/test/tsan/setuid2.c
+++ b/test/tsan/setuid2.c
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" %run %t 2>&1 | FileCheck %s
+// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=flush_memory_ms=1:memory_limit_mb=1 %run %t 2>&1 | FileCheck %s
#include "test.h"
#include <sys/types.h>
#include <unistd.h>
@@ -7,11 +7,11 @@
// Test that setuid call works in presence of stoptheworld.
int main() {
- struct timespec tp0, tp1;
- clock_gettime(CLOCK_MONOTONIC, &tp0);
- clock_gettime(CLOCK_MONOTONIC, &tp1);
- while (tp1.tv_sec - tp0.tv_sec < 3) {
- clock_gettime(CLOCK_MONOTONIC, &tp1);
+ unsigned long long tp0, tp1;
+ tp0 = monotonic_clock_ns();
+ tp1 = monotonic_clock_ns();
+ while (tp1 - tp0 < 3 * 1000000000ull) {
+ tp1 = monotonic_clock_ns();
setuid(0);
}
fprintf(stderr, "DONE\n");
diff --git a/test/tsan/signal_cond.cc b/test/tsan/signal_cond.cc
index f5eae745d407..beb2e0266e50 100644
--- a/test/tsan/signal_cond.cc
+++ b/test/tsan/signal_cond.cc
@@ -6,17 +6,16 @@
#include <semaphore.h>
// Test that signals can be delivered to blocked pthread_cond_wait.
-// https://code.google.com/p/thread-sanitizer/issues/detail?id=91
+// https://github.com/google/sanitizers/issues/498
int g_thread_run = 1;
pthread_mutex_t mutex;
pthread_cond_t cond;
-sem_t sem;
void sig_handler(int sig) {
(void)sig;
write(1, "SIGNAL\n", sizeof("SIGNAL\n") - 1);
- sem_post(&sem);
+ barrier_wait(&barrier);
}
void* my_thread(void* arg) {
@@ -28,7 +27,11 @@ void* my_thread(void* arg) {
}
int main() {
- sem_init(&sem, 0, 0);
+ barrier_init(&barrier, 2);
+
+ pthread_mutex_init(&mutex, 0);
+ pthread_cond_init(&cond, 0);
+
signal(SIGUSR1, &sig_handler);
pthread_t thr;
pthread_create(&thr, 0, &my_thread, 0);
@@ -36,8 +39,7 @@ int main() {
// (can't use barrier_wait for that)
sleep(1);
pthread_kill(thr, SIGUSR1);
- while (sem_wait(&sem) == -1 && errno == EINTR) {
- }
+ barrier_wait(&barrier);
pthread_mutex_lock(&mutex);
g_thread_run = 0;
pthread_cond_signal(&cond);
diff --git a/test/tsan/signal_errno.cc b/test/tsan/signal_errno.cc
index 8305e84930f3..e13e156fdf66 100644
--- a/test/tsan/signal_errno.cc
+++ b/test/tsan/signal_errno.cc
@@ -1,4 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// This test fails on powerpc64 BE (VMA=44), it does not appear to be
+// a functional problem, but the Tsan report is missing some info.
+// XFAIL: powerpc64-unknown-linux-gnu
+
#include "test.h"
#include <signal.h>
#include <sys/types.h>
@@ -24,7 +28,7 @@ static __attribute__((noinline)) void loop() {
volatile char *p = (char*)malloc(1);
p[0] = 0;
free((void*)p);
- pthread_yield();
+ sched_yield();
}
}
diff --git a/test/tsan/signal_longjmp.cc b/test/tsan/signal_longjmp.cc
index 2525c898887b..45e24626cbfa 100644
--- a/test/tsan/signal_longjmp.cc
+++ b/test/tsan/signal_longjmp.cc
@@ -1,10 +1,14 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
// Test case for longjumping out of signal handler:
-// https://code.google.com/p/thread-sanitizer/issues/detail?id=75
+// https://github.com/google/sanitizers/issues/482
// Longjmp assembly has not been implemented for mips64 yet
// XFAIL: mips64
+// This test fails on powerpc64 BE (VMA=44), a segmentation fault
+// error happens at the second assignment
+// "((volatile int *volatile)mem)[1] = 1".
+// XFAIL: powerpc64-unknown-linux-gnu
#include <setjmp.h>
#include <signal.h>
@@ -12,6 +16,12 @@
#include <stdio.h>
#include <sys/mman.h>
+#ifdef __APPLE__
+#define SIGNAL_TO_HANDLE SIGBUS
+#else
+#define SIGNAL_TO_HANDLE SIGSEGV
+#endif
+
sigjmp_buf fault_jmp;
volatile int fault_expected;
@@ -44,7 +54,7 @@ int main() {
exit(1);
}
- if (sigaction(SIGSEGV, &act, NULL)) {
+ if (sigaction(SIGNAL_TO_HANDLE, &act, NULL)) {
perror("sigaction");
exit(1);
}
diff --git a/test/tsan/signal_recursive.cc b/test/tsan/signal_recursive.cc
index 67fc9c0ec9a3..40be2d01502b 100644
--- a/test/tsan/signal_recursive.cc
+++ b/test/tsan/signal_recursive.cc
@@ -1,7 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
// Test case for recursive signal handlers, adopted from:
-// https://code.google.com/p/thread-sanitizer/issues/detail?id=71
+// https://github.com/google/sanitizers/issues/478
// REQUIRES: disabled
diff --git a/test/tsan/signal_reset.cc b/test/tsan/signal_reset.cc
index aec98dc399e9..82758d882382 100644
--- a/test/tsan/signal_reset.cc
+++ b/test/tsan/signal_reset.cc
@@ -1,4 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/tsan/signal_sync.cc b/test/tsan/signal_sync.cc
index 6ff19d3bd120..b529a1859f52 100644
--- a/test/tsan/signal_sync.cc
+++ b/test/tsan/signal_sync.cc
@@ -1,4 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
#include "test.h"
#include <signal.h>
#include <sys/types.h>
diff --git a/test/tsan/signal_thread.cc b/test/tsan/signal_thread.cc
index 8eda80a52264..aa91d1ddeb10 100644
--- a/test/tsan/signal_thread.cc
+++ b/test/tsan/signal_thread.cc
@@ -1,4 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/tsan/stack_sync_reuse.cc b/test/tsan/stack_sync_reuse.cc
index 5ea9e84b085a..d2bc5cb1b282 100644
--- a/test/tsan/stack_sync_reuse.cc
+++ b/test/tsan/stack_sync_reuse.cc
@@ -1,7 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "test.h"
-// Test case https://code.google.com/p/thread-sanitizer/issues/detail?id=87
+// Test case https://github.com/google/sanitizers/issues/494
// Tsan sees false HB edge on address pointed to by syncp variable.
// It is false because when acquire is done syncp points to a var in one frame,
// and during release it points to a var in a different frame.
@@ -31,7 +31,8 @@ void *Thread(void *x) {
}
void __attribute__((noinline)) foobar() {
- long s;
+ __attribute__((aligned(64))) long s;
+
addr = &s;
__atomic_store_n(&s, 0, __ATOMIC_RELAXED);
__atomic_store_n(&syncp, &s, __ATOMIC_RELEASE);
@@ -40,7 +41,8 @@ void __attribute__((noinline)) foobar() {
}
void __attribute__((noinline)) barfoo() {
- long s;
+ __attribute__((aligned(64))) long s;
+
if (addr != &s) {
printf("address mismatch addr=%p &s=%p\n", addr, &s);
exit(1);
diff --git a/test/tsan/suppressions_global.cc b/test/tsan/suppressions_global.cc
index c7b9bb99eb17..8928162cfb8a 100644
--- a/test/tsan/suppressions_global.cc
+++ b/test/tsan/suppressions_global.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
+// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
diff --git a/test/tsan/suppressions_race.cc b/test/tsan/suppressions_race.cc
index 45c30481f0cd..7a88434db820 100644
--- a/test/tsan/suppressions_race.cc
+++ b/test/tsan/suppressions_race.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
+// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s
#include "test.h"
int Global;
diff --git a/test/tsan/suppressions_race2.cc b/test/tsan/suppressions_race2.cc
index 24ecd8ef119f..b6566a80178d 100644
--- a/test/tsan/suppressions_race2.cc
+++ b/test/tsan/suppressions_race2.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
+// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=suppressions='%s.supp' %run %t 2>&1 | FileCheck %s
#include "test.h"
int Global;
diff --git a/test/tsan/test.h b/test/tsan/test.h
index 4e877f6d8dfd..a681daa32906 100644
--- a/test/tsan/test.h
+++ b/test/tsan/test.h
@@ -4,43 +4,66 @@
#include <unistd.h>
#include <dlfcn.h>
#include <stddef.h>
+#include <sched.h>
+#include <stdarg.h>
+
+#ifdef __APPLE__
+#include <mach/mach_time.h>
+#endif
// TSan-invisible barrier.
// Tests use it to establish necessary execution order in a way that does not
// interfere with tsan (does not establish synchronization between threads).
-__typeof(pthread_barrier_wait) *barrier_wait;
+typedef unsigned long long invisible_barrier_t;
-void barrier_init(pthread_barrier_t *barrier, unsigned count) {
-#if defined(__FreeBSD__)
- static const char libpthread_name[] = "libpthread.so";
-#else
- static const char libpthread_name[] = "libpthread.so.0";
+#ifdef __cplusplus
+extern "C" {
+#endif
+void __tsan_testonly_barrier_init(invisible_barrier_t *barrier,
+ unsigned count);
+void __tsan_testonly_barrier_wait(invisible_barrier_t *barrier);
+#ifdef __cplusplus
+}
#endif
- if (barrier_wait == 0) {
- void *h = dlopen(libpthread_name, RTLD_LAZY);
- if (h == 0) {
- fprintf(stderr, "failed to dlopen %s, exiting\n", libpthread_name);
- exit(1);
- }
- barrier_wait = (__typeof(barrier_wait))dlsym(h, "pthread_barrier_wait");
- if (barrier_wait == 0) {
- fprintf(stderr, "failed to resolve pthread_barrier_wait, exiting\n");
- exit(1);
- }
- }
- pthread_barrier_init(barrier, 0, count);
+static inline void barrier_init(invisible_barrier_t *barrier, unsigned count) {
+ __tsan_testonly_barrier_init(barrier, count);
+}
+
+static inline void barrier_wait(invisible_barrier_t *barrier) {
+ __tsan_testonly_barrier_wait(barrier);
}
// Default instance of the barrier, but a test can declare more manually.
-pthread_barrier_t barrier;
+invisible_barrier_t barrier;
-void print_address(void *address) {
-// On FreeBSD, the %p conversion specifier works as 0x%x and thus does not match
-// to the format used in the diagnotic message.
-#ifdef __x86_64__
- fprintf(stderr, "0x%012lx", (unsigned long) address);
+void print_address(const char *str, int n, ...) {
+ fprintf(stderr, "%s", str);
+ va_list ap;
+ va_start(ap, n);
+ while (n--) {
+ void *p = va_arg(ap, void *);
+#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__)
+ // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not
+ // match to the format used in the diagnotic message.
+ fprintf(stderr, "0x%012lx ", (unsigned long) p);
#elif defined(__mips64)
- fprintf(stderr, "0x%010lx", (unsigned long) address);
+ fprintf(stderr, "0x%010lx ", (unsigned long) p);
#endif
+ }
+ fprintf(stderr, "\n");
+}
+
+#ifdef __APPLE__
+unsigned long long monotonic_clock_ns() {
+ static mach_timebase_info_data_t timebase_info;
+ if (timebase_info.denom == 0) mach_timebase_info(&timebase_info);
+ return (mach_absolute_time() * timebase_info.numer) / timebase_info.denom;
}
+#else
+unsigned long long monotonic_clock_ns() {
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return (unsigned long long)t.tv_sec * 1000000000ull + t.tv_nsec;
+}
+#endif
diff --git a/test/tsan/test_output.sh b/test/tsan/test_output.sh
deleted file mode 100755
index bce0fe8b5511..000000000000
--- a/test/tsan/test_output.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/bash
-
-ulimit -s 8192
-set -e # fail on any error
-
-HERE=$(dirname $0)
-TSAN_DIR=$(dirname $0)/../../lib/tsan
-
-# Assume clang and clang++ are in path.
-: ${CC:=clang}
-: ${CXX:=clang++}
-: ${FILECHECK:=FileCheck}
-
-# TODO: add testing for all of -O0...-O3
-CFLAGS="-fsanitize=thread -O2 -g -Wall"
-LDFLAGS="-pthread -ldl -lrt -lm -Wl,--whole-archive $TSAN_DIR/rtl/libtsan.a -Wl,--no-whole-archive"
-
-test_file() {
- SRC=$1
- COMPILER=$2
- echo ----- TESTING $(basename $1)
- OBJ=$SRC.o
- EXE=$SRC.exe
- $COMPILER $SRC $CFLAGS -c -o $OBJ
- $COMPILER $OBJ $LDFLAGS -o $EXE
- RES=$($EXE 2>&1 || true)
- printf "%s\n" "$RES" | $FILECHECK $SRC
- if [ "$3" == "" ]; then
- rm -f $EXE $OBJ
- fi
-}
-
-if [ "$1" == "" ]; then
- for c in $HERE/*.{c,cc}; do
- if [[ $c == */failing_* ]]; then
- echo SKIPPING FAILING TEST $c
- continue
- fi
- if [[ $c == */load_shared_lib.cc ]]; then
- echo TEST $c is not supported
- continue
- fi
- if [[ $c == */*blacklist*.cc ]]; then
- echo TEST $c is not supported
- continue
- fi
- if [ "`grep "TSAN_OPTIONS" $c`" ]; then
- echo SKIPPING $c -- requires TSAN_OPTIONS
- continue
- fi
- if [ "`grep "XFAIL" $c`" ]; then
- echo SKIPPING $c -- has XFAIL
- continue
- fi
- COMPILER=$CXX
- case $c in
- *.c) COMPILER=$CC
- esac
- test_file $c $COMPILER &
- done
- for job in `jobs -p`; do
- wait $job || exit 1
- done
-else
- test_file $HERE/$1 $CXX "DUMP"
-fi
diff --git a/test/tsan/thread_name2.cc b/test/tsan/thread_name2.cc
index a44f4b9d3247..d7ed0f0d1952 100644
--- a/test/tsan/thread_name2.cc
+++ b/test/tsan/thread_name2.cc
@@ -1,12 +1,15 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include "test.h"
+// OS X doesn't have pthread_setname_np(tid, name).
+// UNSUPPORTED: darwin
+
#if defined(__FreeBSD__)
#include <pthread_np.h>
#define pthread_setname_np pthread_set_name_np
#endif
-int Global;
+long long Global;
void *Thread1(void *x) {
barrier_wait(&barrier);
diff --git a/test/tsan/tls_race.cc b/test/tsan/tls_race.cc
index 5e8172276708..b43a514cc8aa 100644
--- a/test/tsan/tls_race.cc
+++ b/test/tsan/tls_race.cc
@@ -1,4 +1,4 @@
-// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK
#include "test.h"
void *Thread(void *a) {
@@ -18,4 +18,6 @@ int main() {
}
// CHECK: WARNING: ThreadSanitizer: data race
-// CHECK: Location is TLS of main thread.
+// CHECK-Linux: Location is TLS of main thread.
+// CHECK-FreeBSD: Location is TLS of main thread.
+// CHECK-Darwin: Location is heap block of size 4
diff --git a/test/tsan/tls_race2.cc b/test/tsan/tls_race2.cc
index d0f7b03e09a1..b04ff6788100 100644
--- a/test/tsan/tls_race2.cc
+++ b/test/tsan/tls_race2.cc
@@ -1,4 +1,4 @@
-// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK
#include "test.h"
void *Thread2(void *a) {
@@ -25,5 +25,6 @@ int main() {
}
// CHECK: WARNING: ThreadSanitizer: data race
-// CHECK: Location is TLS of thread T1.
-
+// CHECK-Linux: Location is TLS of thread T1.
+// CHECK-FreeBSD: Location is TLS of thread T1.
+// CHECK-Darwin: Location is heap block of size 4
diff --git a/test/tsan/vfork.cc b/test/tsan/vfork.cc
index 5ae1dd1ababd..98a82623ee65 100644
--- a/test/tsan/vfork.cc
+++ b/test/tsan/vfork.cc
@@ -1,4 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: darwin
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/tsan/virtual_inheritance_compile_bug.cc b/test/tsan/virtual_inheritance_compile_bug.cc
index 2a50c2e88d01..7da581d80601 100644
--- a/test/tsan/virtual_inheritance_compile_bug.cc
+++ b/test/tsan/virtual_inheritance_compile_bug.cc
@@ -1,4 +1,4 @@
-// Regression test for http://code.google.com/p/thread-sanitizer/issues/detail?id=3.
+// Regression test for https://github.com/google/sanitizers/issues/410.
// The C++ variant is much more compact that the LLVM IR equivalent.
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
diff --git a/test/tsan/vptr_benign_race.cc b/test/tsan/vptr_benign_race.cc
index 92a2b326e717..c0068955129f 100644
--- a/test/tsan/vptr_benign_race.cc
+++ b/test/tsan/vptr_benign_race.cc
@@ -1,28 +1,36 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
-#include <semaphore.h>
#include <stdio.h>
struct A {
A() {
- sem_init(&sem_, 0, 0);
+ pthread_mutex_init(&m, 0);
+ pthread_cond_init(&c, 0);
+ signaled = false;
}
virtual void F() {
}
void Done() {
- sem_post(&sem_);
+ pthread_mutex_lock(&m);
+ signaled = true;
+ pthread_cond_signal(&c);
+ pthread_mutex_unlock(&m);
}
virtual ~A() {
}
- sem_t sem_;
+ pthread_mutex_t m;
+ pthread_cond_t c;
+ bool signaled;
};
struct B : A {
virtual void F() {
}
virtual ~B() {
- sem_wait(&sem_);
- sem_destroy(&sem_);
+ pthread_mutex_lock(&m);
+ while (!signaled)
+ pthread_cond_wait(&c, &m);
+ pthread_mutex_unlock(&m);
}
};