Index: sys/kern/kern_exit.c =================================================================== --- sys/kern/kern_exit.c +++ sys/kern/kern_exit.c @@ -355,6 +355,9 @@ */ PROC_LOCK(p); stopprofclock(p); + if ((p->p_flag & P_TRACED) != 0) { + p->p_flag2 |= P2_EXIT_TRACED; + } p->p_flag &= ~(P_TRACED | P_PPWAIT | P_PPTRACE); p->p_ptevents = 0; @@ -996,11 +999,14 @@ switch (idtype) { case P_ALL: - if (p->p_procdesc != NULL) { - PROC_UNLOCK(p); - return (0); + if (p->p_procdesc == NULL || + (p->p_pptr == td->td_proc && + ((p->p_flag & P_TRACED) != 0 || + (p->p_flag2 & P2_EXIT_TRACED) != 0))) { + break; } - break; + PROC_UNLOCK(p); + return (0); case P_PID: if (p->p_pid != (pid_t)id) { PROC_UNLOCK(p); Index: sys/kern/sys_procdesc.c =================================================================== --- sys/kern/sys_procdesc.c +++ sys/kern/sys_procdesc.c @@ -60,7 +60,6 @@ * * Open questions: * - * - How to handle ptrace(2)? * - Will we want to add a pidtoprocdesc(2) system call to allow process * descriptors to be created for processes without pdfork(2)? */ Index: sys/sys/proc.h =================================================================== --- sys/sys/proc.h +++ sys/sys/proc.h @@ -761,6 +761,7 @@ #define P2_ASLR_ENABLE 0x00000040 /* Force enable ASLR. */ #define P2_ASLR_DISABLE 0x00000080 /* Force disable ASLR. */ #define P2_ASLR_IGNSTART 0x00000100 /* Enable ASLR to consume sbrk area. */ +#define P2_EXIT_TRACED 0x00000200 /* The process exited while it was traced. */ /* Flags protected by proctree_lock, kept in p_treeflags. */ #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ Index: tests/sys/kern/ptrace_test.c =================================================================== --- tests/sys/kern/ptrace_test.c +++ tests/sys/kern/ptrace_test.c @@ -3959,6 +3959,47 @@ ATF_REQUIRE(errno == ECHILD); } +/* + * Ensure that traced processes created with pdfork(2) are visible to + * waitid(P_ALL). + */ +ATF_TC_WITHOUT_HEAD(ptrace__procdesc_wait_child); +ATF_TC_BODY(ptrace__procdesc_wait_child, tc) +{ + pid_t child, wpid; + int pd, status; + + child = pdfork(&pd, 0); + ATF_REQUIRE(child >= 0); + + if (child == 0) { + trace_me(); + (void)raise(SIGSTOP); + exit(0); + } + + wpid = waitpid(child, &status, 0); + ATF_REQUIRE(wpid == child); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == child); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == child); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 0); + + ATF_REQUIRE(close(pd) != -1); +} + ATF_TP_ADD_TCS(tp) { @@ -4021,6 +4062,7 @@ #endif ATF_TP_ADD_TC(tp, ptrace__PT_LWPINFO_stale_siginfo); ATF_TP_ADD_TC(tp, ptrace__proc_reparent); + ATF_TP_ADD_TC(tp, ptrace__procdesc_wait_child); return (atf_no_error()); }