tsan: remove sleeps from tests

Even sleep(1) lead to episodical flakes on some machines.
Use an invisible by tsan barrier to enforce required execution order instead.
This makes the tests deterministic and faster.

llvm-svn: 226659
This commit is contained in:
Dmitry Vyukov 2015-01-21 13:50:02 +00:00
parent 79ca0fd1a0
commit 3ab6b2347e
96 changed files with 476 additions and 425 deletions

View File

@ -1,17 +1,18 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *a) {
__atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST);
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
int *a = new int(0);
pthread_t t;
pthread_create(&t, 0, Thread, a);
sleep(1);
barrier_wait(&barrier);
delete a;
pthread_join(t, 0);
}

View File

@ -1,18 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *a) {
sleep(1);
barrier_wait(&barrier);
__atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST);
return 0;
}
int main() {
barrier_init(&barrier, 2);
int *a = new int(0);
pthread_t t;
pthread_create(&t, 0, Thread, a);
delete a;
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
const int kTestCount = 4;
typedef long long T;
@ -36,7 +34,8 @@ void *Thread(void *p) {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[i], false);
}
sleep(2);
barrier_wait(&barrier);
barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d reverse\n", i);
Test(i, &atomics[kTestCount + i], false);
@ -45,9 +44,10 @@ void *Thread(void *p) {
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d\n", i);
Test(i, &atomics[i], true);
@ -55,6 +55,7 @@ int main() {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[kTestCount + i], true);
}
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include "test.h"
const int kTestCount = 4;
typedef long long T;
@ -36,7 +34,8 @@ void *Thread(void *p) {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[i], false);
}
sleep(4);
barrier_wait(&barrier);
barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d reverse\n", i);
Test(i, &atomics[kTestCount + i], false);
@ -45,9 +44,10 @@ void *Thread(void *p) {
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
for (int i = 0; i < kTestCount; i++) {
fprintf(stderr, "Test %d\n", i);
Test(i, &atomics[i], true);
@ -55,6 +55,7 @@ int main() {
for (int i = 0; i < kTestCount; i++) {
Test(i, &atomics[kTestCount + i], true);
}
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,21 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
__atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED);
return NULL;
}
void *Thread2(void *x) {
Global++;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
int WTFGlobal;
@ -18,10 +16,12 @@ void WTFAnnotateBenignRaceSized(const char *f, int l,
void *Thread(void *x) {
Global = 42;
WTFGlobal = 142;
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
AnnotateBenignRaceSized(__FILE__, __LINE__,
&Global, sizeof(Global), "Race on Global");
WTFAnnotateBenignRaceSized(__FILE__, __LINE__,
@ -29,7 +29,7 @@ int main() {
"Race on WTFGlobal");
pthread_t t;
pthread_create(&t, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
Global = 43;
WTFGlobal = 143;
pthread_join(t, 0);

View File

@ -5,14 +5,12 @@
// RUN: %clangxx_tsan -O1 %s -fsanitize-blacklist=%t.blacklist -o %t
// RUN: %deflake %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
// CHECK: ThreadSanitizer: data race
// CHECK: Write of size 4
// CHECK: #0 Thread1{{.*}}blacklist2.cc:[[@LINE+1]]
@ -35,10 +33,12 @@ void *Blacklisted_Thread2(void *x) {
Global--;
// CHECK: #2 Blacklisted_Thread2{{.*}}blacklist2.cc:[[@LINE+1]]
CallTouchGlobal();
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Blacklisted_Thread2, NULL);

View File

@ -2,10 +2,7 @@
// CHECK-NOT: WARNING
// CHECK: OK
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "test.h"
pthread_mutex_t m;
pthread_cond_t c;
@ -14,6 +11,7 @@ int x;
void *thr1(void *p) {
pthread_mutex_lock(&m);
pthread_cleanup_push((void(*)(void *arg))pthread_mutex_unlock, &m);
barrier_wait(&barrier);
while (x == 0)
pthread_cond_wait(&c, &m);
pthread_cleanup_pop(1);
@ -21,12 +19,15 @@ void *thr1(void *p) {
}
int main() {
barrier_init(&barrier, 2);
pthread_t th;
pthread_mutex_init(&m, 0);
pthread_cond_init(&c, 0);
pthread_create(&th, 0, thr1, 0);
barrier_wait(&barrier);
sleep(1); // let it block on cond var
pthread_cancel(th);

View File

@ -3,10 +3,7 @@
// CHECK: ThreadSanitizer: data race
// CHECK: pthread_cond_signal
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "test.h"
struct Ctx {
pthread_mutex_t m;
@ -20,10 +17,12 @@ void *thr(void *p) {
c->done = true;
pthread_mutex_unlock(&c->m);
pthread_cond_signal(&c->c);
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
Ctx *c = new Ctx();
pthread_mutex_init(&c->m, 0);
pthread_cond_init(&c->c, 0);
@ -33,8 +32,8 @@ int main() {
while (!c->done)
pthread_cond_wait(&c->c, &c->m);
pthread_mutex_unlock(&c->m);
// w/o this sleep, it can be reported as use-after-free
sleep(1);
// otherwise it can be reported as use-after-free
barrier_wait(&barrier);
delete c;
pthread_join(th, 0);
}

View File

@ -7,12 +7,9 @@
// RUN: TSAN_OPTIONS=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
#include <pthread.h>
#include "test.h"
#undef NDEBUG
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <new>
#ifndef LockType
@ -224,7 +221,7 @@ class LockTest {
fprintf(stderr, "Starting Test5\n");
// CHECK: Starting Test5
Init(5);
RunThreads(&LockTest::Lock_0_1, &LockTest::Lock_1_0);
RunThreads(&LockTest::Lock_0_1<true>, &LockTest::Lock_1_0<true>);
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion
// CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ({{.*}}) => [[M2:M[0-9]+]] ({{.*}}) => [[M1]]
// CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]] in thread [[T1:T[0-9]+]]
@ -503,8 +500,21 @@ class LockTest {
private:
void Lock2(size_t l1, size_t l2) { L(l1); L(l2); U(l2); U(l1); }
void Lock_0_1() { Lock2(0, 1); }
void Lock_1_0() { sleep(1); Lock2(1, 0); }
template<bool wait = false>
void Lock_0_1() {
Lock2(0, 1);
if (wait)
barrier_wait(&barrier);
}
template<bool wait = false>
void Lock_1_0() {
if (wait)
barrier_wait(&barrier);
Lock2(1, 0);
}
void Lock1_Loop(size_t i, size_t n_iter) {
for (size_t it = 0; it < n_iter; it++) {
// if ((it & (it - 1)) == 0) fprintf(stderr, "%zd", i);
@ -569,6 +579,7 @@ class LockTest {
};
int main(int argc, char **argv) {
barrier_init(&barrier, 2);
if (argc > 1)
test_number = atoi(argv[1]);
if (argc > 2)

View File

@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t -DORDER1 && %deflake %run %t | FileCheck %s
// RUN: %clangxx_tsan -O1 %s -o %t -DORDER2 && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
volatile int X;
volatile int N;
@ -17,13 +15,17 @@ static void foo() {
void *Thread(void *p) {
#ifdef ORDER1
sleep(1);
barrier_wait(&barrier);
#endif
F();
#ifdef ORDER2
barrier_wait(&barrier);
#endif
return 0;
}
int main() {
barrier_init(&barrier, 2);
N = 50000;
F = foo;
pthread_t t;
@ -32,9 +34,13 @@ int main() {
pthread_attr_setstacksize(&a, N * 256 + (1 << 20));
pthread_create(&t, &a, Thread, 0);
#ifdef ORDER2
sleep(1);
barrier_wait(&barrier);
#endif
X = 43;
#ifdef ORDER1
barrier_wait(&barrier);
#endif
pthread_join(t, 0);
}

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -9,17 +7,19 @@
void *Thread1(void *x) {
int f = open("/dev/random", O_RDONLY);
close(f);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
int f = open("/dev/random", O_RDONLY);
close(f);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,23 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int fds[2];
void *Thread1(void *x) {
write(fds[1], "a", 1);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
close(fds[0]);
close(fds[1]);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pipe(fds);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);

View File

@ -1,23 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int fds[2];
void *Thread1(void *x) {
write(fds[1], "a", 1);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
close(fds[0]);
close(fds[1]);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pipe(fds);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -9,7 +7,7 @@
int X;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
int f = open("/dev/random", O_RDONLY);
char buf;
read(f, &buf, 1);
@ -21,10 +19,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
X = 43;
write(STDOUT_FILENO, "a", 1);
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="atexit_sleep_ms=50" %run %t 2>&1 | FileCheck %s
#include <stdlib.h>
#include <stdio.h>
#include "test.h"
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
@ -16,13 +13,14 @@ static void *incrementer(void *p) {
}
static void *watchdog(void *p) {
sleep(100);
sleep(100); // is not intended to exit
fprintf(stderr, "timed out after 100 seconds\n");
exit(1);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t th1, th2;
pthread_create(&th1, 0, incrementer, 0);
pthread_create(&th2, 0, watchdog, 0);

View File

@ -1,19 +1,21 @@
// 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
#include <stdlib.h>
#include <stdio.h>
#include "test.h"
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
static void *sleeper(void *p) {
sleep(10);
sleep(10); // not intended to exit during test
return 0;
}
static void *nop(void *p) {
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t th;
pthread_create(&th, 0, sleeper, 0);
switch (fork()) {
@ -23,7 +25,7 @@ int main() {
case 0: // child
{
pthread_t th2;
pthread_create(&th2, 0, sleeper, 0);
pthread_create(&th2, 0, nop, 0);
exit(0);
break;
}

View File

@ -2,11 +2,7 @@
// 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
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
int *mem;
pthread_mutex_t mtx;
@ -15,11 +11,12 @@ void *Thread1(void *x) {
pthread_mutex_lock(&mtx);
free(mem);
pthread_mutex_unlock(&mtx);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_mutex_lock(&mtx);
mem[0] = 42;
pthread_mutex_unlock(&mtx);
@ -27,6 +24,7 @@ void *Thread2(void *x) {
}
int main() {
barrier_init(&barrier, 2);
mem = (int*)malloc(100);
pthread_mutex_init(&mtx, 0);
pthread_t t;

View File

@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %T/global_race.cc.exe && %deflake %run %T/global_race.cc.exe | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
int GlobalData[10];
void *Thread(void *a) {
sleep(1);
barrier_wait(&barrier);
GlobalData[2] = 42;
return 0;
}
int main() {
barrier_init(&barrier, 2);
// 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, "addr=0x%012lx\n", (unsigned long) GlobalData);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
GlobalData[2] = 43;
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
int x;
void *Thread(void *a) {
sleep(1);
barrier_wait(&barrier);
x = 1;
return 0;
}
int main() {
barrier_init(&barrier, 2);
// 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, "addr2=0x%012lx\n", (unsigned long) &x);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
x = 0;
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,8 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
namespace XXX {
struct YYY {
@ -12,18 +9,20 @@ namespace XXX {
}
void *Thread(void *a) {
sleep(1);
barrier_wait(&barrier);
XXX::YYY::ZZZ[0] = 1;
return 0;
}
int main() {
barrier_init(&barrier, 2);
// 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, "addr3=0x%012lx\n", (unsigned long) XXX::YYY::ZZZ);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
XXX::YYY::ZZZ[0] = 0;
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,21 +1,21 @@
// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS halt_on_error=1" %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int X;
void *Thread(void *x) {
sleep(1);
barrier_wait(&barrier);
X = 42;
return 0;
}
int main() {
barrier_init(&barrier, 2);
fprintf(stderr, "BEFORE\n");
pthread_t t;
pthread_create(&t, 0, Thread, 0);
X = 43;
barrier_wait(&barrier);
pthread_join(t, 0);
fprintf(stderr, "AFTER\n");
return 0;

View File

@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
extern "C" {
void AnnotateIgnoreReadsBegin(const char *f, int l);
@ -13,14 +10,16 @@ void AnnotateIgnoreWritesEnd(const char *f, int l);
void *Thread(void *p) {
*(int*)p = 42;
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
int *p = new int(0);
pthread_t t;
pthread_create(&t, 0, Thread, p);
sleep(1);
barrier_wait(&barrier);
AnnotateIgnoreReadsBegin(__FILE__, __LINE__);
AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
free(p);

View File

@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
extern "C" {
void AnnotateIgnoreReadsBegin(const char *f, int l);
@ -16,7 +13,7 @@ int *g;
void *Thread(void *a) {
int *p = 0;
while ((p = __atomic_load_n(&g, __ATOMIC_RELAXED)) == 0)
usleep(100);
usleep(100); // spin-wait
*p = 42;
return 0;
}

View File

@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
@ -16,13 +14,15 @@ void *Thread(void *x) {
Global = 42;
AnnotateIgnoreReadsEnd(__FILE__, __LINE__);
AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
Global = 43;
pthread_join(t, 0);
printf("OK\n");

View File

@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include "test.h"
#include <string.h>
#include <unistd.h>
int x[4], z[4];
void *MemCpyThread(void *a) {
memcpy((int*)a, z, 16);
barrier_wait(&barrier);
return NULL;
}
void *MemSetThread(void *a) {
sleep(1);
barrier_wait(&barrier);
memset((int*)a, 0, 16);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
// Race on x between memcpy and memset
pthread_create(&t[0], NULL, MemCpyThread, x);

View File

@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include "test.h"
#include <string.h>
#include <unistd.h>
int y[4], z[4];
void *MemMoveThread(void *a) {
memmove((int*)a, z, 16);
barrier_wait(&barrier);
return NULL;
}
void *MemSetThread(void *a) {
sleep(1);
barrier_wait(&barrier);
memset((int*)a, 0, 16);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
// Race on y between memmove and memset
pthread_create(&t[0], NULL, MemMoveThread, y);

View File

@ -1,7 +1,4 @@
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
extern "C" {
typedef unsigned long jptr; // NOLINT

View File

@ -2,13 +2,14 @@
#include "java.h"
void *Thread(void *p) {
sleep(1);
barrier_wait(&barrier);
__tsan_java_finalize();
*(int*)p = 42;
return 0;
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@ -17,6 +18,7 @@ int main() {
pthread_t th;
pthread_create(&th, 0, Thread, (void*)jheap);
*(int*)jheap = 43;
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
fprintf(stderr, "DONE\n");

View File

@ -1,12 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "java.h"
#include <unistd.h>
jptr varaddr;
jptr lockaddr;
void *Thread(void *p) {
sleep(1);
barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 42;
__tsan_java_mutex_unlock(lockaddr);
@ -14,6 +13,7 @@ void *Thread(void *p) {
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@ -26,6 +26,7 @@ int main() {
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
fprintf(stderr, "DONE\n");

View File

@ -7,7 +7,7 @@ jptr varaddr2;
jptr lockaddr2;
void *Thread(void *p) {
sleep(1);
barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr2);
*(int*)varaddr2 = 42;
__tsan_java_mutex_unlock(lockaddr2);
@ -15,6 +15,7 @@ void *Thread(void *p) {
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@ -31,6 +32,7 @@ int main() {
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
__tsan_java_move(varaddr, varaddr2, kBlockSize);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr2, kBlockSize);
printf("DONE\n");

View File

@ -1,6 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "java.h"
#include <unistd.h>
jptr varaddr;
jptr lockaddr;
@ -14,7 +13,8 @@ void *Thread(void *p) {
printf("FAILED 0 rec=%d\n", rec);
exit(1);
}
sleep(2);
barrier_wait(&barrier);
barrier_wait(&barrier);
__tsan_java_mutex_lock_rec(lockaddr, rec);
if (*(int*)varaddr != 43) {
printf("FAILED 3 var=%d\n", *(int*)varaddr);
@ -26,6 +26,7 @@ void *Thread(void *p) {
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@ -36,7 +37,7 @@ int main() {
lockaddr = jheap + 8;
pthread_t th;
pthread_create(&th, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr);
if (*(int*)varaddr != 42) {
printf("FAILED 1 var=%d\n", *(int*)varaddr);
@ -44,6 +45,7 @@ int main() {
}
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
printf("DONE\n");

View File

@ -1,6 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include "java.h"
#include <unistd.h>
jptr varaddr;
jptr lockaddr;
@ -15,7 +14,8 @@ void *Thread(void *p) {
exit(1);
}
*(int*)varaddr = 42;
sleep(2);
barrier_wait(&barrier);
barrier_wait(&barrier);
__tsan_java_mutex_lock_rec(lockaddr, rec);
__tsan_java_mutex_unlock(lockaddr);
__tsan_java_mutex_unlock(lockaddr);
@ -24,6 +24,7 @@ void *Thread(void *p) {
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@ -34,10 +35,11 @@ int main() {
lockaddr = jheap + 8;
pthread_t th;
pthread_create(&th, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
printf("DONE\n");

View File

@ -13,7 +13,7 @@ jptr lockaddr1_new;
jptr lockaddr2_new;
void *Thread(void *p) {
sleep(1);
barrier_wait(&barrier);
__tsan_java_mutex_lock(lockaddr1_new);
*(char*)varaddr1_new = 43;
__tsan_java_mutex_unlock(lockaddr1_new);
@ -24,6 +24,7 @@ void *Thread(void *p) {
}
int main(int argc, char **argv) {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
void *jheap = malloc(kHeapSize);
jheap = (char*)jheap + 8;
@ -62,6 +63,7 @@ int main(int argc, char **argv) {
__tsan_java_mutex_unlock(lockaddr2_old);
__tsan_java_move(varaddr1_old, varaddr1_new, kBlockSize);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr1_new, kBlockSize);
printf("DONE\n");

View File

@ -9,13 +9,14 @@ jptr varaddr1_new;
jptr varaddr2_new;
void *Thread(void *p) {
sleep(1);
barrier_wait(&barrier);
*(int*)varaddr1_new = 43;
*(int*)varaddr2_new = 43;
return 0;
}
int main(int argc, char **argv) {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
void *jheap = malloc(kHeapSize);
jheap = (char*)jheap + 8;
@ -42,6 +43,7 @@ int main(int argc, char **argv) {
*(int*)varaddr2_old = 43;
__tsan_java_move(varaddr1_old, varaddr1_new, kBlockSize);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr1_new, kBlockSize);
printf("DONE\n");

View File

@ -5,12 +5,13 @@ jptr varaddr;
jptr varaddr2;
void *Thread(void *p) {
sleep(1);
barrier_wait(&barrier);
*(int*)varaddr2 = 42;
return 0;
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@ -23,6 +24,7 @@ int main() {
pthread_create(&th, 0, Thread, 0);
*(int*)varaddr = 43;
__tsan_java_move(varaddr, varaddr2, kBlockSize);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(varaddr2, kBlockSize);
fprintf(stderr, "DONE\n");

View File

@ -1,12 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "java.h"
#include <unistd.h>
jptr varaddr;
jptr lockaddr;
void *Thread(void *p) {
sleep(1);
barrier_wait(&barrier);
__tsan_java_mutex_read_lock(lockaddr);
*(int*)varaddr = 42;
__tsan_java_mutex_read_unlock(lockaddr);
@ -14,6 +13,7 @@ void *Thread(void *p) {
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);
@ -26,6 +26,7 @@ int main() {
__tsan_java_mutex_lock(lockaddr);
*(int*)varaddr = 43;
__tsan_java_mutex_unlock(lockaddr);
barrier_wait(&barrier);
pthread_join(th, 0);
__tsan_java_free(jheap, kBlockSize);
printf("DONE\n");

View File

@ -1,19 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "java.h"
#include <unistd.h>
jptr varaddr;
jptr lockaddr;
void *Thread(void *p) {
while (__atomic_load_n((int*)lockaddr, __ATOMIC_RELAXED) == 0)
usleep(1000);
usleep(1000); // spin-wait
__tsan_java_acquire(lockaddr);
*(int*)varaddr = 42;
return 0;
}
int main() {
barrier_init(&barrier, 2);
int const kHeapSize = 1024 * 1024;
jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
__tsan_java_init(jheap, kHeapSize);

View File

@ -7,35 +7,39 @@
#ifdef BUILD_SO
#include <stddef.h>
#include <unistd.h>
#include "test.h"
int GLOB_SHARED = 0;
extern "C"
void init_so() {
barrier_init(&barrier, 2);
}
extern "C"
void *write_from_so(void *unused) {
if (unused)
sleep(1);
if (unused == 0)
barrier_wait(&barrier);
GLOB_SHARED++;
if (unused != 0)
barrier_wait(&barrier);
return NULL;
}
#else // BUILD_SO
#include "test.h"
#include <dlfcn.h>
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include <string>
int GLOB = 0;
void *write_glob(void *unused) {
if (unused)
sleep(1);
if (unused == 0)
barrier_wait(&barrier);
GLOB++;
if (unused != 0)
barrier_wait(&barrier);
return NULL;
}
@ -48,6 +52,7 @@ void race_two_threads(void *(*access_callback)(void *unused)) {
}
int main(int argc, char *argv[]) {
barrier_init(&barrier, 2);
std::string path = std::string(argv[0]) + std::string("-so.so");
race_two_threads(write_glob);
// CHECK: write_glob
@ -56,6 +61,9 @@ int main(int argc, char *argv[]) {
printf("error in dlopen(): %s\n", dlerror());
return 1;
}
void (*init_so)();
*(void **)&init_so = dlsym(lib, "init_so");
init_so();
void *(*write_from_so)(void *unused);
*(void **)&write_from_so = dlsym(lib, "write_from_so");
race_two_threads(write_from_so);

View File

@ -1,20 +1,21 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
_Atomic(int*) p;
void *thr(void *a) {
sleep(1);
barrier_wait(&barrier);
int *pp = __c11_atomic_load(&p, __ATOMIC_RELAXED);
*pp = 42;
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t th;
pthread_create(&th, 0, thr, p);
__c11_atomic_store(&p, new int, __ATOMIC_RELAXED);
barrier_wait(&barrier);
pthread_join(th, 0);
}

View File

@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include "test.h"
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
@ -12,10 +9,12 @@
void *Thread(void *ptr) {
*(int*)ptr = 42;
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
void *ptr = mmap(0, 128 << 10, PROT_READ|PROT_WRITE,
MAP_32BIT|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
fprintf(stderr, "ptr=%p\n", ptr);
@ -29,7 +28,7 @@ int main() {
}
pthread_t t;
pthread_create(&t, 0, Thread, ptr);
sleep(1);
barrier_wait(&barrier);
*(int*)ptr = 42;
pthread_join(t, 0);
munmap(ptr, 128 << 10);

View File

@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include "test.h"
#include <string.h>
#include <unistd.h>
char *data = new char[10];
char *data1 = new char[10];
@ -12,17 +9,19 @@ char *data2 = new char[10];
void *Thread1(void *x) {
static volatile int size = 1;
memcpy(data+5, data1, size);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
static volatile int size = 4;
sleep(1);
barrier_wait(&barrier);
memcpy(data+3, data2, size);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
fprintf(stderr, "addr=%p\n", &data[5]);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);

View File

@ -1,23 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
void *Thread1(void *x) {
int *p = (int*)x;
p[0] = 1;
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
char *p = (char*)x;
p[2] = 1;
return NULL;
}
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);

View File

@ -1,11 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
int *p = (int*)x;
p[0] = 1;
return NULL;
@ -14,10 +11,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
char *p = (char*)x;
p[2] = 1;
barrier_wait(&barrier);
return NULL;
}
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);

View File

@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
pthread_mutex_t mtx;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_mutex_lock(&mtx);
Global++;
pthread_mutex_unlock(&mtx);
@ -16,10 +14,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
Global--;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
pthread_mutex_t mtx;
@ -10,16 +8,18 @@ void *Thread1(void *x) {
pthread_mutex_lock(&mtx);
Global++;
pthread_mutex_unlock(&mtx);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
Global--;
return NULL;
}
int main() {
barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T2:
// CHECK: Previous write of size 4 at {{.*}} by thread T1

View File

@ -1,14 +1,12 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_mutex_lock(&mtx1);
pthread_mutex_lock(&mtx2);
Global++;
@ -19,10 +17,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
Global--;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]], write [[M2:M[0-9]+]]):

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
pthread_mutex_t mtx1;
@ -13,16 +11,18 @@ void *Thread1(void *x) {
Global++;
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
Global--;
return NULL;
}
int main() {
barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T2:
// CHECK: Previous write of size 4 at {{.*}} by thread T1

View File

@ -1,14 +1,12 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_mutex_lock(&mtx1);
Global++;
pthread_mutex_unlock(&mtx1);
@ -19,10 +17,12 @@ void *Thread2(void *x) {
pthread_mutex_lock(&mtx2);
Global--;
pthread_mutex_unlock(&mtx2);
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
pthread_mutex_t mtx1;
@ -9,7 +7,7 @@ pthread_spinlock_t mtx2;
pthread_rwlock_t mtx3;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_mutex_lock(&mtx1);
Global++;
pthread_mutex_unlock(&mtx1);
@ -24,10 +22,12 @@ void *Thread2(void *x) {
Global--;
pthread_spin_unlock(&mtx2);
pthread_rwlock_unlock(&mtx3);
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):

View File

@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
__thread int huge[1024*1024];
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
Global++;
return NULL;
}
@ -20,10 +18,12 @@ void *Thread2(void *x) {
pthread_mutex_unlock(mtx);
pthread_mutex_destroy(mtx);
delete mtx;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
pthread_mutex_t *mtx;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_mutex_lock(mtx);
Global++;
pthread_mutex_unlock(mtx);
@ -16,10 +14,12 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
Global--;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1
// CHECK: (mutexes: write [[M1:M[0-9]+]]):

View File

@ -1,7 +0,0 @@
#include <time.h>
static void process_sleep(int sec) {
clock_t beg = clock();
while((clock() - beg) / CLOCKS_PER_SEC < sec)
usleep(100);
}

View File

@ -4,14 +4,12 @@
// 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.
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int glob = 0;
void *worker(void *unused) {
sleep(1);
barrier_wait(&barrier);
glob++;
return NULL;
}
@ -22,10 +20,12 @@ void atfork() {
}
int main() {
barrier_init(&barrier, 2);
pthread_atfork(atfork, NULL, NULL);
pthread_t t;
pthread_create(&t, NULL, worker, NULL);
glob++;
barrier_wait(&barrier);
pthread_join(t, NULL);
// CHECK: ThreadSanitizer: data race
// CHECK-NOT: ATFORK

View File

@ -1,25 +1,24 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
pthread_barrier_t B;
int Global;
void *Thread1(void *x) {
pthread_barrier_init(&B, 0, 2);
barrier_wait(&barrier);
pthread_barrier_wait(&B);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_barrier_wait(&B);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, NULL, Thread1, NULL);
Thread2(0);

View File

@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
pthread_mutex_t Mtx;
int Global;
@ -12,11 +9,12 @@ void *Thread1(void *x) {
pthread_mutex_lock(&Mtx);
Global = 42;
pthread_mutex_unlock(&Mtx);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
pthread_mutex_lock(&Mtx);
Global = 43;
pthread_mutex_unlock(&Mtx);
@ -24,6 +22,7 @@ void *Thread2(void *x) {
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
@ -36,7 +35,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:20{{(:3)?}} ({{.*}})
// CHECK-NEXT: #1 Thread2{{.*}} {{.*}}race_on_mutex.c:18{{(: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:11{{(:3)?}} ({{.*}})
// CHECK-NEXT: #1 Thread1{{.*}} {{.*}}race_on_mutex.c:8{{(:3)?}} ({{.*}})

View File

@ -1,21 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *x) {
pthread_mutex_lock((pthread_mutex_t*)x);
pthread_mutex_unlock((pthread_mutex_t*)x);
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_mutex_t Mtx;
pthread_mutex_init(&Mtx, 0);
pthread_t t;
pthread_create(&t, 0, Thread, &Mtx);
sleep(1);
barrier_wait(&barrier);
pthread_mutex_destroy(&Mtx);
pthread_join(t, 0);
return 0;

View File

@ -1,21 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
char s[] = "abracadabra";
void *Thread0(void *p) {
puts(s);
barrier_wait(&barrier);
return 0;
}
void *Thread1(void *p) {
barrier_wait(&barrier);
s[3] = 'z';
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t th[2];
pthread_create(&th[0], 0, Thread0, 0);
pthread_create(&th[1], 0, Thread1, 0);

View File

@ -1,31 +1,35 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
int fd;
char buf;
void *Thread(void *x) {
sleep(1);
void *Thread1(void *x) {
barrier_wait(&barrier);
read(fd, &buf, 1);
return NULL;
}
void *Thread2(void *x) {
read(fd, &buf, 1);
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
fd = open("/dev/random", O_RDONLY);
if (fd < 0) {
fprintf(stderr, "failed to open /dev/random (%d)\n", errno);
return 1;
}
pthread_t t[2];
pthread_create(&t[0], NULL, Thread, NULL);
pthread_create(&t[1], NULL, Thread, NULL);
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
close(fd);

View File

@ -1,9 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t | FileCheck %s
// Regtest for https://code.google.com/p/thread-sanitizer/issues/detail?id=40
// This is a correct program and tsan should not report a race.
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include "test.h"
int g;
__attribute__((noinline))
int foo(int cond) {
@ -11,17 +10,21 @@ int foo(int cond) {
return g;
return 0;
}
void *Thread1(void *p) {
barrier_wait(&barrier);
long res = foo((long)p);
sleep(1);
return (void*) res;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread1, 0);
g = 1;
barrier_wait(&barrier);
pthread_join(t, 0);
printf("PASS\n");
// CHECK-NOT: ThreadSanitizer: data race
// CHECK: PASS
}

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -11,7 +9,7 @@ char buf;
void *Thread1(void *x) {
buf = 1;
sleep(1);
barrier_wait(&barrier);
return NULL;
}
@ -21,11 +19,12 @@ void *Thread2(void *x) {
}
int main() {
barrier_init(&barrier, 2);
fd = open("/dev/null", O_WRONLY);
if (fd < 0) return 1;
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
sleep(1);
barrier_wait(&barrier);
pthread_create(&t[1], NULL, Thread2, NULL);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);

View File

@ -1,9 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "test.h"
// Ensure that we can restore a stack of a finished thread.
@ -15,16 +11,19 @@ void __attribute__((noinline)) foobar(int *p) {
void *Thread1(void *x) {
foobar(&g_data);
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
sleep(1); // let the thread finish and exit
g_data = 43;
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
volatile int x;
@ -17,18 +15,21 @@ void *Thread(void *a) {
__atomic_store_n(&x, 1, __ATOMIC_RELEASE);
foo();
data[0]++;
if (a != 0)
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
for (int i = 0; i < 50; i++) {
pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);
}
pthread_t t;
pthread_create(&t, 0, Thread, 0);
sleep(5);
pthread_create(&t, 0, Thread, (void*)1);
barrier_wait(&barrier);
for (int i = 0; i < kSize; i++)
data[i]++;
pthread_join(t, 0);

View File

@ -1,10 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
pthread_t mainth;
@ -16,12 +13,13 @@ static void MyHandler(int, siginfo_t *s, void *c) {
}
static void* sendsignal(void *p) {
sleep(1);
barrier_wait(&barrier);
pthread_kill(mainth, SIGPROF);
return 0;
}
static __attribute__((noinline)) void loop() {
barrier_wait(&barrier);
while (done == 0) {
volatile char *p = (char*)malloc(1);
p[0] = 0;
@ -31,6 +29,7 @@ static __attribute__((noinline)) void loop() {
}
int main() {
barrier_init(&barrier, 2);
mainth = pthread_self();
struct sigaction act = {};
act.sa_sigaction = &MyHandler;

View File

@ -1,9 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
static void handler(int, siginfo_t*, void*) {
// CHECK: WARNING: ThreadSanitizer: signal-unsafe call inside of a signal
@ -20,7 +18,7 @@ int main() {
act.sa_sigaction = &handler;
sigaction(SIGPROF, &act, 0);
kill(getpid(), SIGPROF);
sleep(1);
sleep(1); // let the signal handler run
return 0;
}

View File

@ -3,19 +3,13 @@
// Test case for recursive signal handlers, adopted from:
// https://code.google.com/p/thread-sanitizer/issues/detail?id=71
#include <pthread.h>
#include "test.h"
#include <semaphore.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "process_sleep.h"
static const int kSigSuspend = SIGUSR1;
static const int kSigRestart = SIGUSR2;
static sigset_t g_suspend_handler_mask;
static sem_t g_thread_suspend_ack_sem;
@ -27,7 +21,7 @@ static void SaveRegistersInStack() {
// Mono walks thread stacks to detect unreferenced objects.
// If last object reference is kept in register the object will be collected
// This is why threads can't be suspended with something like pthread_suspend
};
}
static void fail(const char *what) {
fprintf(stderr, "FAILED: %s (errno=%d)\n", what, errno);
@ -37,15 +31,19 @@ static void fail(const char *what) {
static void SuspendHandler(int sig) {
int old_errno = errno;
SaveRegistersInStack();
// Enable kSigRestart handling, tsan disables signals around signal handlers.
sigset_t sigset;
sigemptyset(&sigset);
pthread_sigmask(SIG_SETMASK, &sigset, 0);
// Acknowledge that thread is saved and suspended
if (sem_post(&g_thread_suspend_ack_sem) != 0)
fail("sem_post failed");
do {
g_busy_thread_received_restart = false;
if (sigsuspend(&g_suspend_handler_mask) != -1 || errno != EINTR)
fail("sigsuspend failed");
} while (!g_busy_thread_received_restart);
// Wait for wakeup signal.
while (!g_busy_thread_received_restart)
usleep(100); // wait for kSigRestart signal
// Acknowledge that thread restarted
if (sem_post(&g_thread_suspend_ack_sem) != 0)
@ -83,21 +81,15 @@ static void StartWorld(pthread_t thread) {
static void CollectGarbage(pthread_t thread) {
StopWorld(thread);
// Walk stacks
process_sleep(1);
StartWorld(thread);
}
static void Init() {
if (sigfillset(&g_suspend_handler_mask) != 0)
fail("sigfillset failed");
if (sigdelset(&g_suspend_handler_mask, kSigRestart) != 0)
fail("sigdelset failed");
if (sem_init(&g_thread_suspend_ack_sem, 0, 0) != 0)
fail("sem_init failed");
struct sigaction act = {};
act.sa_flags = SA_RESTART;
sigfillset(&act.sa_mask);
act.sa_handler = &SuspendHandler;
if (sigaction(kSigSuspend, &act, NULL) != 0)
fail("sigaction failed");

View File

@ -1,11 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
volatile int X;
@ -18,7 +15,7 @@ static void handler(int sig) {
static void* thr(void *p) {
for (int i = 0; i != 1000; i++)
usleep(1000);
usleep(1000); // process signals
return 0;
}

View File

@ -16,7 +16,7 @@ int main() {
act.sa_sigaction = &handler;
sigaction(SIGPROF, &act, 0);
kill(getpid(), SIGPROF);
sleep(1);
sleep(1); // let the signal handler run, can't use barrier in sig handler
fprintf(stderr, "DONE\n");
return 0;
}

View File

@ -1,22 +1,22 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
Global = 42;
return NULL;
}
void *Thread2(void *x) {
Global = 43;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,22 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
Global++;
return NULL;
}
void *Thread2(void *x) {
Global--;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
@ -24,13 +22,14 @@ void __attribute__((noinline)) bar2() {
}
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
bar1();
return NULL;
}
void *Thread2(void *x) {
bar2();
barrier_wait(&barrier);
return NULL;
}
@ -39,6 +38,7 @@ void StartThread(pthread_t *t, void *(*f)(void*)) {
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
StartThread(&t[0], Thread1);
StartThread(&t[1], Thread2);
@ -49,18 +49,18 @@ int main() {
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK-NEXT: Write of size 4 at {{.*}} by thread T1:
// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:9{{(:3)?}} ({{.*}})
// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack.c:14{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack.c:28{{(:3)?}} ({{.*}})
// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:7{{(:3)?}} ({{.*}})
// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack.c:12{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack.c:26{{(:3)?}} ({{.*}})
// CHECK: Previous read of size 4 at {{.*}} by thread T2:
// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:18{{(:20)?}} ({{.*}})
// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:23{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:33{{(:3)?}} ({{.*}})
// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:16{{(:20)?}} ({{.*}})
// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:21{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:31{{(:3)?}} ({{.*}})
// CHECK: Thread T1 (tid={{.*}}, running) created by main thread at:
// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}})
// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:37{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:43{{(:3)?}} ({{.*}})
// CHECK: Thread T2 ({{.*}}) created by main thread at:
// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}})
// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:37{{(:3)?}} ({{.*}})
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:44{{(:3)?}} ({{.*}})

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %T/simple_stack2.cc.exe && %deflake %run %T/simple_stack2.cc.exe | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
@ -30,24 +28,26 @@ void __attribute__((noinline)) bar2() {
}
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
bar1();
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, NULL, Thread1, NULL);
bar2();
barrier_wait(&barrier);
pthread_join(t, NULL);
}
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK-NEXT: Write of size 4 at {{.*}} by thread T1:
// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:9{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:16{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:34{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:7{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:14{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:32{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK: Previous read of size 4 at {{.*}} by main thread:
// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:20{{(:22)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:29{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:41{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:18{{(:22)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:27{{(:3)?}} (simple_stack2.cc.exe+{{.*}})
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:40{{(:3)?}} (simple_stack2.cc.exe+{{.*}})

View File

@ -1,23 +1,25 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
int X = 0;
void MySleep() {
sleep(1);
sleep(1); // the sleep that must appear in the report
}
void *Thread(void *p) {
barrier_wait(&barrier);
MySleep(); // Assume the main thread has done the write.
X = 42;
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
X = 43;
barrier_wait(&barrier);
pthread_join(t, 0);
return 0;
}

View File

@ -1,18 +1,20 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
int X = 0;
void *Thread(void *p) {
X = 42;
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
sleep(1);
sleep(1); // must not appear in the report
pthread_create(&t, 0, Thread, 0);
barrier_wait(&barrier);
X = 43;
pthread_join(t, 0);
return 0;

View File

@ -1,19 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *a) {
sleep(1);
barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
int main() {
barrier_init(&barrier, 2);
int Var = 42;
pthread_t t;
pthread_create(&t, 0, Thread, &Var);
Var = 43;
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,10 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
void *Thread2(void *a) {
sleep(1);
barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
@ -14,11 +12,13 @@ void *Thread(void *a) {
pthread_t t;
pthread_create(&t, 0, Thread2, &Var);
Var = 42;
barrier_wait(&barrier);
pthread_join(t, 0);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);

View File

@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "test.h"
// Test case https://code.google.com/p/thread-sanitizer/issues/detail?id=87
// Tsan sees false HB edge on address pointed to by syncp variable.
@ -26,7 +23,7 @@ long sink;
void *Thread(void *x) {
while (__atomic_load_n(&syncp, __ATOMIC_ACQUIRE) == 0)
usleep(1000);
usleep(1000); // spin wait
global = 42;
__atomic_store_n(syncp, 1, __ATOMIC_RELEASE);
__atomic_store_n(&syncp, 0, __ATOMIC_RELAXED);
@ -39,7 +36,7 @@ void __attribute__((noinline)) foobar() {
__atomic_store_n(&s, 0, __ATOMIC_RELAXED);
__atomic_store_n(&syncp, &s, __ATOMIC_RELEASE);
while (__atomic_load_n(&syncp, __ATOMIC_RELAXED) != 0)
usleep(1000);
usleep(1000); // spin wait
}
void __attribute__((noinline)) barfoo() {

View File

@ -1,11 +1,10 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
volatile int X;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
X = 42;
X = 66;
X = 78;
@ -16,10 +15,12 @@ void *Thread2(void *x) {
X = 11;
X = 99;
X = 73;
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread1, 0);
Thread2(0);

View File

@ -1,22 +1,22 @@
// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
Global = 42;
return NULL;
}
void *Thread2(void *x) {
Global = 43;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,22 +1,22 @@
// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
int Global;
void *Thread1(void *x) {
Global = 42;
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
Global = 43;
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -0,0 +1,31 @@
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <stddef.h>
// 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;
void barrier_init(pthread_barrier_t *barrier, unsigned count) {
if (barrier_wait == 0) {
void *h = dlopen("libpthread.so.0", RTLD_LAZY);
if (h == 0) {
fprintf(stderr, "failed to dlopen libpthread.so.0, exiting\n");
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);
}
// Default instance of the barrier, but a test can declare more manually.
pthread_barrier_t barrier;

View File

@ -1,16 +1,16 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *x) {
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
pthread_detach(t);
printf("PASS\n");
return 0;

View File

@ -1,15 +1,17 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *x) {
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
sleep(1);
barrier_wait(&barrier);
sleep(1); // wait for the thread to finish and exit
return 0;
}

View File

@ -1,18 +1,18 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include "test.h"
void *Thread(void *x) {
sleep(10);
sleep(100); // leave the thread "running"
return 0;
}
int main() {
pthread_t t;
pthread_create(&t, 0, Thread, 0);
printf("OK\n");
printf("DONE\n");
return 0;
}
// CHECK: DONE
// CHECK-NOT: WARNING: ThreadSanitizer: thread leak

View File

@ -1,18 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *x) {
barrier_wait(&barrier);
return 0;
}
int main() {
volatile int N = 5; // prevent loop unrolling
barrier_init(&barrier, N + 1);
for (int i = 0; i < N; i++) {
pthread_t t;
pthread_create(&t, 0, Thread, 0);
}
sleep(1);
barrier_wait(&barrier);
sleep(1); // wait for the threads to finish and exit
return 0;
}

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
#if defined(__linux__)
#define USE_PTHREAD_SETNAME_NP __GLIBC_PREREQ(2, 12)
@ -18,7 +16,7 @@ extern "C" void AnnotateThreadName(const char *f, int l, const char *name);
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
AnnotateThreadName(__FILE__, __LINE__, "Thread1");
Global++;
return NULL;
@ -31,10 +29,12 @@ void *Thread2(void *x) {
AnnotateThreadName(__FILE__, __LINE__, "Thread2");
#endif
Global--;
barrier_wait(&barrier);
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
#if defined(__FreeBSD__)
#include <pthread_np.h>
@ -11,7 +9,7 @@
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
Global++;
return 0;
}
@ -19,14 +17,17 @@ void *Thread1(void *x) {
void *Thread2(void *x) {
pthread_setname_np(pthread_self(), "foobar2");
Global--;
barrier_wait(&barrier);
return 0;
}
int main() {
barrier_init(&barrier, 3);
pthread_t t[2];
pthread_create(&t[0], 0, Thread1, 0);
pthread_create(&t[1], 0, Thread2, 0);
pthread_setname_np(t[0], "foobar1");
barrier_wait(&barrier);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
}

View File

@ -1,19 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
int Global;
void *Thread1(void *x) {
sleep(1);
barrier_wait(&barrier);
Global = 42;
return x;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread1, 0);
Global = 43;
barrier_wait(&barrier);
pthread_join(t, 0);
return Global;
}

View File

@ -1,19 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
void *Thread(void *a) {
sleep(1);
barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
int main() {
barrier_init(&barrier, 2);
static __thread int Var = 42;
pthread_t t;
pthread_create(&t, 0, Thread, &Var);
Var = 43;
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,10 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stddef.h>
#include <unistd.h>
#include "test.h"
void *Thread2(void *a) {
sleep(1);
barrier_wait(&barrier);
*(int*)a = 43;
return 0;
}
@ -14,11 +12,13 @@ void *Thread(void *a) {
pthread_t t;
pthread_create(&t, 0, Thread2, &Var);
Var = 42;
barrier_wait(&barrier);
pthread_join(t, 0);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);

View File

@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
#include <stdint.h>
#include <unistd.h>
#define NOINLINE __attribute__((noinline))
@ -123,15 +120,17 @@ NOINLINE void Test(bool main) {
void *Thread(void *p) {
(void)p;
sleep(1);
barrier_wait(&barrier);
Test(false);
return 0;
}
int main() {
barrier_init(&barrier, 2);
pthread_t th;
pthread_create(&th, 0, Thread, 0);
Test(true);
barrier_wait(&barrier);
pthread_join(th, 0);
}

View File

@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include "test.h"
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
struct A {
A() {
@ -31,16 +29,18 @@ static A *obj = new B;
void *Thread1(void *x) {
obj->F();
obj->Done();
barrier_wait(&barrier);
return NULL;
}
void *Thread2(void *x) {
sleep(1);
barrier_wait(&barrier);
delete obj;
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include "test.h"
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
struct A {
A() {
@ -29,18 +27,20 @@ struct B : A {
static A *obj = new B;
void *Thread1(void *x) {
sleep(1);
obj->F();
barrier_wait(&barrier);
obj->Done();
return NULL;
}
void *Thread2(void *x) {
barrier_wait(&barrier);
delete obj;
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include "test.h"
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
struct A {
A() {
@ -30,18 +28,20 @@ static A *obj = new B;
static void (A::*fn)() = &A::F;
void *Thread1(void *x) {
sleep(1);
(obj->*fn)();
barrier_wait(&barrier);
obj->Done();
return NULL;
}
void *Thread2(void *x) {
barrier_wait(&barrier);
delete obj;
return NULL;
}
int main() {
barrier_init(&barrier, 2);
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);

View File

@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
struct A {
virtual void F() {
@ -17,16 +15,18 @@ struct B : A {
};
void *Thread(void *x) {
sleep(1);
barrier_wait(&barrier);
((A*)x)->F();
return 0;
}
int main() {
barrier_init(&barrier, 2);
A *obj = new B;
pthread_t t;
pthread_create(&t, 0, Thread, obj);
delete obj;
barrier_wait(&barrier);
pthread_join(t, 0);
}

View File

@ -1,6 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include <pthread.h>
#include <unistd.h>
#include "test.h"
pthread_rwlock_t rwlock;
int GLOB;
@ -8,14 +7,15 @@ int GLOB;
void *Thread1(void *p) {
(void)p;
pthread_rwlock_rdlock(&rwlock);
barrier_wait(&barrier);
// Write under reader lock.
sleep(1);
GLOB++;
pthread_rwlock_unlock(&rwlock);
return 0;
}
int main(int argc, char *argv[]) {
barrier_init(&barrier, 2);
pthread_rwlock_init(&rwlock, NULL);
pthread_rwlock_rdlock(&rwlock);
pthread_t t;
@ -23,6 +23,7 @@ int main(int argc, char *argv[]) {
volatile int x = GLOB;
(void)x;
pthread_rwlock_unlock(&rwlock);
barrier_wait(&barrier);
pthread_join(t, 0);
pthread_rwlock_destroy(&rwlock);
return 0;
@ -30,6 +31,6 @@ int main(int argc, char *argv[]) {
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Write of size 4 at {{.*}} by thread T1{{.*}}:
// CHECK: #0 Thread1(void*) {{.*}}write_in_reader_lock.cc:13
// CHECK: #0 Thread1(void*) {{.*}}write_in_reader_lock.cc:12
// CHECK: Previous read of size 4 at {{.*}} by main thread{{.*}}:
// CHECK: #0 main {{.*}}write_in_reader_lock.cc:23