diff options
Diffstat (limited to 'test/tsan/Darwin')
54 files changed, 432 insertions, 52 deletions
diff --git a/test/tsan/Darwin/debug_external.cc b/test/tsan/Darwin/debug_external.cc new file mode 100644 index 000000000000..217690fc5dd0 --- /dev/null +++ b/test/tsan/Darwin/debug_external.cc @@ -0,0 +1,66 @@ +// RUN: %clangxx_tsan -O1 %s -o %t +// RUN: %deflake %run %t 2>&1 | FileCheck %s + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../test.h" + +extern "C" { +void __tsan_on_report(void *report); +int __tsan_get_report_loc(void *report, unsigned long idx, const char **type, + void **addr, void **start, + unsigned long *size, int *tid, int *fd, + int *suppressable, void **trace, + unsigned long trace_size); +int __tsan_get_report_loc_object_type(void *report, unsigned long idx, + const char **object_type); +void *__tsan_external_register_tag(const char *object_type); +void __tsan_external_assign_tag(void *addr, void *tag); +} + +void *Thread(void *arg) { + barrier_wait(&barrier); + *((long *)arg) = 42; + return NULL; +} + +int main() { + barrier_init(&barrier, 2); + void *tag = __tsan_external_register_tag("MyObject"); + long *obj = (long *)malloc(sizeof(long)); + fprintf(stderr, "obj = %p\n", obj); + // CHECK: obj = [[ADDR:0x[0-9a-f]+]] + __tsan_external_assign_tag(obj, tag); + + pthread_t t; + pthread_create(&t, 0, Thread, obj); + *obj = 41; + barrier_wait(&barrier); + pthread_join(t, 0); + fprintf(stderr, "Done.\n"); + return 0; +} + +void __tsan_on_report(void *report) { + const char *type; + void *addr; + void *start; + unsigned long size; + int tid, fd, suppressable; + void *trace[16] = {0}; + __tsan_get_report_loc(report, 0, &type, &addr, &start, &size, &tid, &fd, + &suppressable, trace, 16); + fprintf(stderr, "type = %s, start = %p, size = %ld\n", type, start, size); + // CHECK: type = heap, start = [[ADDR]], size = 8 + + const char *object_type; + __tsan_get_report_loc_object_type(report, 0, &object_type); + fprintf(stderr, "object_type = %s\n", object_type); + // CHECK: object_type = MyObject +} + +// CHECK: Done. +// CHECK: ThreadSanitizer: reported 1 warnings diff --git a/test/tsan/Darwin/dispatch_main.mm b/test/tsan/Darwin/dispatch_main.mm index 75887547c606..f4c1e44bc6b1 100644 --- a/test/tsan/Darwin/dispatch_main.mm +++ b/test/tsan/Darwin/dispatch_main.mm @@ -2,7 +2,7 @@ // quits the main thread. // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/dispatch_once_deadlock.mm b/test/tsan/Darwin/dispatch_once_deadlock.mm index e88cdc0d0da5..e109f64a8dcb 100644 --- a/test/tsan/Darwin/dispatch_once_deadlock.mm +++ b/test/tsan/Darwin/dispatch_once_deadlock.mm @@ -1,7 +1,7 @@ // Check that calling dispatch_once from a report callback works. // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 not %run %t 2>&1 | FileCheck %s +// RUN: not %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> #import <pthread.h> diff --git a/test/tsan/Darwin/external.cc b/test/tsan/Darwin/external.cc new file mode 100644 index 000000000000..2605480d7b82 --- /dev/null +++ b/test/tsan/Darwin/external.cc @@ -0,0 +1,163 @@ +// RUN: %clangxx_tsan %s -shared -DSHARED_LIB \ +// RUN: -o %t-lib-instrumented.dylib \ +// RUN: -install_name @rpath/`basename %t-lib-instrumented.dylib` + +// RUN: %clangxx_tsan %s -shared -DSHARED_LIB -fno-sanitize=thread \ +// RUN: -o %t-lib-noninstrumented.dylib \ +// RUN: -install_name @rpath/`basename %t-lib-noninstrumented.dylib` + +// RUN: %clangxx_tsan %s -shared -DSHARED_LIB -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \ +// RUN: -o %t-lib-noninstrumented-callbacks.dylib \ +// RUN: -install_name @rpath/`basename %t-lib-noninstrumented-callbacks.dylib` + +// RUN: %clangxx_tsan %s %t-lib-instrumented.dylib -o %t-lib-instrumented +// RUN: %clangxx_tsan %s %t-lib-noninstrumented.dylib -o %t-lib-noninstrumented +// RUN: %clangxx_tsan %s %t-lib-noninstrumented-callbacks.dylib -o %t-lib-noninstrumented-callbacks + +// RUN: %deflake %run %t-lib-instrumented 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST1 +// RUN: %run %t-lib-noninstrumented 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST2 +// RUN: %deflake %run %t-lib-noninstrumented-callbacks 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST3 + +#include <thread> + +#include <dlfcn.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +struct MyObject; +typedef MyObject *MyObjectRef; +extern "C" { + void InitializeLibrary(); + MyObject *ObjectCreate(); + long ObjectRead(MyObject *); + void ObjectWrite(MyObject *, long); + void ObjectWriteAnother(MyObject *, long); +} + +#if defined(SHARED_LIB) + +struct MyObject { + long _val; + long _another; +}; + +#if defined(USE_TSAN_CALLBACKS) +static void *tag; +void *(*callback_register_tag)(const char *object_type); +void *(*callback_assign_tag)(void *addr, void *tag); +void (*callback_read)(void *addr, void *caller_pc, void *tag); +void (*callback_write)(void *addr, void *caller_pc, void *tag); +#endif + +void InitializeLibrary() { +#if defined(USE_TSAN_CALLBACKS) + callback_register_tag = (decltype(callback_register_tag))dlsym(RTLD_DEFAULT, "__tsan_external_register_tag"); + callback_assign_tag = (decltype(callback_assign_tag))dlsym(RTLD_DEFAULT, "__tsan_external_assign_tag"); + callback_read = (decltype(callback_read))dlsym(RTLD_DEFAULT, "__tsan_external_read"); + callback_write = (decltype(callback_write))dlsym(RTLD_DEFAULT, "__tsan_external_write"); + tag = callback_register_tag("MyLibrary::MyObject"); +#endif +} + +MyObject *ObjectCreate() { + MyObject *ref = (MyObject *)malloc(sizeof(MyObject)); +#if defined(USE_TSAN_CALLBACKS) + callback_assign_tag(ref, tag); +#endif + return ref; +} + +long ObjectRead(MyObject *ref) { +#if defined(USE_TSAN_CALLBACKS) + callback_read(ref, __builtin_return_address(0), tag); +#endif + return ref->_val; +} + +void ObjectWrite(MyObject *ref, long val) { +#if defined(USE_TSAN_CALLBACKS) + callback_write(ref, __builtin_return_address(0), tag); +#endif + ref->_val = val; +} + +void ObjectWriteAnother(MyObject *ref, long val) { +#if defined(USE_TSAN_CALLBACKS) + callback_write(ref, __builtin_return_address(0), tag); +#endif + ref->_another = val; +} + +#else // defined(SHARED_LIB) + +int main(int argc, char *argv[]) { + InitializeLibrary(); + + { + MyObjectRef ref = ObjectCreate(); + std::thread t1([ref]{ ObjectRead(ref); }); + std::thread t2([ref]{ ObjectRead(ref); }); + t1.join(); + t2.join(); + } + + // CHECK-NOT: WARNING: ThreadSanitizer + + fprintf(stderr, "RR test done\n"); + // CHECK: RR test done + + { + MyObjectRef ref = ObjectCreate(); + std::thread t1([ref]{ ObjectRead(ref); }); + std::thread t2([ref]{ ObjectWrite(ref, 66); }); + t1.join(); + t2.join(); + } + + // TEST1: WARNING: ThreadSanitizer: data race + // TEST1: {{Write|Read}} of size 8 at + // TEST1: Previous {{write|read}} of size 8 at + // TEST1: Location is heap block of size 16 at + + // TEST2-NOT: WARNING: ThreadSanitizer + + // TEST3: WARNING: ThreadSanitizer: race on a library object + // TEST3: {{Mutating|read-only}} access of object MyLibrary::MyObject at + // TEST3: {{ObjectWrite|ObjectRead}} + // TEST3: Previous {{mutating|read-only}} access of object MyLibrary::MyObject at + // TEST3: {{ObjectWrite|ObjectRead}} + // TEST3: Location is MyLibrary::MyObject object of size 16 at + // TEST3: {{ObjectCreate}} + + fprintf(stderr, "RW test done\n"); + // CHECK: RW test done + + { + MyObjectRef ref = ObjectCreate(); + std::thread t1([ref]{ ObjectWrite(ref, 76); }); + std::thread t2([ref]{ ObjectWriteAnother(ref, 77); }); + t1.join(); + t2.join(); + } + + // TEST1-NOT: WARNING: ThreadSanitizer: data race + + // TEST2-NOT: WARNING: ThreadSanitizer + + // TEST3: WARNING: ThreadSanitizer: race on a library object + // TEST3: Mutating access of object MyLibrary::MyObject at + // TEST3: {{ObjectWrite|ObjectWriteAnother}} + // TEST3: Previous mutating access of object MyLibrary::MyObject at + // TEST3: {{ObjectWrite|ObjectWriteAnother}} + // TEST3: Location is MyLibrary::MyObject object of size 16 at + // TEST3: {{ObjectCreate}} + + fprintf(stderr, "WW test done\n"); + // CHECK: WW test done +} + +#endif // defined(SHARED_LIB) diff --git a/test/tsan/Darwin/gcd-after-null.mm b/test/tsan/Darwin/gcd-after-null.mm new file mode 100644 index 000000000000..7c9913c0fb17 --- /dev/null +++ b/test/tsan/Darwin/gcd-after-null.mm @@ -0,0 +1,23 @@ +// Regression test to make sure we don't crash when dispatch_after is called with a NULL queue. + +// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %run %t 2>&1 | FileCheck %s + +#import <Foundation/Foundation.h> + +int main(int argc, const char *argv[]) { + fprintf(stderr, "start\n"); + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_MSEC)), NULL, ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + CFRunLoopStop(CFRunLoopGetMain()); + }); + }); + CFRunLoopRun(); + + fprintf(stderr, "done\n"); + return 0; +} + +// CHECK: start +// CHECK: done diff --git a/test/tsan/Darwin/gcd-after.mm b/test/tsan/Darwin/gcd-after.mm index 49b6bc6f71e9..4d66c508554a 100644 --- a/test/tsan/Darwin/gcd-after.mm +++ b/test/tsan/Darwin/gcd-after.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-apply-race.mm b/test/tsan/Darwin/gcd-apply-race.mm index 028be1ac5b1c..a7bf663a9fe2 100644 --- a/test/tsan/Darwin/gcd-apply-race.mm +++ b/test/tsan/Darwin/gcd-apply-race.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s +// RUN: %deflake %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-apply.mm b/test/tsan/Darwin/gcd-apply.mm index a7dc3740dc7b..d9d256203aeb 100644 --- a/test/tsan/Darwin/gcd-apply.mm +++ b/test/tsan/Darwin/gcd-apply.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-async-norace.mm b/test/tsan/Darwin/gcd-async-norace.mm index c7e28b4ce791..83f8c0d6fb58 100644 --- a/test/tsan/Darwin/gcd-async-norace.mm +++ b/test/tsan/Darwin/gcd-async-norace.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-async-race.mm b/test/tsan/Darwin/gcd-async-race.mm index 1002a56b0a16..cb8fb4bf5eca 100644 --- a/test/tsan/Darwin/gcd-async-race.mm +++ b/test/tsan/Darwin/gcd-async-race.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s +// RUN: %deflake %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-barrier-race.mm b/test/tsan/Darwin/gcd-barrier-race.mm index c42eaebded2b..c11e147ff7cd 100644 --- a/test/tsan/Darwin/gcd-barrier-race.mm +++ b/test/tsan/Darwin/gcd-barrier-race.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s +// RUN: %deflake %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-barrier.mm b/test/tsan/Darwin/gcd-barrier.mm index 6f58cae7d8f5..9d4dcb215027 100644 --- a/test/tsan/Darwin/gcd-barrier.mm +++ b/test/tsan/Darwin/gcd-barrier.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-blocks.mm b/test/tsan/Darwin/gcd-blocks.mm index e0082605f24e..1aac7e1f2ef6 100644 --- a/test/tsan/Darwin/gcd-blocks.mm +++ b/test/tsan/Darwin/gcd-blocks.mm @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-data.mm b/test/tsan/Darwin/gcd-data.mm index a5154dc3598d..d451cf5e8efa 100644 --- a/test/tsan/Darwin/gcd-data.mm +++ b/test/tsan/Darwin/gcd-data.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-fd.mm b/test/tsan/Darwin/gcd-fd.mm index 75da9cd4252d..838cf20ca98b 100644 --- a/test/tsan/Darwin/gcd-fd.mm +++ b/test/tsan/Darwin/gcd-fd.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-groups-destructor.mm b/test/tsan/Darwin/gcd-groups-destructor.mm index 19c2c9bd147f..05c65c04b665 100644 --- a/test/tsan/Darwin/gcd-groups-destructor.mm +++ b/test/tsan/Darwin/gcd-groups-destructor.mm @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-groups-leave.mm b/test/tsan/Darwin/gcd-groups-leave.mm index 6ecf85f5ff0d..49fd8e2101c8 100644 --- a/test/tsan/Darwin/gcd-groups-leave.mm +++ b/test/tsan/Darwin/gcd-groups-leave.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-groups-norace.mm b/test/tsan/Darwin/gcd-groups-norace.mm index 64ec386ca40f..e8501692fe80 100644 --- a/test/tsan/Darwin/gcd-groups-norace.mm +++ b/test/tsan/Darwin/gcd-groups-norace.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-groups-stress.mm b/test/tsan/Darwin/gcd-groups-stress.mm index 457d9afd9c93..cfe4deb0a518 100644 --- a/test/tsan/Darwin/gcd-groups-stress.mm +++ b/test/tsan/Darwin/gcd-groups-stress.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-io-barrier-race.mm b/test/tsan/Darwin/gcd-io-barrier-race.mm index fffc19bd16de..137c3b26700c 100644 --- a/test/tsan/Darwin/gcd-io-barrier-race.mm +++ b/test/tsan/Darwin/gcd-io-barrier-race.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s +// RUN: %deflake %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-io-barrier.mm b/test/tsan/Darwin/gcd-io-barrier.mm index fe30138f6036..af92b03c1c70 100644 --- a/test/tsan/Darwin/gcd-io-barrier.mm +++ b/test/tsan/Darwin/gcd-io-barrier.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-io-cleanup.mm b/test/tsan/Darwin/gcd-io-cleanup.mm index b15fa0dc2532..570e37dd04cd 100644 --- a/test/tsan/Darwin/gcd-io-cleanup.mm +++ b/test/tsan/Darwin/gcd-io-cleanup.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-io-race.mm b/test/tsan/Darwin/gcd-io-race.mm index 0bec28fdb758..99000fca1587 100644 --- a/test/tsan/Darwin/gcd-io-race.mm +++ b/test/tsan/Darwin/gcd-io-race.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s +// RUN: %deflake %run %t 2>&1 | FileCheck %s // REQUIRES: disabled diff --git a/test/tsan/Darwin/gcd-io.mm b/test/tsan/Darwin/gcd-io.mm index 4a1726dac8c7..70ded40417d7 100644 --- a/test/tsan/Darwin/gcd-io.mm +++ b/test/tsan/Darwin/gcd-io.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-once.mm b/test/tsan/Darwin/gcd-once.mm index 3e4a5335607c..70e588aaf711 100644 --- a/test/tsan/Darwin/gcd-once.mm +++ b/test/tsan/Darwin/gcd-once.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-semaphore-norace.mm b/test/tsan/Darwin/gcd-semaphore-norace.mm index 20bc5724d165..fd5d14655182 100644 --- a/test/tsan/Darwin/gcd-semaphore-norace.mm +++ b/test/tsan/Darwin/gcd-semaphore-norace.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-serial-queue-norace.mm b/test/tsan/Darwin/gcd-serial-queue-norace.mm index 95efbb764c53..8754b618df2a 100644 --- a/test/tsan/Darwin/gcd-serial-queue-norace.mm +++ b/test/tsan/Darwin/gcd-serial-queue-norace.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-source-cancel.mm b/test/tsan/Darwin/gcd-source-cancel.mm index 86e1b28a61c4..8aa6f106932f 100644 --- a/test/tsan/Darwin/gcd-source-cancel.mm +++ b/test/tsan/Darwin/gcd-source-cancel.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-source-cancel2.mm b/test/tsan/Darwin/gcd-source-cancel2.mm index 956fe87298bb..92b31d7d0dab 100644 --- a/test/tsan/Darwin/gcd-source-cancel2.mm +++ b/test/tsan/Darwin/gcd-source-cancel2.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-source-event.mm b/test/tsan/Darwin/gcd-source-event.mm index e50cb568de1e..e707b6551000 100644 --- a/test/tsan/Darwin/gcd-source-event.mm +++ b/test/tsan/Darwin/gcd-source-event.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-source-event2.mm b/test/tsan/Darwin/gcd-source-event2.mm index c45d481a0028..b10e4741a3f6 100644 --- a/test/tsan/Darwin/gcd-source-event2.mm +++ b/test/tsan/Darwin/gcd-source-event2.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-source-registration.mm b/test/tsan/Darwin/gcd-source-registration.mm index db22613eddae..d6d339f94dbb 100644 --- a/test/tsan/Darwin/gcd-source-registration.mm +++ b/test/tsan/Darwin/gcd-source-registration.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-source-registration2.mm b/test/tsan/Darwin/gcd-source-registration2.mm index 4431bc9d6898..63657873cae3 100644 --- a/test/tsan/Darwin/gcd-source-registration2.mm +++ b/test/tsan/Darwin/gcd-source-registration2.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-source-serial.mm b/test/tsan/Darwin/gcd-source-serial.mm index c0989fcc732a..992203074c15 100644 --- a/test/tsan/Darwin/gcd-source-serial.mm +++ b/test/tsan/Darwin/gcd-source-serial.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-suspend.mm b/test/tsan/Darwin/gcd-suspend.mm index 3e8818a2d56e..561e7c0b79c8 100644 --- a/test/tsan/Darwin/gcd-suspend.mm +++ b/test/tsan/Darwin/gcd-suspend.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-sync-norace.mm b/test/tsan/Darwin/gcd-sync-norace.mm index c683524f73b6..18bf97320793 100644 --- a/test/tsan/Darwin/gcd-sync-norace.mm +++ b/test/tsan/Darwin/gcd-sync-norace.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-sync-race.mm b/test/tsan/Darwin/gcd-sync-race.mm index 650faa4e082c..b7f3266dc09b 100644 --- a/test/tsan/Darwin/gcd-sync-race.mm +++ b/test/tsan/Darwin/gcd-sync-race.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s +// RUN: %deflake %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/gcd-target-queue-norace.mm b/test/tsan/Darwin/gcd-target-queue-norace.mm index 36cb1b9298de..fbfa65806bdb 100644 --- a/test/tsan/Darwin/gcd-target-queue-norace.mm +++ b/test/tsan/Darwin/gcd-target-queue-norace.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/ignore-noninstrumented.mm b/test/tsan/Darwin/ignore-noninstrumented.mm index 5e4453102a9c..528e07b9a721 100644 --- a/test/tsan/Darwin/ignore-noninstrumented.mm +++ b/test/tsan/Darwin/ignore-noninstrumented.mm @@ -3,7 +3,7 @@ // RUN: %clang_tsan %s -o %t -framework Foundation // Check that without the flag, there are false positives. -// RUN: %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE +// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0 %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE // With ignore_noninstrumented_modules=1, no races are reported. // RUN: %env_tsan_opts=ignore_noninstrumented_modules=1 %run %t 2>&1 | FileCheck %s diff --git a/test/tsan/Darwin/ignored-interceptors.mm b/test/tsan/Darwin/ignored-interceptors.mm index d51314281844..1105132a3cb6 100644 --- a/test/tsan/Darwin/ignored-interceptors.mm +++ b/test/tsan/Darwin/ignored-interceptors.mm @@ -6,13 +6,13 @@ // RUN: %clang_tsan %s -o %t -framework Foundation // Check that without the flag, there are false positives. -// RUN: %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE +// 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_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// 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_interceptors_accesses=1 %deflake %run %t race 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RACE +// 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> diff --git a/test/tsan/Darwin/libcxx-call-once.mm b/test/tsan/Darwin/libcxx-call-once.mm index 5388e495c9c2..ba4615fa3ab9 100644 --- a/test/tsan/Darwin/libcxx-call-once.mm +++ b/test/tsan/Darwin/libcxx-call-once.mm @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -framework Foundation -std=c++11 -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/libcxx-future.mm b/test/tsan/Darwin/libcxx-future.mm index 902f267ecb89..720c2e089b47 100644 --- a/test/tsan/Darwin/libcxx-future.mm +++ b/test/tsan/Darwin/libcxx-future.mm @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #include <iostream> #include <future> diff --git a/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm b/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm index eea02dc561e1..a9a3a96f2ada 100644 --- a/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm +++ b/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/libcxx-shared-ptr-stress.mm b/test/tsan/Darwin/libcxx-shared-ptr-stress.mm index 7c36729f010f..e5cd7edc6bb7 100644 --- a/test/tsan/Darwin/libcxx-shared-ptr-stress.mm +++ b/test/tsan/Darwin/libcxx-shared-ptr-stress.mm @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/libcxx-shared-ptr.mm b/test/tsan/Darwin/libcxx-shared-ptr.mm index 6187c438fec0..057ff22874c9 100644 --- a/test/tsan/Darwin/libcxx-shared-ptr.mm +++ b/test/tsan/Darwin/libcxx-shared-ptr.mm @@ -1,5 +1,5 @@ // RUN: %clangxx_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/lit.local.cfg b/test/tsan/Darwin/lit.local.cfg index a85dfcd24c08..e74e82dbf474 100644 --- a/test/tsan/Darwin/lit.local.cfg +++ b/test/tsan/Darwin/lit.local.cfg @@ -7,3 +7,5 @@ root = getRoot(config) if root.host_os not in ['Darwin']: config.unsupported = True + +config.environment['TSAN_OPTIONS'] += ':ignore_noninstrumented_modules=1' diff --git a/test/tsan/Darwin/main_tid.mm b/test/tsan/Darwin/main_tid.mm new file mode 100644 index 000000000000..af658e4b96e5 --- /dev/null +++ b/test/tsan/Darwin/main_tid.mm @@ -0,0 +1,46 @@ +// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %deflake %run %t 2>&1 | FileCheck %s + +#import <pthread.h> +#import <stdio.h> +#import <stdlib.h> + +extern "C" { +void __tsan_on_report(void *report); +int __tsan_get_report_thread(void *report, unsigned long idx, int *tid, + unsigned long *os_id, int *running, + const char **name, int *parent_tid, void **trace, + unsigned long trace_size); +} + +void __tsan_on_report(void *report) { + fprintf(stderr, "__tsan_on_report(%p)\n", report); + + int tid; + unsigned long os_id; + int running; + const char *name; + int parent_tid; + void *trace[16] = {0}; + __tsan_get_report_thread(report, 0, &tid, &os_id, &running, &name, &parent_tid, trace, 16); + fprintf(stderr, "tid = %d, os_id = %lu\n", tid, os_id); +} + +int main() { + fprintf(stderr, "Hello world.\n"); + + uint64_t threadid; + pthread_threadid_np(NULL, &threadid); + fprintf(stderr, "pthread_threadid_np = %llu\n", threadid); + + pthread_mutex_t m; + pthread_mutex_init(&m, NULL); + pthread_mutex_unlock(&m); + fprintf(stderr, "Done.\n"); +} + +// CHECK: Hello world. +// CHECK: pthread_threadid_np = [[ADDR:[0-9]+]] +// CHECK: WARNING: ThreadSanitizer +// CHECK: tid = 0, os_id = [[ADDR]] +// CHECK: Done. diff --git a/test/tsan/Darwin/norace-objcxx-run-time.mm b/test/tsan/Darwin/norace-objcxx-run-time.mm index 0cf729e7f2d8..1de431a076c7 100644 --- a/test/tsan/Darwin/norace-objcxx-run-time.mm +++ b/test/tsan/Darwin/norace-objcxx-run-time.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -lc++ -fobjc-arc -lobjc -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s // Check that we do not report races between: // - Object retain and initialize diff --git a/test/tsan/Darwin/objc-double-property.mm b/test/tsan/Darwin/objc-double-property.mm index 51b10f21c9ca..c99151d28048 100644 --- a/test/tsan/Darwin/objc-double-property.mm +++ b/test/tsan/Darwin/objc-double-property.mm @@ -1,7 +1,7 @@ -// RUN: %clangxx_tsan -O0 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_tsan -O1 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_tsan -O2 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_tsan -O3 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O0 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O1 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O2 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_tsan -O3 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/objc-simple.mm b/test/tsan/Darwin/objc-simple.mm index a8fc35592962..b62d0eb8702d 100644 --- a/test/tsan/Darwin/objc-simple.mm +++ b/test/tsan/Darwin/objc-simple.mm @@ -1,7 +1,7 @@ // Test that a simple Obj-C program runs and exits without any warnings. // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> diff --git a/test/tsan/Darwin/workerthreads.mm b/test/tsan/Darwin/workerthreads.mm new file mode 100644 index 000000000000..18369fd62dd3 --- /dev/null +++ b/test/tsan/Darwin/workerthreads.mm @@ -0,0 +1,43 @@ +// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %deflake %run %t 2>&1 | FileCheck %s + +#import <Foundation/Foundation.h> + +#import "../test.h" + +long global; + +int main() { + fprintf(stderr, "Hello world.\n"); + print_address("addr=", 1, &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(); + fprintf(stderr, "Done.\n"); +} + +// CHECK: Hello world. +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: Write of size 8 +// CHECK: Previous write of size 8 +// CHECK: Location is global +// CHECK: Thread {{.*}} is a GCD worker thread +// CHECK-NOT: failed to restore the stack +// CHECK: Thread {{.*}} is a GCD worker thread +// CHECK-NOT: failed to restore the stack +// CHECK: Done. diff --git a/test/tsan/Darwin/xpc-cancel.mm b/test/tsan/Darwin/xpc-cancel.mm new file mode 100644 index 000000000000..5e326b7e4973 --- /dev/null +++ b/test/tsan/Darwin/xpc-cancel.mm @@ -0,0 +1,37 @@ +// RUN: %clang_tsan %s -o %t -framework Foundation +// RUN: %run %t 2>&1 | FileCheck %s + +#import <Foundation/Foundation.h> +#import <xpc/xpc.h> + +long global; + +int main(int argc, const char *argv[]) { + fprintf(stderr, "Hello world.\n"); + + dispatch_queue_t server_q = dispatch_queue_create("server.queue", DISPATCH_QUEUE_CONCURRENT); + xpc_connection_t server_conn = xpc_connection_create(NULL, server_q); + + xpc_connection_set_event_handler(server_conn, ^(xpc_object_t client) { + if (client == XPC_ERROR_CONNECTION_INTERRUPTED || client == XPC_ERROR_CONNECTION_INVALID) { + global = 43; + + dispatch_async(dispatch_get_main_queue(), ^{ + CFRunLoopStop(CFRunLoopGetCurrent()); + }); + } + }); + xpc_connection_resume(server_conn); + + global = 42; + + xpc_connection_cancel(server_conn); + + CFRunLoopRun(); + + fprintf(stderr, "Done.\n"); +} + +// CHECK: Hello world. +// CHECK-NOT: WARNING: ThreadSanitizer +// CHECK: Done. diff --git a/test/tsan/Darwin/xpc-race.mm b/test/tsan/Darwin/xpc-race.mm index 9141da42e3a0..eaef4e06c1f6 100644 --- a/test/tsan/Darwin/xpc-race.mm +++ b/test/tsan/Darwin/xpc-race.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s +// RUN: %deflake %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> #import <xpc/xpc.h> diff --git a/test/tsan/Darwin/xpc.mm b/test/tsan/Darwin/xpc.mm index a939b02ef21a..2d6de269b59f 100644 --- a/test/tsan/Darwin/xpc.mm +++ b/test/tsan/Darwin/xpc.mm @@ -1,5 +1,5 @@ // RUN: %clang_tsan %s -o %t -framework Foundation -// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s #import <Foundation/Foundation.h> #import <xpc/xpc.h> |