diff options
-rw-r--r-- | compiler-rt/lib/tsan/lit_tests/fd_socket_connect_norace.cc | 44 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/lit_tests/signal_errno.cc | 4 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_fd.cc | 9 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_fd.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors.cc | 1 |
5 files changed, 57 insertions, 2 deletions
diff --git a/compiler-rt/lib/tsan/lit_tests/fd_socket_connect_norace.cc b/compiler-rt/lib/tsan/lit_tests/fd_socket_connect_norace.cc new file mode 100644 index 00000000000..a1e2e894bd4 --- /dev/null +++ b/compiler-rt/lib/tsan/lit_tests/fd_socket_connect_norace.cc @@ -0,0 +1,44 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +struct sockaddr_in addr; +int X; + +void *ClientThread(void *x) { + int c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + X = 42; + if (connect(c, (struct sockaddr*)&addr, sizeof(addr))) { + perror("connect"); + exit(1); + } + close(c); + return NULL; +} + +int main() { + int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + addr.sin_family = AF_INET; + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); + addr.sin_port = INADDR_ANY; + socklen_t len = sizeof(addr); + bind(s, (sockaddr*)&addr, len); + getsockname(s, (sockaddr*)&addr, &len); + listen(s, 10); + pthread_t t; + pthread_create(&t, 0, ClientThread, 0); + int c = accept(s, 0, 0); + X = 42; + pthread_join(t, 0); + close(c); + close(s); +} + +// CHECK-NOT: WARNING: ThreadSanitizer: data race + diff --git a/compiler-rt/lib/tsan/lit_tests/signal_errno.cc b/compiler-rt/lib/tsan/lit_tests/signal_errno.cc index 14453a2e6e4..af9ccce9045 100644 --- a/compiler-rt/lib/tsan/lit_tests/signal_errno.cc +++ b/compiler-rt/lib/tsan/lit_tests/signal_errno.cc @@ -10,12 +10,12 @@ pthread_t mainth; volatile int done; -static void handler(int, siginfo_t*, void*) { +static void handler(int, siginfo_t *s, void *c) { errno = 1; done = 1; } -static void* sendsignal(void*) { +static void* sendsignal(void *p) { pthread_kill(mainth, SIGPROF); return 0; } diff --git a/compiler-rt/lib/tsan/rtl/tsan_fd.cc b/compiler-rt/lib/tsan/rtl/tsan_fd.cc index 97ab2d93044..cb91c413166 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_fd.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_fd.cc @@ -31,6 +31,7 @@ struct FdContext { FdDesc globdesc; FdDesc filedesc; FdDesc sockdesc; + u64 connectsync; }; static FdContext fdctx; @@ -165,9 +166,17 @@ void FdSocketCreate(ThreadState *thr, uptr pc, int fd) { void FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd) { DPrintf("#%d: FdSocketAccept(%d, %d)\n", thr->tid, fd, newfd); + // Synchronize connect->accept. + Acquire(thr, pc, (uptr)&fdctx.connectsync); init(thr, pc, newfd, &fdctx.sockdesc); } +void FdSocketConnecting(ThreadState *thr, uptr pc, int fd) { + DPrintf("#%d: FdSocketConnecting(%d)\n", thr->tid, fd); + // Synchronize connect->accept. + Release(thr, pc, (uptr)&fdctx.connectsync); +} + void FdSocketConnect(ThreadState *thr, uptr pc, int fd) { DPrintf("#%d: FdSocketConnect(%d)\n", thr->tid, fd); init(thr, pc, fd, &fdctx.sockdesc); diff --git a/compiler-rt/lib/tsan/rtl/tsan_fd.h b/compiler-rt/lib/tsan/rtl/tsan_fd.h index 7d204685d60..6f509cd2e90 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_fd.h +++ b/compiler-rt/lib/tsan/rtl/tsan_fd.h @@ -49,6 +49,7 @@ void FdEventCreate(ThreadState *thr, uptr pc, int fd); void FdPollCreate(ThreadState *thr, uptr pc, int fd); void FdSocketCreate(ThreadState *thr, uptr pc, int fd); void FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd); +void FdSocketConnecting(ThreadState *thr, uptr pc, int fd); void FdSocketConnect(ThreadState *thr, uptr pc, int fd); uptr File2addr(char *path); diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index 6d2b4122331..239aa27c748 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -1146,6 +1146,7 @@ TSAN_INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int *fd) { TSAN_INTERCEPTOR(int, connect, int fd, void *addr, unsigned addrlen) { SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen); + FdSocketConnecting(thr, pc, fd); int res = REAL(connect)(fd, addr, addrlen); if (res == 0) FdSocketConnect(thr, pc, fd); |