Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,47 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: %deflake %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import "../test.h"
pthread_mutex_t m1;
pthread_mutex_t m2;
int main(int argc, const char *argv[]) {
barrier_init(&barrier, 2);
fprintf(stderr, "Hello world.\n");
pthread_mutex_init(&m1, NULL);
pthread_mutex_init(&m2, NULL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&m1);
pthread_mutex_lock(&m2);
pthread_mutex_unlock(&m2);
pthread_mutex_unlock(&m1);
barrier_wait(&barrier);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
barrier_wait(&barrier);
pthread_mutex_lock(&m2);
pthread_mutex_lock(&m1);
pthread_mutex_unlock(&m1);
pthread_mutex_unlock(&m2);
dispatch_sync(dispatch_get_main_queue(), ^{
CFRunLoopStop(CFRunLoopGetCurrent());
});
});
CFRunLoopRun();
fprintf(stderr, "Done.\n");
return 0;
}
// CHECK: Hello world.
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
// CHECK: Done.

View File

@@ -0,0 +1,64 @@
// 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 *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

View File

@@ -0,0 +1,38 @@
// Check that we don't crash when dispatch_main calls pthread_exit which
// quits the main thread.
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
int main() {
fprintf(stderr,"Hello world");
dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(q, ^{
fprintf(stderr,"1");
});
dispatch_async(q, ^{
fprintf(stderr,"2");
});
dispatch_async(q, ^{
fprintf(stderr,"3");
dispatch_async(dispatch_get_main_queue(), ^{
fprintf(stderr,"Done.");
sleep(1);
exit(0);
});
});
dispatch_main();
}
// CHECK: Hello world
// CHECK: Done.
// CHECK-NOT: WARNING: ThreadSanitizer
// CHECK-NOT: CHECK failed

View File

@@ -0,0 +1,41 @@
// Check that calling dispatch_once from a report callback works.
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: not %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import <pthread.h>
long g = 0;
long h = 0;
void f() {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
g++;
});
h++;
}
extern "C" void __tsan_on_report() {
fprintf(stderr, "Report.\n");
f();
}
int main() {
fprintf(stderr, "Hello world.\n");
f();
pthread_mutex_t mutex = {0};
pthread_mutex_lock(&mutex);
fprintf(stderr, "g = %ld.\n", g);
fprintf(stderr, "h = %ld.\n", h);
fprintf(stderr, "Done.\n");
}
// CHECK: Hello world.
// CHECK: Report.
// CHECK: g = 1
// CHECK: h = 2
// CHECK: Done.

View File

@@ -0,0 +1,43 @@
// Checks that on OS X 10.11+ (where we do not re-exec anymore, because
// interceptors work automatically), dlopen'ing a TSanified library from a
// non-instrumented program exits with a user-friendly message.
// REQUIRES: osx-autointerception
// XFAIL: ios
// RUN: %clangxx_tsan %s -o %t.so -shared -DSHARED_LIB
// RUN: %clangxx_tsan -fno-sanitize=thread %s -o %t
// RUN: TSAN_DYLIB_PATH=`%clangxx_tsan %s -### 2>&1 \
// RUN: | grep "libclang_rt.tsan_osx_dynamic.dylib" \
// RUN: | sed -e 's/.*"\(.*libclang_rt.tsan_osx_dynamic.dylib\)".*/\1/'`
// Launching a non-instrumented binary that dlopen's an instrumented library should fail.
// RUN: not %run %t %t.so 2>&1 | FileCheck %s --check-prefix=CHECK-FAIL
// Launching a non-instrumented binary with an explicit DYLD_INSERT_LIBRARIES should work.
// RUN: DYLD_INSERT_LIBRARIES=$TSAN_DYLIB_PATH %run %t %t.so 2>&1 | FileCheck %s
#include <dlfcn.h>
#include <pthread.h>
#include <stdio.h>
#if defined(SHARED_LIB)
extern "C" void foo() {
fprintf(stderr, "Hello world.\n");
}
#else // defined(SHARED_LIB)
int main(int argc, char *argv[]) {
void *handle = dlopen(argv[1], RTLD_NOW);
fprintf(stderr, "handle = %p\n", handle);
void (*foo)() = (void (*)())dlsym(handle, "foo");
fprintf(stderr, "foo = %p\n", foo);
foo();
}
#endif // defined(SHARED_LIB)
// CHECK: Hello world.
// CHECK-NOT: ERROR: Interceptors are not working.
// CHECK-FAIL-NOT: Hello world.
// CHECK-FAIL: ERROR: Interceptors are not working.

