From owner-dev-commits-src-all@freebsd.org Tue May 25 15:22:57 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D31BF64ECA0; Tue, 25 May 2021 15:22:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FqHrx5bHFz3JPJ; Tue, 25 May 2021 15:22:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 960391FE7C; Tue, 25 May 2021 15:22:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 14PFMveM013083; Tue, 25 May 2021 15:22:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 14PFMvZa013082; Tue, 25 May 2021 15:22:57 GMT (envelope-from git) Date: Tue, 25 May 2021 15:22:57 GMT Message-Id: <202105251522.14PFMvZa013082@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: fd3ac06f452f - main - ptrace: add an option to not kill debuggees on debugger exit MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: fd3ac06f452f47332e2f6fec8347579265c96104 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 25 May 2021 15:22:57 -0000 The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=fd3ac06f452f47332e2f6fec8347579265c96104 commit fd3ac06f452f47332e2f6fec8347579265c96104 Author: Konstantin Belousov AuthorDate: 2021-05-18 16:26:22 +0000 Commit: Konstantin Belousov 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 #include #include +#include #include #include #include /* 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)