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:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user