[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