[PATCH v4] Add support for Linux/no-mmu with vfork

Mike Frysinger vapier at gentoo.org
Thu Oct 8 00:41:29 UTC 2009


* configure.ac (AC_CHECK_FUNCS): Add fork.
* strace.c (strace_fork): Define.
(startup_child): Do not SIGSTOP if vforked.
(trace): Skip first exec when starting up after vforked.
* syscall.c (get_scno): Drop Blackfin waitexec checks.

Signed-off-by: Mike Frysinger <vapier at gentoo.org>
---
v4
	- drop dynamic fork()==ENOSYS detection

 configure.ac |    1 +
 strace.c     |   17 +++++++++++++++--
 syscall.c    |    3 ---
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 95f769e..7b1a8c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -209,6 +209,7 @@ AC_CHECK_LIB(nsl, main)
 fi
 
 AC_CHECK_FUNCS([ \
+	fork \
 	getdents \
 	if_indextoname \
 	inet_ntop \
diff --git a/strace.c b/strace.c
index da8cc4a..56ffbe5 100644
--- a/strace.c
+++ b/strace.c
@@ -212,6 +212,14 @@ foobar()
 #endif /* MIPS */
 #endif /* SVR4 */
 
+/* Glue for systems without a MMU that cannot provide fork() */
+#ifdef HAVE_FORK
+# define strace_vforked false
+#else
+# define strace_vforked true
+# define fork()         vfork()
+#endif
+
 static int
 set_cloexec_flag(int fd)
 {
@@ -636,8 +644,11 @@ startup_child (char **argv)
 			 * Induce an immediate stop so that the parent
 			 * will resume us with PTRACE_SYSCALL and display
 			 * this execve call normally.
+			 * Unless of course we're on a no-MMU system where
+			 * we vfork()-ed, so we cannot stop the child.
 			 */
-			kill(getpid(), SIGSTOP);
+			if (!strace_vforked)
+				kill(getpid(), SIGSTOP);
 		} else {
 			struct sigaction sv_sigchld;
 			sigaction(SIGCHLD, NULL, &sv_sigchld);
@@ -2445,8 +2456,10 @@ Process %d attached (waiting for parent)\n",
 		 * with STOPSIG equal to some other signal
 		 * than SIGSTOP if we happend to attach
 		 * just before the process takes a signal.
+		 * A no-mmu vforked child won't send up a signal,
+		 * so skip the first (lost) execve notification.
 		 */
-		if ((tcp->flags & TCB_STARTUP) && WSTOPSIG(status) == SIGSTOP) {
+		if ((tcp->flags & TCB_STARTUP) && (WSTOPSIG(status) == SIGSTOP || strace_vforked)) {
 			/*
 			 * This flag is there to keep us in sync.
 			 * Next time this process stops it should
diff --git a/syscall.c b/syscall.c
index a2e6885..6a75c70 100644
--- a/syscall.c
+++ b/syscall.c
@@ -922,9 +922,6 @@ get_scno(struct tcb *tcp)
 # elif defined(BFIN)
 	if (upeek(tcp, PT_ORIG_P0, &scno))
 		return -1;
-	/* Check if we return from execve. */
-	if (tcp->flags & TCB_WAITEXECVE && tcp->flags & TCB_INSYSCALL)
-		tcp->flags &= ~(TCB_INSYSCALL | TCB_WAITEXECVE);
 # elif defined (I386)
 	if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
 		return -1;
-- 
1.6.5.rc2





More information about the Strace-devel mailing list