[compiler-rt] r191144 - tsan: intercept fork syscall

Dmitry Vyukov dvyukov at google.com
Sat Sep 21 13:59:05 PDT 2013


Author: dvyukov
Date: Sat Sep 21 15:59:04 2013
New Revision: 191144

URL: http://llvm.org/viewvc/llvm-project?rev=191144&view=rev
Log:
tsan: intercept fork syscall


Modified:
    compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc

Modified: compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h?rev=191144&r1=191143&r2=191144&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h (original)
+++ compiler-rt/trunk/include/sanitizer/linux_syscall_hooks.h Sat Sep 21 15:59:04 2013
@@ -1826,6 +1826,14 @@
   __sanitizer_syscall_post_impl_process_vm_writev(                          \
       res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),        \
       (long)(riovcnt), (long)(flags))
+#define __sanitizer_syscall_pre_fork() \
+  __sanitizer_syscall_pre_impl_fork()
+#define __sanitizer_syscall_post_fork(res) \
+  __sanitizer_syscall_post_impl_fork(res)
+#define __sanitizer_syscall_pre_vfork() \
+  __sanitizer_syscall_pre_impl_vfork()
+#define __sanitizer_syscall_post_vfork(res) \
+  __sanitizer_syscall_post_impl_vfork(res)
 
 // And now a few syscalls we don't handle yet.
 #define __sanitizer_syscall_pre_afs_syscall(...)
@@ -1843,7 +1851,6 @@
 #define __sanitizer_syscall_pre_fanotify_init(...)
 #define __sanitizer_syscall_pre_fanotify_mark(...)
 #define __sanitizer_syscall_pre_fchown32(...)
-#define __sanitizer_syscall_pre_fork(...)
 #define __sanitizer_syscall_pre_ftime(...)
 #define __sanitizer_syscall_pre_ftruncate64(...)
 #define __sanitizer_syscall_pre_futex(...)
@@ -1907,7 +1914,6 @@
 #define __sanitizer_syscall_pre_ugetrlimit(...)
 #define __sanitizer_syscall_pre_ulimit(...)
 #define __sanitizer_syscall_pre_umount2(...)
-#define __sanitizer_syscall_pre_vfork(...)
 #define __sanitizer_syscall_pre_vm86(...)
 #define __sanitizer_syscall_pre_vm86old(...)
 #define __sanitizer_syscall_pre_vserver(...)
@@ -1927,7 +1933,6 @@
 #define __sanitizer_syscall_post_fanotify_init(res, ...)
 #define __sanitizer_syscall_post_fanotify_mark(res, ...)
 #define __sanitizer_syscall_post_fchown32(res, ...)
-#define __sanitizer_syscall_post_fork(res, ...)
 #define __sanitizer_syscall_post_ftime(res, ...)
 #define __sanitizer_syscall_post_ftruncate64(res, ...)
 #define __sanitizer_syscall_post_futex(res, ...)
@@ -1991,7 +1996,6 @@
 #define __sanitizer_syscall_post_ugetrlimit(res, ...)
 #define __sanitizer_syscall_post_ulimit(res, ...)
 #define __sanitizer_syscall_post_umount2(res, ...)
-#define __sanitizer_syscall_post_vfork(res, ...)
 #define __sanitizer_syscall_post_vm86old(res, ...)
 #define __sanitizer_syscall_post_vm86(res, ...)
 #define __sanitizer_syscall_post_vserver(res, ...)
@@ -3053,6 +3057,10 @@ void __sanitizer_syscall_post_impl_proce
                                                      long lvec, long liovcnt,
                                                      long rvec, long riovcnt,
                                                      long flags);
+void __sanitizer_syscall_pre_impl_fork();
+void __sanitizer_syscall_post_impl_fork(long res);
+void __sanitizer_syscall_pre_impl_vfork();
+void __sanitizer_syscall_post_impl_vfork(long res);
 
 #ifdef __cplusplus
 }  // extern "C"

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc?rev=191144&r1=191143&r2=191144&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_syscalls.inc Sat Sep 21 15:59:04 2013
@@ -27,6 +27,10 @@
 //          and are now initialized.
 //   COMMON_SYSCALL_FD_CLOSE(fd)
 //          Called before closing file descriptor fd.
+//   COMMON_SYSCALL_PRE_FORK()
+//          Called before fork syscall.
+//   COMMON_SYSCALL_POST_FORK(long res)
+//          Called after fork syscall.
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_platform.h"
@@ -48,6 +52,14 @@
 # define COMMON_SYSCALL_FD_CLOSE(fd)
 #endif
 
