diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2022-01-12 08:21:19 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2022-01-19 00:46:08 +0000 |
commit | 29887e602b6e00d886348f3a5a65dc0070a7d7ef (patch) | |
tree | 07b9892706fa98fd23140fb4fcbd2f9f6610f55c | |
parent | 7545bb2ba726e6262d11b699ce88df90d9739d3d (diff) |
truss(1): detach more carefully
(cherry picked from commit 12f747e6ff675edfc1f2f95f7fc435dc01e0c29c)
-rw-r--r-- | usr.bin/truss/setup.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c index 78be0c7f570f..d98e618d9c43 100644 --- a/usr.bin/truss/setup.c +++ b/usr.bin/truss/setup.c @@ -223,11 +223,24 @@ restore_proc(int signo __unused) static void detach_proc(pid_t pid) { + int sig, status; - /* stop the child so that we can detach */ + /* + * Stop the child so that we can detach. Filter out possible + * lingering SIGTRAP events buffered in the threads. + */ kill(pid, SIGSTOP); - if (waitpid(pid, NULL, 0) < 0) - err(1, "Unexpected stop in waitpid"); + for (;;) { + if (waitpid(pid, &status, 0) < 0) + err(1, "Unexpected error in waitpid"); + sig = WIFSTOPPED(status) ? WSTOPSIG(status) : 0; + if (sig == SIGSTOP) + break; + if (sig == SIGTRAP) + sig = 0; + if (ptrace(PT_CONTINUE, pid, (caddr_t)1, sig) < 0) + err(1, "Can not continue for detach"); + } if (ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) err(1, "Can not detach the process"); |