View File

@@ -0,0 +1,58 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %deflake %run %t 2>&1 | FileCheck %s
#include <thread>
#import "../test.h"
void *tag;
__attribute__((no_sanitize("thread")))
void ExternalWrite(void *addr) {
__tsan_external_write(addr, __builtin_return_address(0), tag);
}
int main(int argc, char *argv[]) {
barrier_init(&barrier, 2);
tag = __tsan_external_register_tag("HelloWorld");
fprintf(stderr, "Start.\n");
// CHECK: Start.
for (int i = 0; i < 4; i++) {
void *opaque_object = malloc(16);
std::thread t1([opaque_object] {
ExternalWrite(opaque_object);
barrier_wait(&barrier);
});
std::thread t2([opaque_object] {
barrier_wait(&barrier);
ExternalWrite(opaque_object);
});
// CHECK: WARNING: ThreadSanitizer: race on HelloWorld
t1.join();
t2.join();
}
fprintf(stderr, "First phase done.\n");
// CHECK: First phase done.
for (int i = 0; i < 4; i++) {
void *opaque_object = malloc(16);
std::thread t1([opaque_object] {
ExternalWrite(opaque_object);
barrier_wait(&barrier);
});
std::thread t2([opaque_object] {
barrier_wait(&barrier);
ExternalWrite(opaque_object);
});
// CHECK: WARNING: ThreadSanitizer: race on HelloWorld
t1.join();
t2.join();
}
fprintf(stderr, "Second phase done.\n");
// CHECK: Second phase done.
}
// CHECK: ThreadSanitizer: reported 2 warnings

View File

@@ -0,0 +1,19 @@
// RUN: %clangxx_tsan -shared %p/external-lib.cc -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \
// RUN: -o %t-lib.dylib -install_name @rpath/`basename %t-lib.dylib`
// RUN: %clangxx_tsan -shared %p/external-noninstrumented-module.cc %t-lib.dylib -fno-sanitize=thread \
// RUN: -o %t-module.dylib -install_name @rpath/`basename %t-module.dylib`
// RUN: %clangxx_tsan %s %t-module.dylib -o %t
// RUN: %run %t 2>&1 | FileCheck %s
#include <stdio.h>
extern "C" void NonInstrumentedModule();
int main(int argc, char *argv[]) {
NonInstrumentedModule();
fprintf(stderr, "Done.\n");
}
// CHECK-NOT: WARNING: ThreadSanitizer
// CHECK: Done.

View File

@@ -0,0 +1,68 @@
// This file is used from other tests.
// RUN: true
#include <dlfcn.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);
}
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;
}

View File

@@ -0,0 +1,27 @@
// This file is used from other tests.
// RUN: true
#include <thread>
#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);
}
extern "C" void NonInstrumentedModule() {
InitializeLibrary();
MyObjectRef ref = ObjectCreate();
std::thread t1([ref]{ ObjectWrite(ref, 42); });
std::thread t2([ref]{ ObjectWrite(ref, 43); });
t1.join();
t2.join();
}

View File

