git: 4048ccc6ae37 - main - kern_sig.c: extract the first stop handling into a helper

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 17 Apr 2025 20:45:03 UTC
The branch main has been updated by kib:

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

commit 4048ccc6ae374c015c31f7b35221d5da8fe7d63f
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-04-17 11:44:51 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-04-17 20:33:47 +0000

    kern_sig.c: extract the first stop handling into a helper
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D49678
---
 sys/kern/kern_sig.c | 43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 0ee58af7fbe4..520577961c3a 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -115,6 +115,8 @@ static int	filt_signal(struct knote *kn, long hint);
 static struct thread *sigtd(struct proc *p, int sig, bool fast_sigblock);
 static void	sigqueue_start(void);
 static void	sigfastblock_setpend(struct thread *td, bool resched);
+static void	sig_handle_first_stop(struct thread *td, struct proc *p,
+    int sig, bool ext);
 
 static uma_zone_t	ksiginfo_zone = NULL;
 const struct filterops sig_filtops = {
@@ -2820,6 +2822,29 @@ sig_suspend_threads(struct thread *td, struct proc *p)
 	}
 }
 
+static void
+sig_handle_first_stop(struct thread *td, struct proc *p, int sig, bool ext)
+{
+	if ((td->td_dbgflags & TDB_FSTP) == 0 &&
+	    ((p->p_flag2 & P2_PTRACE_FSTP) != 0 ||
+	    p->p_xthread != NULL))
+		return;
+
+	p->p_xsig = sig;
+	p->p_xthread = td;
+
+	/*
+	 * If we are on sleepqueue already, let sleepqueue
+	 * code decide if it needs to go sleep after attach.
+	 */
+	if (ext || td->td_wchan == NULL)
+		td->td_dbgflags &= ~TDB_FSTP;
+
+	p->p_flag2 &= ~P2_PTRACE_FSTP;
+	p->p_flag |= P_STOPPED_SIG | P_STOPPED_TRACE;
+	sig_suspend_threads(td, p);
+}
+
 /*
  * Stop the process for an event deemed interesting to the debugger. If si is
  * non-NULL, this is a signal exchange; the new signal requested by the
@@ -2880,24 +2905,8 @@ ptracestop(struct thread *td, int sig, ksiginfo_t *si)
 			 * already set p_xthread, the current thread will get
 			 * a chance to report itself upon the next iteration.
 			 */
-			if ((td->td_dbgflags & TDB_FSTP) != 0 ||
-			    ((p->p_flag2 & P2_PTRACE_FSTP) == 0 &&
-			    p->p_xthread == NULL)) {
-				p->p_xsig = sig;
-				p->p_xthread = td;
+			sig_handle_first_stop(td, p, sig, false);
 
-				/*
-				 * If we are on sleepqueue already,
-				 * let sleepqueue code decide if it
-				 * needs to go sleep after attach.
-				 */
-				if (td->td_wchan == NULL)
-					td->td_dbgflags &= ~TDB_FSTP;
-
-				p->p_flag2 &= ~P2_PTRACE_FSTP;
-				p->p_flag |= P_STOPPED_SIG | P_STOPPED_TRACE;
-				sig_suspend_threads(td, p);
-			}
 			if ((td->td_dbgflags & TDB_STOPATFORK) != 0) {
 				td->td_dbgflags &= ~TDB_STOPATFORK;
 			}