From a68096576afc07e51d33b49c432d658b27a7f13c Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 10 Nov 2008 17:14:58 +0000 Subject: [PATCH] 2008-09-29 Dmitry V. Levin * strace.c (startup_child): Save child pid for future use. (main): Exit/kill ourself with straced child's exitcode/signal. (trace): If signalled process pid matches the saved child pid, save the signal number. If terminated process pid matches the saved child pid, save its exit status. Patch from Denys Vlasenko --- ChangeLog | 9 +++++++++ strace.c | 26 ++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb01c5d2b6..688476c70e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-09-29 Dmitry V. Levin + + * strace.c (startup_child): Save child pid for future use. + (main): Exit/kill ourself with straced child's exitcode/signal. + (trace): If signalled process pid matches the saved child pid, + save the signal number. If terminated process pid matches the + saved child pid, save its exit status. + Patch from Denys Vlasenko + 2008-09-12 Tomas Pospisek Jan Kratochvil diff --git a/strace.c b/strace.c index cab3489a81..9f3c7247c6 100644 --- a/strace.c +++ b/strace.c @@ -85,6 +85,9 @@ static int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0; /* Sometimes we want to print only succeeding syscalls. */ int not_failing_only = 0; +static int exit_code = 0; +static int strace_child = 0; + static char *username = NULL; uid_t run_uid; gid_t run_gid; @@ -523,7 +526,8 @@ startup_child (char **argv) progname, filename); exit(1); } - switch (pid = fork()) { + strace_child = pid = fork(); + switch (pid) { case -1: perror("strace: fork"); cleanup(); @@ -879,7 +883,17 @@ main(int argc, char *argv[]) if (trace() < 0) exit(1); cleanup(); - exit(0); + fflush(NULL); + if (exit_code > 0xff) { + /* Child was killed by a signal, mimic that. */ + exit_code &= 0xff; + signal(exit_code, SIG_DFL); + raise(exit_code); + /* Paranoia - what if this signal is not fatal? + Exit with 128 + signo then. */ + exit_code += 128; + } + exit(exit_code); } int @@ -1783,7 +1797,7 @@ int pfd; switch (fork()) { case -1: perror("fork"); - _exit(0); + _exit(1); case 0: break; default: @@ -1807,7 +1821,7 @@ int pfd; if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { perror("getrlimit(RLIMIT_NOFILE, ...)"); - _exit(0); + _exit(1); } n = rl.rlim_cur; for (i = 0; i < n; i++) { @@ -2322,6 +2336,8 @@ Process %d attached (waiting for parent)\n", continue; } if (WIFSIGNALED(status)) { + if (pid == strace_child) + exit_code = 0x100 | WTERMSIG(status); if (!cflag && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { printleader(tcp); @@ -2341,6 +2357,8 @@ Process %d attached (waiting for parent)\n", continue; } if (WIFEXITED(status)) { + if (pid == strace_child) + exit_code = WEXITSTATUS(status); if (debug) fprintf(stderr, "pid %u exited\n", pid); if ((tcp->flags & TCB_ATTACHED)