Page MenuHomeFreeBSD

D49678.id153772.diff
No OneTemporary

D49678.id153772.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_first_stop(struct thread *td, struct proc *p,
+ int sig, bool ext);
static uma_zone_t ksiginfo_zone = NULL;
const struct filterops sig_filtops = {
@@ -172,6 +174,11 @@
"Discard ignored signals on delivery, otherwise queue them to "
"the target queue");
+static bool sigstop_transparent = true;
+SYSCTL_BOOL(_debug, OID_AUTO, sigstop_transparent, CTLFLAG_RWTUN,
+ &sigstop_transparent, 0,
+ "hide wakes from SIGSTOP on interruptible sleeps");
+
SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL);
/*
@@ -2363,6 +2370,16 @@
if (prop & SIGPROP_CONT)
sigqueue_delete_stopmask_proc(p);
else if (prop & SIGPROP_STOP) {
+ if (sigstop_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);
+ 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 +2837,29 @@
}
}
+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 +2920,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_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;
}
@@ -3336,7 +3360,8 @@
}
}
- if ((p->p_flag & (P_TRACED | P_PPTRACE)) == P_TRACED &&
+ if (!sigstop_transparent &&
+ (p->p_flag & (P_TRACED | P_PPTRACE)) == P_TRACED &&
(p->p_flag2 & P2_PTRACE_FSTP) != 0 &&
SIGISMEMBER(sigpending, SIGSTOP)) {
/*
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, 11:46 AM (21 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28477089
Default Alt Text
D49678.id153772.diff (3 KB)

Event Timeline