diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index d6a1edc..ade6c7b 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -163,6 +163,7 @@ strsig(int sig) int main(int ac, char **av) { + struct sigaction sa; struct ex_types *funcs; struct trussinfo *trussinfo; char *fname; @@ -257,10 +258,13 @@ main(int ac, char **av) signal(SIGTERM, SIG_IGN); signal(SIGQUIT, SIG_IGN); } else { + sa.sa_handler = restore_proc; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); start_tracing(trussinfo->pid); - signal(SIGINT, restore_proc); - signal(SIGTERM, restore_proc); - signal(SIGQUIT, restore_proc); } diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c index b4c61e1..2670355 100644 --- a/usr.bin/truss/setup.c +++ b/usr.bin/truss/setup.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include "extern.h" static pid_t child_pid; +static sig_atomic_t detaching; /* * setup_and_wait() is called to start a process. All it really does @@ -70,7 +71,6 @@ int setup_and_wait(char *command[]) { pid_t pid; - int waitval; pid = vfork(); if (pid == -1) @@ -82,10 +82,8 @@ setup_and_wait(char *command[]) } /* Only in the parent here */ - if (waitpid(pid, &waitval, 0) < 0) { + if (waitpid(pid, NULL, 0) < 0) err(1, "unexpect stop in waitpid"); - return 0; - } child_pid = pid; @@ -101,7 +99,7 @@ setup_and_wait(char *command[]) int start_tracing(pid_t pid) { - int ret, retry, waitval; + int ret, retry; retry = 10; do { @@ -112,7 +110,7 @@ start_tracing(pid_t pid) err(1, "can not attach to target process"); child_pid = pid; - if (waitpid(pid, &waitval, 0) < 0) + if (waitpid(pid, NULL, 0) < 0) err(1, "Unexpect stop in waitpid"); return (0); @@ -127,12 +125,14 @@ start_tracing(pid_t pid) void restore_proc(int signo __unused) { - int waitval; - /* stop the child so that we can detach */ kill(child_pid, SIGSTOP); - if (waitpid(child_pid, &waitval, 0) < 0) - err(1, "Unexpected stop in waitpid"); + detaching = 1; +} + +static void +detach_proc(void) +{ if (ptrace(PT_DETACH, child_pid, (caddr_t)1, 0) < 0) err(1, "Can not detach the process"); @@ -183,8 +183,15 @@ waitevent(struct trussinfo *info) ptrace(PT_SYSCALL, info->pid, (caddr_t)1, pending_signal); pending_signal = 0; - if (waitpid(info->pid, &waitval, 0) < 0) +retry: + if (waitpid(info->pid, &waitval, 0) == -1) { + if (errno == EINTR) + goto retry; err(1, "Unexpected stop in waitpid"); + } + + if (detaching) + detach_proc(); if (WIFCONTINUED(waitval)) { info->pr_why = S_NONE;