diff options
author | zont <zont@FreeBSD.org> | 2012-09-12 13:06:57 +0000 |
---|---|---|
committer | zont <zont@FreeBSD.org> | 2012-09-12 13:06:57 +0000 |
commit | 907a148c9fb470dbf8e24ed46c37ef13788929e6 (patch) | |
tree | 6e08361c9ce542272c7c5f927f7965b9c5f725a7 /usr.bin/truss/main.c | |
parent | 05d54cfa61ef04e334ab3137b05cb4021e4f8515 (diff) | |
download | FreeBSD-src-907a148c9fb470dbf8e24ed46c37ef13788929e6.zip FreeBSD-src-907a148c9fb470dbf8e24ed46c37ef13788929e6.tar.gz |
- Fix detaching under some circumstances.
When truss is detaching from very active process it is possible to
hang on waitpid(2) in restore_proc() forever, because
ptrace(PT_SYSCALL) must be called before detaching, to allow the
debugging process to continue execution. Also when truss called with
'-c' argument, it does not print anything after detach, because it
immediately exits from restore_proc().
To fix these two problems make detaching deferred, but then it is
impossible to detach from a process which does not do any system call.
To fix this issue use sigaction(2) instead of signal(3) to disable
SA_RESTART flag for waitpid(2) that makes it non-restartable. Remove
global variable child_pid, because now detaching is handled in context
where child's pid is known.
Reported by: mjg
Tested by: mjg, swills
Approved by: kib (mentor)
MFC after: 2 weeks
Diffstat (limited to 'usr.bin/truss/main.c')
-rw-r--r-- | usr.bin/truss/main.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index d6a1edc..cb97293 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); } @@ -366,7 +370,8 @@ START_TRACE: default: break; } - } while (trussinfo->pr_why != S_EXIT); + } while (trussinfo->pr_why != S_EXIT && + trussinfo->pr_why != S_DETACHED); if (trussinfo->flags & FOLLOWFORKS) { do { |