]> granicus.if.org Git - strace/commitdiff
Assorted NOMMU fixes
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 26 Feb 2013 11:00:34 +0000 (12:00 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 26 Feb 2013 11:00:34 +0000 (12:00 +0100)
With -D, strdup'ing of pathname is necessary only on NOMMU.

Don't set skip_startup_execve to 1 if NOMMU and not in daemonized mode
(try "strace [-D] -b env echo HI" to see whether we detach on correct execve).

Fix test_ptrace_FOO shortcuts on NOMMU to always assume success
and _properly_ set all variables.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
defs.h
strace.c

diff --git a/defs.h b/defs.h
index 3212418c4f43a9d8db262d3edf8f905a2e00d4c8..e85154ed91504fa3f81b3d59a2cb236c2b2cbcf0 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -116,7 +116,7 @@ extern char *stpcpy(char *dst, const char *src);
  * This needs Linux kernel 3.4.x or later to work.
  */
 #define USE_SEIZE 1
-/* For forcing NOMMU build, set to 1 */
+/* To force NOMMU build, set to 1 */
 #define NOMMU_SYSTEM 0
 
 
index 41cfe065e7abb789d7610c093e57061780fb1e20..de5b08a06c25ccb2d52f77fdf265d9973acb21d6 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -1122,7 +1122,7 @@ startup_child(char **argv)
         * On NOMMU, can be safely freed only after execve in tracee.
         * It's hard to know when that happens, so we just leak it.
         */
-       params_for_tracee.pathname = strdup(pathname);
+       params_for_tracee.pathname = NOMMU_SYSTEM ? strdup(pathname) : pathname;
 
        strace_child = pid = fork();
        if (pid < 0) {
@@ -1156,6 +1156,7 @@ startup_child(char **argv)
                                        kill_save_errno(pid, SIGKILL);
                                        perror_msg_and_die("Unexpected wait status %x", status);
                                }
+                               skip_startup_execve = 1;
                        }
                        /* Else: NOMMU case, we have no way to sync.
                         * Just attach to it as soon as possible.
@@ -1177,13 +1178,14 @@ startup_child(char **argv)
                newoutf(tcp);
        }
        else {
-               /* With -D, *we* are child here, IOW: different pid. Fetch it: */
+               /* With -D, we are *child* here, IOW: different pid. Fetch it: */
                strace_tracer_pid = getpid();
                /* The tracee is our parent: */
                pid = getppid();
                alloctcb(pid);
                /* attaching will be done later, by startup_attach */
                /* note: we don't do newoutf(tcp) here either! */
+               skip_startup_execve = 1;
 
                /* NOMMU BUG! -D mode is active, we (child) return,
                 * and we will scribble over parent's stack!
@@ -1201,6 +1203,9 @@ startup_child(char **argv)
                 * This may save us if (1) and (2) failed
                 * and compiler decided to use stack in exec_or_die() anyway
                 * (happens on i386 because of stack parameter passing).
+                *
+                * A cleaner solution is to use makecontext + setcontext
+                * to create a genuine separate stack and execute on it.
                 */
        }
 }
@@ -1218,6 +1223,10 @@ test_ptrace_setoptions_followfork(void)
                                          PTRACE_O_TRACEFORK |
                                          PTRACE_O_TRACEVFORK;
 
+       /* Need fork for test. NOMMU has no forks */
+       if (NOMMU_SYSTEM)
+               goto worked; /* be bold, and pretend that test succeeded */
+
        pid = fork();
        if (pid < 0)
                perror_msg_and_die("fork");
@@ -1299,6 +1308,7 @@ test_ptrace_setoptions_followfork(void)
                }
        }
        if (expected_grandchild && expected_grandchild == found_grandchild) {
+ worked:
                ptrace_setoptions |= test_options;
                if (debug_flag)
                        fprintf(stderr, "ptrace_setoptions = %#x\n",
@@ -1332,9 +1342,9 @@ test_ptrace_setoptions_for_all(void)
        int pid;
        int it_worked = 0;
 
-       /* this fork test doesn't work on no-mmu systems */
+       /* Need fork for test. NOMMU has no forks */
        if (NOMMU_SYSTEM)
-               return 0; /* be bold, and pretend that test succeeded */
+               goto worked; /* be bold, and pretend that test succeeded */
 
        pid = fork();
        if (pid < 0)
@@ -1398,6 +1408,7 @@ test_ptrace_setoptions_for_all(void)
        }
 
        if (it_worked) {
+ worked:
                syscall_trap_sig = (SIGTRAP | 0x80);
                ptrace_setoptions |= test_options;
                if (debug_flag)
@@ -1417,7 +1428,7 @@ test_ptrace_seize(void)
 {
        int pid;
 
-       /* this fork test doesn't work on no-mmu systems */
+       /* Need fork for test. NOMMU has no forks */
        if (NOMMU_SYSTEM) {
                post_attach_sigstop = 0; /* this sets use_seize to 1 */
                return;
@@ -1770,7 +1781,6 @@ init(int argc, char *argv[])
         * in the startup_child() mode we kill the spawned process anyway.
         */
        if (argv[0]) {
-               skip_startup_execve = 1;
                startup_child(argv);
        }