[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