From: Dmitry V. Levin Date: Sat, 27 May 2017 15:58:54 +0000 (+0000) Subject: Do not reset SIGCHLD handler in tracees to SIG_DFL X-Git-Tag: v4.18~158 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=v4.17-8-ge97a66f;p=strace Do not reset SIGCHLD handler in tracees to SIG_DFL While strace resets SIGCHLD handler to the default action so that waitpid definitely works without losing track of children, tracees should not inherit this change. * strace.c (struct exec_params): Add child_sa field. (init): When setting SIGCHLD handler to SIG_DFL, save the old handler. (exec_or_die): Restore SIGCHLD handler if it was different from SIG_DFL at startup. * NEWS: Mention this change. --- diff --git a/NEWS b/NEWS index 80479a15..5866e69a 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ Noteworthy changes in release ?.?? (????-??-??) * Bug fixes * In interactive mode (-I2), those signals that were blocked at startup will remain blocked for the whole period of strace execution. + * strace no longer resets SIGCHLD handler in tracees to the default action. Noteworthy changes in release 4.17 (2017-05-24) =============================================== diff --git a/strace.c b/strace.c index 07d5adac..473572fa 100644 --- a/strace.c +++ b/strace.c @@ -1200,6 +1200,7 @@ struct exec_params { gid_t run_egid; char **argv; char *pathname; + struct sigaction child_sa; }; static struct exec_params params_for_tracee; @@ -1254,6 +1255,9 @@ exec_or_die(void) alarm(0); } + if (params_for_tracee.child_sa.sa_handler != SIG_DFL) + sigaction(SIGCHLD, ¶ms_for_tracee.child_sa, NULL); + execv(params->pathname, params->argv); perror_msg_and_die("exec"); } @@ -1622,13 +1626,6 @@ init(int argc, char *argv[]) progname = argv[0] ? argv[0] : "strace"; - /* Make sure SIGCHLD has the default action so that waitpid - definitely works without losing track of children. The user - should not have given us a bogus state to inherit, but he might - have. Arguably we should detect SIG_IGN here and pass it on - to children, but probably noone really needs that. */ - signal(SIGCHLD, SIG_DFL); - strace_tracer_pid = getpid(); os_release = get_os_release(); @@ -1821,6 +1818,11 @@ init(int argc, char *argv[]) tflag = 1; } + sigprocmask(SIG_SETMASK, NULL, &start_set); + memcpy(&blocked_set, &start_set, sizeof(blocked_set)); + + set_sigaction(SIGCHLD, SIG_DFL, ¶ms_for_tracee.child_sa); + #ifdef USE_LIBUNWIND if (stack_trace_enabled) { unsigned int tcbi; @@ -1913,9 +1915,6 @@ init(int argc, char *argv[]) if (!opt_intr) opt_intr = INTR_WHILE_WAIT; - sigprocmask(SIG_SETMASK, NULL, &start_set); - memcpy(&blocked_set, &start_set, sizeof(blocked_set)); - /* * startup_child() must be called before the signal handlers get * installed below as they are inherited into the spawned process.