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 @@ -4368,6 +4368,48 @@ ATF_REQUIRE(ptrace(PT_DETACH, fpid, (caddr_t)1, 0) != -1); } +/* + * Make sure that procctl(PROC_REAP_KILL) can kill a process that's stopped + * waiting for 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, killer, wpid; + int status; + + REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); + + debuggee = fork(); + ATF_REQUIRE(debuggee >= 0); + if (debuggee == 0) { + trace_me(); + exit(0); + } + attach_child(debuggee); + + killer = fork(); + ATF_REQUIRE(killer >= 0); + if (killer == 0) { + int error; + + memset(&prk, 0, sizeof(prk)); + prk.rk_sig = SIGINT; + errno = 0; + error = procctl(P_PID, getppid(), PROC_REAP_KILL, &prk); + CHILD_REQUIRE_EQ(error, 0); + CHILD_REQUIRE_EQ(1, prk.rk_killed); + CHILD_REQUIRE_EQ(-1, prk.rk_fpid); + _exit(errno); + } + + wpid = waitpid(killer, &status, 0); + REQUIRE_EQ(wpid, killer); + ATF_REQUIRE_MSG(WEXITSTATUS(status) == 0, + "killer failed with error %d", WEXITSTATUS(status)); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); @@ -4434,6 +4476,7 @@ 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()); }