diff options
author | Mark Johnston <markj@FreeBSD.org> | 2024-03-31 18:11:47 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2024-03-31 18:11:47 +0000 |
commit | 43b4da44118e4fe29e9d7456db4390c9cbb53636 (patch) | |
tree | 3b4ba450382f410bb0fc769c887faf250d657bc1 /tests/sys | |
parent | d68c68693e110353f70b5c04f8de416cf5766eca (diff) | |
download | src-43b4da44118e4fe29e9d7456db4390c9cbb53636.tar.gz src-43b4da44118e4fe29e9d7456db4390c9cbb53636.zip |
Diffstat (limited to 'tests/sys')
-rw-r--r-- | tests/sys/kern/ptrace_test.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/tests/sys/kern/ptrace_test.c b/tests/sys/kern/ptrace_test.c index bd176e2963f0..b65c84144ad0 100644 --- a/tests/sys/kern/ptrace_test.c +++ b/tests/sys/kern/ptrace_test.c @@ -4368,6 +4368,52 @@ ATF_TC_BODY(ptrace__PT_SC_REMOTE_getpid, tc) ATF_REQUIRE(ptrace(PT_DETACH, fpid, (caddr_t)1, 0) != -1); } +/* + * Ensure that procctl(PROC_REAP_KILL) won't block forever waiting for a target + * process that stopped to report its status to a debugger. + */ +ATF_TC_WITHOUT_HEAD(ptrace__reap_kill_stopped); +ATF_TC_BODY(ptrace__reap_kill_stopped, tc) +{ + struct procctl_reaper_kill prk; + pid_t debuggee, wpid; + int error, status; + + REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); + + debuggee = fork(); + ATF_REQUIRE(debuggee >= 0); + if (debuggee == 0) { + trace_me(); + for (;;) + sleep(10); + _exit(0); + } + wpid = waitpid(debuggee, &status, 0); + REQUIRE_EQ(wpid, debuggee); + ATF_REQUIRE(WIFSTOPPED(status)); + REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); + + /* Resume the child and ask it to stop during syscall exits. */ + ATF_REQUIRE(ptrace(PT_TO_SCX, debuggee, (caddr_t)1, 0) != -1); + + /* Give the debuggee some time to go to sleep. */ + usleep(100000); + + /* + * Kill the child process. procctl() may attempt to stop the target + * process to prevent it from adding new children to the reaper subtree, + * and this should not conflict with the child stopping itself for the + * debugger. + */ + memset(&prk, 0, sizeof(prk)); + prk.rk_sig = SIGTERM; + error = procctl(P_PID, getpid(), PROC_REAP_KILL, &prk); + REQUIRE_EQ(error, 0); + REQUIRE_EQ(1, prk.rk_killed); + REQUIRE_EQ(-1, prk.rk_fpid); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); @@ -4434,6 +4480,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, ptrace__procdesc_wait_child); ATF_TP_ADD_TC(tp, ptrace__procdesc_reparent_wait_child); ATF_TP_ADD_TC(tp, ptrace__PT_SC_REMOTE_getpid); + ATF_TP_ADD_TC(tp, ptrace__reap_kill_stopped); return (atf_no_error()); } |