summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/tsan/lit_tests/fd_socket_connect_norace.cc44
-rw-r--r--compiler-rt/lib/tsan/lit_tests/signal_errno.cc4
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_fd.cc9
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_fd.h1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc1
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);
OpenPOWER on IntegriCloud