Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 May 2025 15:20:05 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: f0ba6535d446 - stable/14 - sig_handle_first_stop(): notify debugger
Message-ID:  <202505031520.543FK5k6048766@gitrepo.freebsd.org>

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

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

commit f0ba6535d446ed79b628e3cd27a971131752ee44
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-04-23 16:51:12 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-05-03 15:19:41 +0000

    sig_handle_first_stop(): notify debugger
    
    (cherry picked from commit 2f87445747430b4ca2e1d344550d9befb54226e7)
    (cherry picked from commit 4f32b298c679271243855083d20306563f815f17)
---
 sys/kern/kern_sig.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 0f87b8db9244..84bac9fc77ed 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -110,7 +110,7 @@ static int	issignal(struct thread *td);
 static void	reschedule_signals(struct proc *p, sigset_t block, int flags);
 static int	sigprop(int sig);
 static void	tdsigwakeup(struct thread *, int, sig_t, int);
-static int	sig_suspend_threads(struct thread *, struct proc *);
+static int	sig_suspend_threads(struct thread *, struct proc *, bool *);
 static int	filt_sigattach(struct knote *kn);
 static void	filt_sigdetach(struct knote *kn);
 static int	filt_signal(struct knote *kn, long hint);
@@ -2534,12 +2534,14 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
 		MPASS(action == SIG_DFL);
 
 		if (prop & SIGPROP_STOP) {
+			bool res;
+
 			if (p->p_flag & (P_PPWAIT|P_WEXIT))
 				goto out;
 			p->p_flag |= P_STOPPED_SIG;
 			p->p_xsig = sig;
 			PROC_SLOCK(p);
-			wakeup_swapper = sig_suspend_threads(td, p);
+			wakeup_swapper = sig_suspend_threads(td, p, &res);
 			if (p->p_numthreads == p->p_suspcount) {
 				/*
 				 * only thread sending signal to another
@@ -2804,16 +2806,26 @@ ptrace_remotereq(struct thread *td, int flag)
 	wakeup(p);
 }
 
+/*
+ * Suspend threads of the process p, either by directly setting the
+ * inhibitor for the thread sleeping interruptibly, or by making the
+ * thread suspend at the userspace boundary by scheduling a suspend AST.
+ *
+ * *resp returns true if some threads were suspended directly from the
+ * sleeping state, and false if all threads are forced to process AST.
+ */
 static int
-sig_suspend_threads(struct thread *td, struct proc *p)
+sig_suspend_threads(struct thread *td, struct proc *p, bool *resp)
 {
 	struct thread *td2;
 	int wakeup_swapper;
+	bool res;
 
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	PROC_SLOCK_ASSERT(p, MA_OWNED);
 
 	wakeup_swapper = 0;
+	res = false;
 	FOREACH_THREAD_IN_PROC(p, td2) {
 		thread_lock(td2);
 		ast_sched_locked(td2, TDA_SUSPEND);
@@ -2833,8 +2845,10 @@ sig_suspend_threads(struct thread *td, struct proc *p)
 					    TD_SBDRY_ERRNO(td2));
 					continue;
 				}
-			} else if (!TD_IS_SUSPENDED(td2))
+			} else if (!TD_IS_SUSPENDED(td2)) {
 				thread_suspend_one(td2);
+				res = true;
+			}
 		} else if (!TD_IS_SUSPENDED(td2)) {
 #ifdef SMP
 			if (TD_IS_RUNNING(td2) && td2 != td)
@@ -2843,12 +2857,15 @@ sig_suspend_threads(struct thread *td, struct proc *p)
 		}
 		thread_unlock(td2);
 	}
+	*resp = res;
 	return (wakeup_swapper);
 }
 
 static void
 sig_handle_first_stop(struct thread *td, struct proc *p, int sig)
 {
+	bool res;
+
 	if (td != NULL && (td->td_dbgflags & TDB_FSTP) == 0 &&
 	    ((p->p_flag2 & P2_PTRACE_FSTP) != 0 || p->p_xthread != NULL))
 		return;
@@ -2865,7 +2882,9 @@ sig_handle_first_stop(struct thread *td, struct proc *p, int sig)
 
 	p->p_flag2 &= ~P2_PTRACE_FSTP;
 	p->p_flag |= P_STOPPED_SIG | P_STOPPED_TRACE;
-	sig_suspend_threads(td, p);
+	sig_suspend_threads(td, p, &res);
+	if (res && td == NULL)
+		thread_stopped(p);
 }
 
 /*
@@ -3267,6 +3286,8 @@ sigprocess(struct thread *td, int sig)
 		 */
 		prop = sigprop(sig);
 		if (prop & SIGPROP_STOP) {
+			bool res;
+
 			mtx_unlock(&ps->ps_mtx);
 			if ((p->p_flag & (P_TRACED | P_WEXIT |
 			    P_SINGLE_EXIT)) != 0 || ((p->p_pgrp->
@@ -3288,7 +3309,7 @@ sigprocess(struct thread *td, int sig)
 			p->p_flag |= P_STOPPED_SIG;
 			p->p_xsig = sig;
 			PROC_SLOCK(p);
-			sig_suspend_threads(td, p);
+			sig_suspend_threads(td, p, &res);
 			thread_suspend_switch(td, p);
 			PROC_SUNLOCK(p);
 			mtx_lock(&ps->ps_mtx);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505031520.543FK5k6048766>