ptrace: add an option to not kill debuggees on debugger exit
Requested by: markj Reviewed by: jhb (previous version) Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differrential revision: https://reviews.freebsd.org/D30351
This commit is contained in:
parent
d7a7ea5be6
commit
fd3ac06f45
@ -2,7 +2,7 @@
|
||||
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
|
||||
.\"
|
||||
.\" This file is in the public domain.
|
||||
.Dd May 4, 2021
|
||||
.Dd May 20, 2021
|
||||
.Dt PTRACE 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -99,6 +99,30 @@ will report a
|
||||
signal.
|
||||
All other additional signal stops use
|
||||
.Dv SIGTRAP .
|
||||
.Sh DETACH AND TERMINATION
|
||||
.Pp
|
||||
Normally, exiting tracing process should wait for all pending
|
||||
debugging events and then detach from all alive traced processes
|
||||
before exiting using
|
||||
.Dv PT_DETACH
|
||||
request.
|
||||
If tracing process exits without detaching, for instance due to abnormal
|
||||
termination, the destiny of the traced children processes is determined
|
||||
by the
|
||||
.Dv kern.kill_on_debugger_exit
|
||||
sysctl control.
|
||||
.Pp
|
||||
If the control is set to the default value 1, such traced processes
|
||||
are terminated.
|
||||
If set to zero, kernel implicitly detaches traced processes.
|
||||
Traced processes are un-stopped if needed, and then continue the execution
|
||||
without tracing.
|
||||
Kernel drops any
|
||||
.Dv SIGTRAP
|
||||
signals queued to the traced children, which could be either generated by
|
||||
not yet consumed debug events, or sent by other means, the later should
|
||||
not be done anyway.
|
||||
.Sh TRACING EVENTS
|
||||
.Pp
|
||||
Each traced process has a tracing event mask.
|
||||
An event in the traced process only reports a
|
||||
@ -216,6 +240,7 @@ includes only
|
||||
.Dv PTRACE_EXEC
|
||||
events.
|
||||
All other event flags are disabled.
|
||||
.Sh PTRACE REQUESTS
|
||||
.Pp
|
||||
The
|
||||
.Fa request
|
||||
|
@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sched.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/acct.h> /* for acct_process() function prototype */
|
||||
@ -99,6 +100,11 @@ dtrace_execexit_func_t dtrace_fasttrap_exit;
|
||||
SDT_PROVIDER_DECLARE(proc);
|
||||
SDT_PROBE_DEFINE1(proc, , , exit, "int");
|
||||
|
||||
static int kern_kill_on_dbg_exit = 1;
|
||||
SYSCTL_INT(_kern, OID_AUTO, kill_on_debugger_exit, CTLFLAG_RWTUN,
|
||||
&kern_kill_on_dbg_exit, 0,
|
||||
"Kill ptraced processes when debugger exits");
|
||||
|
||||
struct proc *
|
||||
proc_realparent(struct proc *child)
|
||||
{
|
||||
@ -504,8 +510,9 @@ exit1(struct thread *td, int rval, int signo)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Traced processes are killed since their existence
|
||||
* means someone is screwing up.
|
||||
* Traced processes are killed by default
|
||||
* since their existence means someone is
|
||||
* screwing up.
|
||||
*/
|
||||
t = proc_realparent(q);
|
||||
if (t == p) {
|
||||
@ -522,14 +529,23 @@ exit1(struct thread *td, int rval, int signo)
|
||||
* orphan link for q now while q is locked.
|
||||
*/
|
||||
proc_clear_orphan(q);
|
||||
q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
|
||||
q->p_flag &= ~P_TRACED;
|
||||
q->p_flag2 &= ~P2_PTRACE_FSTP;
|
||||
q->p_ptevents = 0;
|
||||
p->p_xthread = NULL;
|
||||
FOREACH_THREAD_IN_PROC(q, tdt) {
|
||||
tdt->td_dbgflags &= ~(TDB_SUSPEND | TDB_XSIG |
|
||||
TDB_FSTP);
|
||||
tdt->td_xsig = 0;
|
||||
}
|
||||
if (kern_kill_on_dbg_exit) {
|
||||
q->p_flag &= ~P_STOPPED_TRACE;
|
||||
kern_psignal(q, SIGKILL);
|
||||
} else if ((q->p_flag & (P_STOPPED_TRACE |
|
||||
P_STOPPED_SIG)) != 0) {
|
||||
sigqueue_delete_proc(q, SIGTRAP);
|
||||
ptrace_unsuspend(q);
|
||||
}
|
||||
kern_psignal(q, SIGKILL);
|
||||
}
|
||||
PROC_UNLOCK(q);
|
||||
if (ksi != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user