Page MenuHomeFreeBSD

D49678.id153739.diff
No OneTemporary

D49678.id153739.diff

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -115,6 +115,8 @@
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_fstp(struct thread *td, struct proc *p, int sig,
+ bool ext);
static uma_zone_t ksiginfo_zone = NULL;
const struct filterops sig_filtops = {
@@ -2363,6 +2365,15 @@
if (prop & SIGPROP_CONT)
sigqueue_delete_stopmask_proc(p);
else if (prop & SIGPROP_STOP) {
+ if ((p->p_flag & P_TRACED) != 0 &&
+ (p->p_flag2 & P2_PTRACE_FSTP) != 0) {
+ td->td_dbgflags |= TDB_FSTP;
+ PROC_SLOCK(p);
+ sig_handle_fstp(td, p, sig, true);
+ PROC_SUNLOCK(p);
+ return (0);
+ }
+
/*
* If sending a tty stop signal to a member of an orphaned
* process group, discard the signal here if the action
@@ -2820,6 +2831,29 @@
}
}
+static void
+sig_handle_fstp(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 +2914,8 @@
* 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_fstp(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;
}
@@ -3336,20 +3354,6 @@
}
}
- if ((p->p_flag & (P_TRACED | P_PPTRACE)) == P_TRACED &&
- (p->p_flag2 & P2_PTRACE_FSTP) != 0 &&
- SIGISMEMBER(sigpending, SIGSTOP)) {
- /*
- * If debugger just attached, always consume
- * SIGSTOP from ptrace(PT_ATTACH) first, to
- * execute the debugger attach ritual in
- * order.
- */
- td->td_dbgflags |= TDB_FSTP;
- SIGEMPTYSET(sigpending);
- SIGADDSET(sigpending, SIGSTOP);
- }
-
SIG_FOREACH(sig, &sigpending) {
switch (sigprocess(td, sig)) {
case SIGSTATUS_HANDLE:
diff --git a/tests/sys/kern/ptrace_test.c b/tests/sys/kern/ptrace_test.c
--- a/tests/sys/kern/ptrace_test.c
+++ b/tests/sys/kern/ptrace_test.c
@@ -4378,7 +4378,10 @@
exit(0);
}
- attach_child(fpid);
+ wpid = waitpid(fpid, &status, 0);
+ REQUIRE_EQ(wpid, fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ REQUIRE_EQ(WSTOPSIG(status), SIGSTOP);
pscr.pscr_syscall = SYS_getpid;
pscr.pscr_nargs = 0;

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 5:25 AM (19 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28542679
Default Alt Text
D49678.id153739.diff (3 KB)

Event Timeline