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.
This commit is contained in:
Дмитрий Левин 2017-05-27 15:58:54 +00:00
parent e0fd7e7035
commit e97a66faa1
2 changed files with 10 additions and 10 deletions

1
NEWS
View File

@ -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)
===============================================

View File

@ -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, &params_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, &params_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.