diff --git a/compiler-rt/test/tsan/Linux/fork_syscall.cpp b/compiler-rt/test/tsan/Linux/fork_syscall.cpp --- a/compiler-rt/test/tsan/Linux/fork_syscall.cpp +++ b/compiler-rt/test/tsan/Linux/fork_syscall.cpp @@ -1,8 +1,7 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=atexit_sleep_ms=50 %run %t 2>&1 | FileCheck %s #include "../test.h" +#include "syscall.h" #include -#include -#include #include #include @@ -14,19 +13,7 @@ return 0; } -int myfork() { - __sanitizer_syscall_pre_fork(); -#ifdef SYS_fork - int res = syscall(SYS_fork); -#else - int res = syscall(SYS_clone, SIGCHLD, 0); -#endif - __sanitizer_syscall_post_fork(res); - return res; -} - int main() { - barrier_init(&barrier, 2); pthread_t th1; pthread_create(&th1, 0, incrementer, 0); for (int i = 0; i < 10; i++) { diff --git a/compiler-rt/test/tsan/Linux/syscall.h b/compiler-rt/test/tsan/Linux/syscall.h new file mode 100644 --- /dev/null +++ b/compiler-rt/test/tsan/Linux/syscall.h @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +int myfork() { + __sanitizer_syscall_pre_fork(); +#ifdef SYS_fork + int res = syscall(SYS_fork); +#else + int res = syscall(SYS_clone, SIGCHLD, 0); +#endif + __sanitizer_syscall_post_fork(res); + return res; +} + +int mypipe(int pipefd[2]) { + __sanitizer_syscall_pre_pipe(pipefd); + int res = syscall(SYS_pipe, pipefd); + __sanitizer_syscall_post_pipe(res, pipefd); + return res; +} + +int myclose(int fd) { + __sanitizer_syscall_pre_close(fd); + int res = syscall(SYS_close, fd); + __sanitizer_syscall_post_close(res, fd); + return res; +} + +ssize_t myread(int fd, void *buf, size_t count) { + __sanitizer_syscall_pre_read(fd, buf, count); + ssize_t res = syscall(SYS_read, fd, buf, count); + __sanitizer_syscall_post_read(res, fd, buf, count); + return res; +} + +ssize_t mywrite(int fd, const void *buf, size_t count) { + __sanitizer_syscall_pre_write(fd, buf, count); + ssize_t res = syscall(SYS_write, fd, buf, count); + __sanitizer_syscall_post_write(res, fd, buf, count); + return res; +} diff --git a/compiler-rt/test/tsan/Linux/syscall.cpp b/compiler-rt/test/tsan/Linux/syscall.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/tsan/Linux/syscall.cpp @@ -0,0 +1,37 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s +#include "syscall.h" +#include "../test.h" +#include +#include +#include + +int pipefd[2]; +char buf[10]; + +static void *thr(void *p) { + barrier_wait(&barrier); + mywrite(pipefd[1], buf, sizeof(buf)); + return 0; +} + +int main() { + barrier_init(&barrier, 2); + if (mypipe(pipefd)) + exit((perror("pipe"), 1)); + mywrite(pipefd[1], buf, sizeof(buf)); + pthread_t th; + pthread_create(&th, 0, thr, 0); + myread(pipefd[0], buf, sizeof(buf)); + barrier_wait(&barrier); + pthread_join(th, 0); + fprintf(stderr, "DONE\n"); +} + +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: Read of size 8 +// CHECK: #0 mywrite +// CHECK: #1 thr +// CHECK: Previous write of size 8 +// CHECK: #0 myread +// CHECK: #1 main +// CHECK: DONE