[llvm-commits] [compiler-rt] r170433 - in /compiler-rt/trunk/lib/tsan/rtl: tsan_fd.cc tsan_fd.h tsan_interceptors.cc tsan_stat.cc tsan_stat.h tsan_sync.cc

Dmitry Vyukov dvyukov at google.com
Tue Dec 18 06:44:44 PST 2012


Author: dvyukov
Date: Tue Dec 18 08:44:44 2012
New Revision: 170433

URL: http://llvm.org/viewvc/llvm-project?rev=170433&view=rev
Log:
tsan: intercept fork() to prevent false race reports on fd's

Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_fd.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc?rev=170433&r1=170432&r2=170433&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_fd.cc Tue Dec 18 08:44:44 2012
@@ -114,6 +114,21 @@
   atomic_store(&fdctx.socksync.rc, (u64)-1, memory_order_relaxed);
 }
 
+void FdOnFork(ThreadState *thr, uptr pc) {
+  // On fork() we need to reset all fd's, because the child is going
+  // close all them, and that will cause races between previous read/write
+  // and the close.
+  for (int l1 = 0; l1 < kTableSizeL1; l1++) {
+    FdDesc *tab = (FdDesc*)atomic_load(&fdctx.tab[l1], memory_order_relaxed);
+    if (tab == 0)
+      break;
+    for (int l2 = 0; l2 < kTableSizeL2; l2++) {
+      FdDesc *d = &tab[l2];
+      MemoryResetRange(thr, pc, (uptr)d, 8);
+    }
+  }
+}
+
 bool FdLocation(uptr addr, int *fd, int *tid, u32 *stack) {
   for (int l1 = 0; l1 < kTableSizeL1; l1++) {
     FdDesc *tab = (FdDesc*)atomic_load(&fdctx.tab[l1], memory_order_relaxed);

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_fd.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_fd.h?rev=170433&r1=170432&r2=170433&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_fd.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_fd.h Tue Dec 18 08:44:44 2012
@@ -54,6 +54,7 @@
 void FdSocketConnecting(ThreadState *thr, uptr pc, int fd);
 void FdSocketConnect(ThreadState *thr, uptr pc, int fd);
 bool FdLocation(uptr addr, int *fd, int *tid, u32 *stack);
+void FdOnFork(ThreadState *thr, uptr pc);
 
 uptr File2addr(char *path);
 uptr Dir2addr(char *path);

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=170433&r1=170432&r2=170433&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue Dec 18 08:44:44 2012
@@ -1617,6 +1617,19 @@
   return 0;
 }
 
+TSAN_INTERCEPTOR(int, fork) {
+  SCOPED_TSAN_INTERCEPTOR(fork);
+  // It's intercepted merely to process pending signals.
+  int pid = REAL(fork)();
+  if (pid == 0) {
+    // child
+    FdOnFork(thr, pc);
+  } else if (pid > 0) {
+    // parent
+  }
+  return pid;
+}
+
 namespace __tsan {
 
 void ProcessPendingSignals(ThreadState *thr) {
@@ -1826,6 +1839,8 @@
   TSAN_INTERCEPT(mlockall);
   TSAN_INTERCEPT(munlockall);
 
+  TSAN_INTERCEPT(fork);
+
   // Need to setup it, because interceptors check that the function is resolved.
   // But atexit is emitted directly into the module, so can't be resolved.
   REAL(atexit) = (int(*)(void(*)()))unreachable;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=170433&r1=170432&r2=170433&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Tue Dec 18 08:44:44 2012
@@ -234,6 +234,7 @@
   name[StatInt_usleep]                   = "  usleep                          ";
   name[StatInt_nanosleep]                = "  nanosleep                       ";
   name[StatInt_gettimeofday]             = "  gettimeofday                    ";
+  name[StatInt_fork]                     = "  fork                            ";
 
   name[StatAnnotation]                   = "Dynamic annotations               ";
   name[StatAnnotateHappensBefore]        = "  HappensBefore                   ";

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=170433&r1=170432&r2=170433&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Tue Dec 18 08:44:44 2012
@@ -233,6 +233,7 @@
   StatInt_usleep,
   StatInt_nanosleep,
   StatInt_gettimeofday,
+  StatInt_fork,
 
   // Dynamic annotations.
   StatAnnotation,

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc?rev=170433&r1=170432&r2=170433&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc Tue Dec 18 08:44:44 2012
@@ -60,6 +60,9 @@
 SyncVar* SyncTab::GetAndLock(ThreadState *thr, uptr pc,
                              uptr addr, bool write_lock, bool create) {
 #ifndef TSAN_GO
+  // Here we ask only PrimaryAllocator, because
+  // SecondaryAllocator::PointerIsMine() is slow and we have fallback on
+  // the hashmap anyway.
   if (PrimaryAllocator::PointerIsMine((void*)addr)) {
     MBlock *b = user_mblock(thr, (void*)addr);
     Lock l(&b->mtx);





More information about the llvm-commits mailing list