git: f87811ca3bc1 - main - sig_handle_first_stop(): allow NULL leader thread

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sun, 27 Apr 2025 21:52:48 UTC
The branch main has been updated by kib:

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

commit f87811ca3bc110af29e3a0e341d241c292dc8424
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-04-21 12:54:32 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-04-27 21:52:12 +0000

    sig_handle_first_stop(): allow NULL leader thread
    
    Remove the ext argument, the ext condition is indicated by NULL td.
    If the td argument is NULL, p_xthread is set to NULL, for initial
    attach. Previous commit prepared ptrace() code for the case.
    
    sig_suspend_thread() only uses the td arg to avoid interrupting the
    current thread as micro-optimization, so it is fine to pass NULL.
    
    Tested by:      pho
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D49961
---
 sys/kern/kern_sig.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 91287b3c1f87..2724944bb7a2 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -116,7 +116,7 @@ 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);
+    int sig);
 
 static uma_zone_t	ksiginfo_zone = NULL;
 const struct filterops sig_filtops = {
@@ -2373,9 +2373,8 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
 		if (pt_attach_transparent &&
 		    (p->p_flag & P_TRACED) != 0 &&
 		    (p->p_flag2 & P2_PTRACE_FSTP) != 0) {
-			td->td_dbgflags |= TDB_FSTP;
 			PROC_SLOCK(p);
-			sig_handle_first_stop(td, p, sig, true);
+			sig_handle_first_stop(NULL, p, sig);
 			PROC_SUNLOCK(p);
 			return (0);
 		}
@@ -2838,11 +2837,10 @@ 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)
+sig_handle_first_stop(struct thread *td, struct proc *p, int sig)
 {
-	if ((td->td_dbgflags & TDB_FSTP) == 0 &&
-	    ((p->p_flag2 & P2_PTRACE_FSTP) != 0 ||
-	    p->p_xthread != NULL))
+	if (td != NULL && (td->td_dbgflags & TDB_FSTP) == 0 &&
+	    ((p->p_flag2 & P2_PTRACE_FSTP) != 0 || p->p_xthread != NULL))
 		return;
 
 	p->p_xsig = sig;
@@ -2852,7 +2850,7 @@ sig_handle_first_stop(struct thread *td, struct proc *p, int sig, bool ext)
 	 * If we are on sleepqueue already, let sleepqueue
 	 * code decide if it needs to go sleep after attach.
 	 */
-	if (ext || td->td_wchan == NULL)
+	if (td != NULL && td->td_wchan == NULL)
 		td->td_dbgflags &= ~TDB_FSTP;
 
 	p->p_flag2 &= ~P2_PTRACE_FSTP;
@@ -2920,7 +2918,7 @@ 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.
 			 */
-			sig_handle_first_stop(td, p, sig, false);
+			sig_handle_first_stop(td, p, sig);
 
 			if ((td->td_dbgflags & TDB_STOPATFORK) != 0) {
 				td->td_dbgflags &= ~TDB_STOPATFORK;