git: f0ba6535d446 - stable/14 - sig_handle_first_stop(): notify debugger
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 03 May 2025 15:20:05 UTC
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);