+#ifndef COMMON_SYSCALL_PRE_FORK
+# define COMMON_SYSCALL_PRE_FORK()
+#endif
+
+#ifndef COMMON_SYSCALL_POST_FORK
+# define COMMON_SYSCALL_POST_FORK(res)
+#endif
+
 // FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
 
 extern "C" {
@@ -2694,6 +2706,22 @@ POST_SYSCALL(process_vm_writev)(long res
     if (lvec) kernel_read_iovec(lvec, liovcnt, res);
   }
 }
+
+PRE_SYSCALL(fork)() {
+  COMMON_SYSCALL_PRE_FORK();
+}
+
+POST_SYSCALL(fork)(long res) {
+  COMMON_SYSCALL_POST_FORK(res);
+}
+
+PRE_SYSCALL(vfork)() {
+  COMMON_SYSCALL_PRE_FORK();
+}
+
+POST_SYSCALL(vfork)(long res) {
+  COMMON_SYSCALL_POST_FORK(res);
+}
 }  // extern "C"
 
 #undef PRE_SYSCALL

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=191144&r1=191143&r2=191144&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Sat Sep 21 15:59:04 2013
@@ -1792,7 +1792,6 @@ TSAN_INTERCEPTOR(int, munlockall, void)
 
 TSAN_INTERCEPTOR(int, fork, int fake) {
   SCOPED_TSAN_INTERCEPTOR(fork, fake);
-  // It's intercepted merely to process pending signals.
   int pid = REAL(fork)(fake);
   if (pid == 0) {
     // child
@@ -1846,28 +1845,51 @@ struct TsanInterceptorContext {
 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)
 #include "sanitizer_common/sanitizer_common_interceptors.inc"
 
+#define TSAN_SYSCALL() \
+  ThreadState *thr = cur_thread(); \
+  ScopedSyscall scoped_syscall(thr) \
+/**/
+
+struct ScopedSyscall {
+  ThreadState *thr;
+
+  explicit ScopedSyscall(ThreadState *thr)
+      : thr(thr) {
+    if (thr->in_rtl == 0)
+      Initialize(thr);
+    thr->in_rtl++;
+  }
+
+  ~ScopedSyscall() {
+    thr->in_rtl--;
+    if (thr->in_rtl == 0)
+      ProcessPendingSignals(thr);
+  }
+};
+
 static void syscall_access_range(uptr pc, uptr p, uptr s, bool write) {
-  ThreadState *thr = cur_thread();
-  if (thr->in_rtl == 0)
-    Initialize(thr);
-  thr->in_rtl++;
+  TSAN_SYSCALL();
   MemoryAccessRange(thr, pc, p, s, write);
-  thr->in_rtl--;
-  if (thr->in_rtl == 0)
-    ProcessPendingSignals(thr);
 }
 
 static void syscall_fd_close(uptr pc, int fd) {
-  if (fd < 0)
-    return;
-  ThreadState *thr = cur_thread();
-  if (thr->in_rtl == 0)
-    Initialize(thr);
-  thr->in_rtl++;
-  FdClose(thr, pc, fd);
-  thr->in_rtl--;
-  if (thr->in_rtl == 0)
-    ProcessPendingSignals(thr);
+  TSAN_SYSCALL();
+  if (fd >= 0)
+    FdClose(thr, pc, fd);
+}
+
+static void syscall_pre_fork(uptr pc) {
+  TSAN_SYSCALL();
+}
+
+static void syscall_post_fork(uptr pc, int res) {
+  TSAN_SYSCALL();
+  if (res == 0) {
+    // child
+    FdOnFork(thr, pc);
+  } else if (res > 0) {
+    // parent
+  }
 }
 
 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) \
@@ -1880,6 +1902,10 @@ static void syscall_fd_close(uptr pc, in
   do { } while (false)
 #define COMMON_SYSCALL_FD_CLOSE(fd) \
   syscall_fd_close(GET_CALLER_PC(), fd)
+#define COMMON_SYSCALL_PRE_FORK() \
+  syscall_pre_fork(GET_CALLER_PC())
+#define COMMON_SYSCALL_POST_FORK(res) \
+  syscall_post_fork(GET_CALLER_PC(), res)
 #include "sanitizer_common/sanitizer_common_syscalls.inc"
 
 namespace __tsan {





More information about the llvm-commits mailing list