Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143505402
D50917.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D50917.diff
View Options
diff --git a/lib/libsys/ptrace.2 b/lib/libsys/ptrace.2
--- a/lib/libsys/ptrace.2
+++ b/lib/libsys/ptrace.2
@@ -1,7 +1,7 @@
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
.\"
.\" This file is in the public domain.
-.Dd August 18, 2023
+.Dd June 19, 2025
.Dt PTRACE 2
.Os
.Sh NAME
@@ -473,6 +473,16 @@
specifying an alternate place to continue execution, and after it
succeeds, the traced process is no longer traced and continues
execution normally.
+.Pp
+The parent of the traced process will be sent a
+.Dv SIGCHLD
+to indicate that the process has continued from a stopped state regardless of
+whether the process was in a stopped state prior to the corresponding
+.Dv PT_ATTACH
+request.
+A
+.Xr wait 2
+for the traced process would indicate that it had been continued.
.It Dv PT_GETREGS
This request reads the traced process's machine registers into the
.Do
diff --git a/lib/libsys/wait.2 b/lib/libsys/wait.2
--- a/lib/libsys/wait.2
+++ b/lib/libsys/wait.2
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 27, 2024
+.Dd June 19, 2025
.Dt WAIT 2
.Os
.Sh NAME
@@ -273,6 +273,10 @@
have continued from a job control stop by receiving a
.Dv SIGCONT
signal.
+.Xr ptrace 2
+can also cause a process to be continued, when a
+.Dv PT_DETACH
+request is issued to detach the debugger.
.It Dv WNOHANG
Do not block when
there are no processes wishing to report status.
@@ -450,7 +454,7 @@
.Bl -tag -width Ds
.It Fn WIFCONTINUED status
True if the process has not terminated, and
-has continued after a job control stop.
+has continued after a job control stop or detach of a debugger.
This macro can be true only if the wait call specified the
.Dv WCONTINUED
option.
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
@@ -2461,8 +2461,6 @@
PROC_SLOCK(p);
if (p->p_numthreads == p->p_suspcount) {
PROC_SUNLOCK(p);
- p->p_flag |= P_CONTINUED;
- p->p_xsig = SIGCONT;
PROC_LOCK(p->p_pptr);
childproc_continued(p);
PROC_UNLOCK(p->p_pptr);
@@ -3778,6 +3776,9 @@
void
childproc_continued(struct proc *p)
{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ p->p_flag |= P_CONTINUED;
+ p->p_xsig = SIGCONT;
childproc_jobstate(p, CLD_CONTINUED, SIGCONT);
}
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1324,8 +1324,15 @@
p->p_flag2 &= ~P2_PTRACE_FSTP;
}
- /* should we send SIGCHLD? */
- /* childproc_continued(p); */
+ /*
+ * Send SIGCHLD and wakeup the parent as needed. It
+ * may be the case that they had stopped the child
+ * before it got ptraced, and now they're in the middle
+ * of a wait(2) for it to continue.
+ */
+ PROC_LOCK(p->p_pptr);
+ childproc_continued(p);
+ PROC_UNLOCK(p->p_pptr);
break;
}
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
@@ -4523,6 +4523,73 @@
ATF_REQUIRE(timespeccmp(&shm->sleep_time, &twelve_sec, <=));
}
+ATF_TC_WITHOUT_HEAD(ptrace__PT_DETACH_continued);
+ATF_TC_BODY(ptrace__PT_DETACH_continued, tc)
+{
+ char buf[256];
+ pid_t debuggee, debugger;
+ int dpipe[2] = {-1, -1}, status;
+
+ /* Setup the debuggee's pipe, which we'll use to let it terminate. */
+ ATF_REQUIRE(pipe(dpipe) == 0);
+ ATF_REQUIRE((debuggee = fork()) != -1);
+
+ if (debuggee == 0) {
+ ssize_t readsz;
+
+ /*
+ * The debuggee will just absorb everything until the parent
+ * closes it. In the process, we expect it to get SIGSTOP'd,
+ * then ptrace(2)d and finally, it should resume after we detach
+ * and the parent will be notified.
+ */
+ close(dpipe[1]);
+ while ((readsz = read(dpipe[0], buf, sizeof(buf))) != 0) {
+ if (readsz > 0 || errno == EINTR)
+ continue;
+ _exit(1);
+ }
+
+ _exit(0);
+ }
+
+ close(dpipe[0]);
+
+ ATF_REQUIRE(kill(debuggee, SIGSTOP) == 0);
+ REQUIRE_EQ(waitpid(debuggee, &status, WUNTRACED), debuggee);
+ ATF_REQUIRE(WIFSTOPPED(status));
+
+ /* Child is stopped, enter the debugger to attach/detach. */
+ ATF_REQUIRE((debugger = fork()) != -1);
+ if (debugger == 0) {
+ REQUIRE_EQ(ptrace(PT_ATTACH, debuggee, 0, 0), 0);
+ REQUIRE_EQ(waitpid(debuggee, &status, 0), debuggee);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ REQUIRE_EQ(WSTOPSIG(status), SIGSTOP);
+
+ REQUIRE_EQ(ptrace(PT_DETACH, debuggee, 0, 0), 0);
+ _exit(0);
+ }
+
+ REQUIRE_EQ(waitpid(debugger, &status, 0), debugger);
+ ATF_REQUIRE(WIFEXITED(status));
+ REQUIRE_EQ(WEXITSTATUS(status), 0);
+
+ REQUIRE_EQ(waitpid(debuggee, &status, WCONTINUED), debuggee);
+ ATF_REQUIRE(WIFCONTINUED(status));
+
+ /*
+ * Closing the pipe will trigger the debuggee to exit now that the
+ * child has resumed following detach.
+ */
+ close(dpipe[1]);
+
+ REQUIRE_EQ(waitpid(debuggee, &status, 0), debuggee);
+ ATF_REQUIRE(WIFEXITED(status));
+ REQUIRE_EQ(WEXITSTATUS(status), 0);
+
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me);
@@ -4592,6 +4659,7 @@
ATF_TP_ADD_TC(tp, ptrace__PT_SC_REMOTE_getpid);
ATF_TP_ADD_TC(tp, ptrace__reap_kill_stopped);
ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_no_EINTR);
+ ATF_TP_ADD_TC(tp, ptrace__PT_DETACH_continued);
return (atf_no_error());
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 31, 7:07 PM (5 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28160238
Default Alt Text
D50917.diff (5 KB)
Attached To
Mode
D50917: kern: send parent a SIGCHLD when the debugger has detached
Attached
Detach File
Event Timeline
Log In to Comment