Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 May 2021 15:22:57 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: fd3ac06f452f - main - ptrace: add an option to not kill debuggees on debugger exit
Message-ID:  <202105251522.14PFMvZa013082@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=fd3ac06f452f47332e2f6fec8347579265c96104

commit fd3ac06f452f47332e2f6fec8347579265c96104
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-05-18 16:26:22 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-05-25 15:22:34 +0000

    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
---
 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 0135db98dc97..504891597dab 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 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
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?202105251522.14PFMvZa013082>