@@ -0,0 +1,92 @@
// RUN: %clangxx_tsan %s -o %t
// RUN: %deflake %run %t 2>&1 | FileCheck %s
#include <thread>
#import "../test.h"
extern "C" {
void __tsan_write8(void *addr);
}
static void *tag = (void *)0x1;
__attribute__((no_sanitize("thread")))
void ExternalWrite(void *addr) {
__tsan_external_write(addr, nullptr, tag);
}
__attribute__((no_sanitize("thread")))
void RegularWrite(void *addr) {
__tsan_write8(addr);
}
int main(int argc, char *argv[]) {
barrier_init(&barrier, 2);
fprintf(stderr, "Start.\n");
// CHECK: Start.
{
void *opaque_object = malloc(16);
std::thread t1([opaque_object] {
ExternalWrite(opaque_object);
barrier_wait(&barrier);
});
std::thread t2([opaque_object] {
barrier_wait(&barrier);
ExternalWrite(opaque_object);
});
// CHECK: WARNING: ThreadSanitizer: Swift access race
// CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
// CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
// CHECK: SUMMARY: ThreadSanitizer: Swift access race
t1.join();
t2.join();
}
fprintf(stderr, "external+external test done.\n");
// CHECK: external+external test done.
{
void *opaque_object = malloc(16);
std::thread t1([opaque_object] {
ExternalWrite(opaque_object);
barrier_wait(&barrier);
});
std::thread t2([opaque_object] {
barrier_wait(&barrier);
RegularWrite(opaque_object);
});
// CHECK: WARNING: ThreadSanitizer: Swift access race
// CHECK: Write of size 8 at {{.*}} by thread {{.*}}
// CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
// CHECK: SUMMARY: ThreadSanitizer: Swift access race
t1.join();
t2.join();
}
fprintf(stderr, "external+regular test done.\n");
// CHECK: external+regular test done.
{
void *opaque_object = malloc(16);
std::thread t1([opaque_object] {
RegularWrite(opaque_object);
barrier_wait(&barrier);
});
std::thread t2([opaque_object] {
barrier_wait(&barrier);
ExternalWrite(opaque_object);
});
// CHECK: WARNING: ThreadSanitizer: Swift access race
// CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
// CHECK: Previous write of size 8 at {{.*}} by thread {{.*}}
// CHECK: SUMMARY: ThreadSanitizer: Swift access race
t1.join();
t2.join();
}
fprintf(stderr, "regular+external test done.\n");
// CHECK: regular+external test done.
}

View File

@@ -0,0 +1,105 @@
// RUN: %clangxx_tsan %p/external-lib.cc -shared \
// RUN: -o %t-lib-instrumented.dylib \
// RUN: -install_name @rpath/`basename %t-lib-instrumented.dylib`
// RUN: %clangxx_tsan %p/external-lib.cc -shared -fno-sanitize=thread \
// RUN: -o %t-lib-noninstrumented.dylib \
// RUN: -install_name @rpath/`basename %t-lib-noninstrumented.dylib`
// RUN: %clangxx_tsan %p/external-lib.cc -shared -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 <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);
}
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 MyLibrary::MyObject
// TEST3: {{Modifying|read-only}} access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectRead}}
// TEST3: Previous {{modifying|read-only}} access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectRead}}
// TEST3: Location is MyLibrary::MyObject of size 16 at
// TEST3: {{ObjectCreate}}
// TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectRead}}
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 MyLibrary::MyObject
// TEST3: Modifying access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectWriteAnother}}
// TEST3: Previous modifying access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectWriteAnother}}
// TEST3: Location is MyLibrary::MyObject of size 16 at
// TEST3: {{ObjectCreate}}
// TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectWriteAnother}}
fprintf(stderr, "WW test done\n");
// CHECK: WW test done
}

View File

@@ -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

View File

@@ -0,0 +1,41 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
long my_global;
long my_global2;
void callback(void *context) {
my_global2 = 42;
dispatch_async(dispatch_get_main_queue(), ^{
CFRunLoopStop(CFRunLoopGetMain());
});
}
int main(int argc, const char *argv[]) {
fprintf(stderr, "start\n");
my_global = 10;
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_MSEC)), q, ^{
my_global = 42;
dispatch_async(dispatch_get_main_queue(), ^{
CFRunLoopStop(CFRunLoopGetMain());
});
});
CFRunLoopRun();
my_global2 = 10;
dispatch_after_f(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_MSEC)), q, NULL, &callback);
CFRunLoopRun();
fprintf(stderr, "done\n");
return 0;
}
// CHECK: start
// CHECK: done
// CHECK-NOT: WARNING: ThreadSanitizer

View File

