Date: Tue, 1 Jun 2021 00:50:45 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 9c74a2068109 - stable/13 - ptrace: add an option to not kill debuggees on debugger exit Message-ID: <202106010050.1510oj9r082964@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=9c74a2068109b8a4b2dd0d98fb1ff0ebe48aa3a3 commit 9c74a2068109b8a4b2dd0d98fb1ff0ebe48aa3a3 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-05-18 16:26:22 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-06-01 00:38:54 +0000 ptrace: add an option to not kill debuggees on debugger exit (cherry picked from commit fd3ac06f452f47332e2f6fec8347579265c96104) --- lib/libc/sys/ptrace.2 | 27 ++++++++++++++++++++++++++- sys/kern/kern_exit.c | 24 ++++++++++++++++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/lib/libc/sys/ptrace.2 b/lib/libc/sys/ptrace.2 index 6148e6d333d5..43ec2b76bbfd 100644 --- a/lib/libc/sys/ptrace.2 +++ b/lib/libc/sys/ptrace.2 @@ -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 April 10, 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 diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index e1b40a171345..cb5996982a3a 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106010050.1510oj9r082964>