[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