@@ -0,0 +1,30 @@
// 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(int argc, const char *argv[]) {
barrier_init(&barrier, 2);
fprintf(stderr, "start\n");
// Warm up GCD (workaround for macOS Sierra where dispatch_apply might run single-threaded).
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ });
dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_apply(2, q, ^(size_t i) {
global = i;
barrier_wait(&barrier);
});
fprintf(stderr, "done\n");
return 0;
}
// CHECK: start
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Location is global 'global'
// CHECK: done

View File

@@ -0,0 +1,48 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import "../test.h"
long global;
long array[2];
void callback(void *context, size_t i) {
long n = global;
array[i] = n + i;
barrier_wait(&barrier);
}
int main(int argc, const char *argv[]) {
barrier_init(&barrier, 2);
fprintf(stderr, "start\n");
// Warm up GCD (workaround for macOS Sierra where dispatch_apply might run single-threaded).
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ });
dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
global = 42;
dispatch_apply(100, q, ^(size_t i) {
long n = global;
array[i] = n + i;
barrier_wait(&barrier);
});
for (int i = 0; i < 100; i++) {
fprintf(stderr, "array[%d] = %ld\n", i, array[i]);
}
global = 43;
dispatch_apply_f(100, q, NULL, &callback);
fprintf(stderr, "done\n");
return 0;
}
// CHECK: start
// CHECK: done
// CHECK-NOT: WARNING: ThreadSanitizer

View File

@@ -0,0 +1,26 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: %run %t 2>&1 | FileCheck %s
#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

View File

@@ -0,0 +1,38 @@
// 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() {
NSLog(@"Hello world.");
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();
NSLog(@"Done.");
}
// CHECK: Hello world.
// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Location is global 'global' {{(of size 8 )?}}at [[ADDR]] (gcd-async-race.mm.tmp+0x{{[0-9,a-f]+}})
// CHECK: Done.

View File

@@ -0,0 +1,48 @@
// 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);
dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t bgq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_barrier_sync(q, ^{
global = 42;
});
dispatch_async(bgq, ^{
dispatch_sync(q, ^{
global = 43;
barrier_wait(&barrier);
});
});
dispatch_async(bgq, ^{
dispatch_sync(q, ^{
barrier_wait(&barrier);
global = 44;
dispatch_sync(dispatch_get_main_queue(), ^{
CFRunLoopStop(CFRunLoopGetCurrent());
});
});
});
CFRunLoopRun();
fprintf(stderr, "Done.\n");
}
// CHECK: Hello world.
// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Location is global 'global' {{(of size 8 )?}}at [[ADDR]] (gcd-barrier-race.mm.tmp+0x{{[0-9,a-f]+}})
// CHECK: Done.

View File

@@ -0,0 +1,49 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
// RUN: %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);
dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t bgq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(bgq, ^{
dispatch_sync(q, ^{
global = 42;
});
barrier_wait(&barrier);
});
dispatch_async(bgq, ^{
barrier_wait(&barrier);
dispatch_barrier_sync(q, ^{
global = 43;
});
dispatch_async(bgq, ^{
barrier_wait(&barrier);
global = 44;
});
barrier_wait(&barrier);
dispatch_sync(dispatch_get_main_queue(), ^{
CFRunLoopStop(CFRunLoopGetCurrent());
});
});
CFRunLoopRun();
fprintf(stderr, "Done.\n");
}
// CHECK: Hello world.
// CHECK: Done.
// CHECK-NOT: WARNING: ThreadSanitizer

View File

@@ -0,0 +1,34 @@
// RUN: %clangxx_tsan %s -o %t -framework Foundation
// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
int main() {
fprintf(stderr, "start\n");
dispatch_queue_t background_q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t main_q = dispatch_get_main_queue();
dispatch_async(background_q, ^{
__block long block_var = 0;
dispatch_sync(main_q, ^{
block_var = 42;
});
fprintf(stderr, "block_var = %ld\n", block_var);
dispatch_sync(dispatch_get_main_queue(), ^{
CFRunLoopStop(CFRunLoopGetCurrent());
});
});
CFRunLoopRun();
fprintf(stderr, "done\n");
}
// CHECK: start
// CHECK: block_var = 42
// CHECK: done
// CHECK-NOT: WARNING: ThreadSanitizer
// CHECK-NOT: CHECK failed

Some files were not shown because too many files have changed in this diff Show More