proc_detach: use ptrace(PT_KILL) to kill the tracee

When MFC'ing commit dad11f990e to stable/12, the child would dump core
when dtrace exited.  It was getting SIGTRAP, even though proc_detach
sent a SIGKILL.  I could not find the reason for this difference in
behavior from main (and stable/13).  The present change, however, works
as expected, probably due the proc_wkilled special case in kern_ptrace.
It also seems like a more obvious approach.

While I'm here, fix two other issues in the previous code:

It would SIGKILL a tracee even in read-only mode.

It would SIGSTOP/SIGCONT the tracee if ptrace succeeded but errno happened
to be EBUSY for some other reason.

Reviewed by:	markj
MFC after:	1 week
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D41122
This commit is contained in:
Eric van Gyzen
2023-07-25 11:58:11 -05:00
parent bcbce2a29b
commit be1dd8e65b
+4 -8
View File
@@ -85,25 +85,21 @@ int
proc_detach(struct proc_handle *phdl, int reason)
{
int status;
int request;
pid_t pid;
if (phdl == NULL)
return (EINVAL);
if (reason == PRELEASE_HANG)
return (EINVAL);
if (reason == PRELEASE_KILL) {
kill(proc_getpid(phdl), SIGKILL);
goto free;
}
if ((phdl->flags & PATTACH_RDONLY) != 0)
goto free;
request = (reason == PRELEASE_KILL) ? PT_KILL : PT_DETACH;
pid = proc_getpid(phdl);
if (ptrace(PT_DETACH, pid, 0, 0) != 0 && errno == ESRCH)
goto free;
if (errno == EBUSY) {
if (ptrace(request, pid, 0, 0) != 0 && errno == EBUSY) {
kill(pid, SIGSTOP);
waitpid(pid, &status, WUNTRACED);
ptrace(PT_DETACH, pid, 0, 0);
ptrace(request, pid, 0, 0);
kill(pid, SIGCONT);
}
free: