[llvm-commits] [compiler-rt] r169607 - in /compiler-rt/trunk/lib/tsan: lit_tests/fd_pipe_norace.cc lit_tests/fd_pipe_race.cc rtl/tsan_interceptors.cc
Dmitry Vyukov
dvyukov at google.com
Fri Dec 7 08:22:54 PST 2012
Author: dvyukov
Date: Fri Dec 7 10:22:54 2012
New Revision: 169607
URL: http://llvm.org/viewvc/llvm-project?rev=169607&view=rev
Log:
tsan: fix pipe interceptors and add 2 tests
Added:
compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_norace.cc
compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_race.cc
Modified:
compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
Added: compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_norace.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_norace.cc?rev=169607&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_norace.cc (added)
+++ compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_norace.cc Fri Dec 7 10:22:54 2012
@@ -0,0 +1,32 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int fds[2];
+int X;
+
+void *Thread1(void *x) {
+ X = 42;
+ write(fds[1], "a", 1);
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ char buf;
+ while (read(fds[0], &buf, 1) != 1) {
+ }
+ X = 43;
+ return NULL;
+}
+
+int main() {
+ pipe(fds);
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread1, NULL);
+ pthread_create(&t[1], NULL, Thread2, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
Added: compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_race.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_race.cc?rev=169607&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_race.cc (added)
+++ compiler-rt/trunk/lib/tsan/lit_tests/fd_pipe_race.cc Fri Dec 7 10:22:54 2012
@@ -0,0 +1,37 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int fds[2];
+
+void *Thread1(void *x) {
+ write(fds[1], "a", 1);
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ sleep(1);
+ close(fds[0]);
+ close(fds[1]);
+ return NULL;
+}
+
+int main() {
+ pipe(fds);
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread1, NULL);
+ pthread_create(&t[1], NULL, Thread2, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write of size 1
+// CHECK: #0 close
+// CHECK: #1 Thread2
+// CHECK: Previous read of size 1
+// CHECK: #0 write
+// CHECK: #1 Thread1
+
+
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=169607&r1=169606&r2=169607&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Fri Dec 7 10:22:54 2012
@@ -364,14 +364,20 @@
static void FdAcquire(ThreadState *thr, uptr pc, int fd) {
void *addr = FdAddr(fd);
- if (addr)
+ DPrintf("#%d: FdAcquire(%d) -> %p\n", thr->tid, fd, addr);
+ if (addr) {
Acquire(thr, pc, (uptr)addr);
+ MemoryRead1Byte(thr, pc, (uptr)addr);
+ }
}
static void FdRelease(ThreadState *thr, uptr pc, int fd) {
void *addr = FdAddr(fd);
- if (addr)
- Acquire(thr, pc, (uptr)addr);
+ DPrintf("#%d: FdRelease(%d) -> %p\n", thr->tid, fd, addr);
+ if (addr) {
+ Release(thr, pc, (uptr)addr);
+ MemoryRead1Byte(thr, pc, (uptr)addr);
+ }
}
static void FdClose(ThreadState *thr, uptr pc, int fd) {
@@ -390,7 +396,7 @@
}
static void FdCreatePipe(ThreadState *thr, uptr pc, int rfd, int wfd) {
- if (rfd >= FdContext::kMaxFds || rfd >= FdContext::kMaxFds) {
+ if (rfd >= FdContext::kMaxFds || wfd >= FdContext::kMaxFds) {
if (rfd < FdContext::kMaxFds) {
FdDesc *rdesc = &fdctx.desc[rfd];
rdesc->type = FdGlobal;
@@ -404,16 +410,18 @@
rdesc->type = FdPipe;
void *raddr = FdAddr(rfd);
if (raddr) {
- // To catch races between fd usage and close.
+ // To catch races between fd usage and open.
MemoryWrite1Byte(thr, pc, (uptr)raddr);
}
FdDesc *wdesc = &fdctx.desc[wfd];
wdesc->type = FdPipe;
void *waddr = FdAddr(wfd);
if (waddr) {
- // To catch races between fd usage and close.
+ // To catch races between fd usage and open.
MemoryWrite1Byte(thr, pc, (uptr)waddr);
}
+ DPrintf("#%d: FdCreatePipe(%d, %d) -> (%p, %p)\n",
+ thr->tid, rfd, wfd, raddr, waddr);
}
static uptr file2addr(char *path) {
@@ -1184,15 +1192,15 @@
return REAL(close)(fd);
}
-TSAN_INTERCEPTOR(int, pipe, int pipefd[2]) {
+TSAN_INTERCEPTOR(int, pipe, int *pipefd) {
SCOPED_TSAN_INTERCEPTOR(pipe, pipefd);
int res = REAL(pipe)(pipefd);
if (res == 0)
FdCreatePipe(thr, pc, pipefd[0], pipefd[1]);
- return res;
+ return res;
}
-TSAN_INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
+TSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) {
SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags);
int res = REAL(pipe2)(pipefd, flags);
if (res == 0)
More information about the llvm-commits
mailing list