forked from OSchip/llvm-project
parent
5363bf157f
commit
38d0b60fb9
|
@ -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
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
pthread_t mainth;
|
pthread_t mainth;
|
||||||
volatile int done;
|
volatile int done;
|
||||||
|
|
||||||
static void handler(int, siginfo_t*, void*) {
|
static void handler(int, siginfo_t *s, void *c) {
|
||||||
errno = 1;
|
errno = 1;
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* sendsignal(void*) {
|
static void* sendsignal(void *p) {
|
||||||
pthread_kill(mainth, SIGPROF);
|
pthread_kill(mainth, SIGPROF);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct FdContext {
|
||||||
FdDesc globdesc;
|
FdDesc globdesc;
|
||||||
FdDesc filedesc;
|
FdDesc filedesc;
|
||||||
FdDesc sockdesc;
|
FdDesc sockdesc;
|
||||||
|
u64 connectsync;
|
||||||
};
|
};
|
||||||
|
|
||||||
static FdContext fdctx;
|
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) {
|
void FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd) {
|
||||||
DPrintf("#%d: FdSocketAccept(%d, %d)\n", thr->tid, fd, 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);
|
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) {
|
void FdSocketConnect(ThreadState *thr, uptr pc, int fd) {
|
||||||
DPrintf("#%d: FdSocketConnect(%d)\n", thr->tid, fd);
|
DPrintf("#%d: FdSocketConnect(%d)\n", thr->tid, fd);
|
||||||
init(thr, pc, fd, &fdctx.sockdesc);
|
init(thr, pc, fd, &fdctx.sockdesc);
|
||||||
|
|
|
@ -49,6 +49,7 @@ void FdEventCreate(ThreadState *thr, uptr pc, int fd);
|
||||||
void FdPollCreate(ThreadState *thr, uptr pc, int fd);
|
void FdPollCreate(ThreadState *thr, uptr pc, int fd);
|
||||||
void FdSocketCreate(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 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);
|
void FdSocketConnect(ThreadState *thr, uptr pc, int fd);
|
||||||
|
|
||||||
uptr File2addr(char *path);
|
uptr File2addr(char *path);
|
||||||
|
|
|
@ -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) {
|
TSAN_INTERCEPTOR(int, connect, int fd, void *addr, unsigned addrlen) {
|
||||||
SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen);
|
SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen);
|
||||||
|
FdSocketConnecting(thr, pc, fd);
|
||||||
int res = REAL(connect)(fd, addr, addrlen);
|
int res = REAL(connect)(fd, addr, addrlen);
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
FdSocketConnect(thr, pc, fd);
|
FdSocketConnect(thr, pc, fd);
|
||||||
|
|
Loading…
Reference in New Issue