43#include "opt_ktrace.h"
47#include <sys/sysproto.h>
48#include <sys/capsicum.h>
49#include <sys/eventhandler.h>
50#include <sys/kernel.h>
52#include <sys/malloc.h>
56#include <sys/procdesc.h>
60#include <sys/vmmeter.h>
63#include <sys/resourcevar.h>
65#include <sys/signalvar.h>
68#include <sys/syscallsubr.h>
69#include <sys/sysctl.h>
70#include <sys/syslog.h>
71#include <sys/ptrace.h>
73#include <sys/filedesc.h>
77#include <sys/sysent.h>
78#include <sys/timers.h>
79#include <sys/umtxvar.h>
81#include <sys/ktrace.h>
84#include <security/audit/audit.h>
85#include <security/mac/mac_framework.h>
88#include <vm/vm_extern.h>
89#include <vm/vm_param.h>
92#include <vm/vm_page.h>
96#include <sys/dtrace_bsd.h>
97dtrace_execexit_func_t dtrace_fasttrap_exit;
104SYSCTL_INT(_kern, OID_AUTO, kill_on_debugger_exit, CTLFLAG_RWTUN,
106 "Kill ptraced processes when debugger exits");
111 "Dequeue SIGCHLD on wait(2) for live process");
119 if ((
child->p_treeflag & P_TREE_ORPHANED) == 0)
120 return (
child->p_pptr->p_pid ==
child->p_oppid ?
122 for (p =
child; (p->p_treeflag & P_TREE_FIRST_ORPHAN) == 0;) {
124 p = __containerof(p->p_orphan.le_prev,
struct proc,
126 KASSERT((p->p_treeflag & P_TREE_ORPHANED) != 0,
127 (
"missing P_ORPHAN %p", p));
129 parent = __containerof(p->p_orphan.le_prev,
struct proc,
137 struct proc *p1, *p2, *ptmp;
140 KASSERT(p !=
initproc, (
"reaper_abandon_children for initproc"));
141 if ((p->p_treeflag & P_TREE_REAPER) == 0)
144 LIST_FOREACH_SAFE(p2, &p->p_reaplist, p_reapsibling, ptmp) {
145 LIST_REMOVE(p2, p_reapsibling);
147 p2->p_reapsubtree = p->p_reapsubtree;
148 LIST_INSERT_HEAD(&p1->p_reaplist, p2, p_reapsibling);
149 if (exiting && p2->p_pptr == p) {
155 KASSERT(LIST_EMPTY(&p->p_reaplist), (
"p_reaplist not empty"));
156 p->p_treeflag &= ~P_TREE_REAPER;
166 LIST_REMOVE(p, p_reapsibling);
167 if (p->p_reapsubtree == 1)
170 LIST_FOREACH(p1, &p->p_reaper->p_reaplist, p_reapsibling) {
171 if (p1->p_reapsubtree == p->p_reapsubtree) {
186 if ((p->p_treeflag & P_TREE_ORPHANED) == 0)
188 if ((p->p_treeflag & P_TREE_FIRST_ORPHAN) != 0) {
189 p1 = LIST_NEXT(p, p_orphan);
191 p1->p_treeflag |= P_TREE_FIRST_ORPHAN;
192 p->p_treeflag &= ~P_TREE_FIRST_ORPHAN;
194 LIST_REMOVE(p, p_orphan);
195 p->p_treeflag &= ~P_TREE_ORPHANED;
201 MPASS(p->p_numthreads == 1);
212 exit1(td, uap->rval, 0);
222exit1(
struct thread *td,
int rval,
int signo)
224 struct proc *p, *nq, *q, *t;
226 ksiginfo_t *ksi, *ksi1;
229 mtx_assert(&
Giant, MA_NOTOWNED);
230 KASSERT(rval == 0 || signo == 0, (
"exit1 rv %d sig %d", rval, signo));
231 TSPROCEXIT(td->td_proc->p_pid);
241 printf(
"init died (signal %d, exit %d)\n", signo, rval);
242 panic(
"Going nowhere without my init!");
248 td_softdep_cleanup(td);
261 while (p->p_flag & P_HADTHREADS) {
293 KASSERT(p->p_numthreads == 1,
294 (
"exit1: proc %p exiting with %d threads", p, p->p_numthreads));
295 racct_sub(p, RACCT_NTHR, 1);
306 p->p_flag &= ~P_STOPPED_SIG;
307 KASSERT(!P_SHOULDSTOP(p), (
"exiting process is stopped"));
310 p->p_flag |= P_WEXIT;
316 while (p->p_lock > 0)
317 msleep(&p->p_lock, &p->p_mtx, PWAIT,
"exithold", 0);
321 callout_drain(&p->p_limco);
330 AUDIT_ARG_EXIT(rval, 0);
331 AUDIT_SYSCALL_EXIT(0, td);
335 if (p->p_peers != NULL && p == p->p_leader) {
344 while (p->p_peers != NULL)
357 EVENTHANDLER_DIRECT_INVOKE(process_exit, p);
371 if (timevalisset(&p->p_realtimer.it_value) &&
373 timevalclear(&p->p_realtimer.it_interval);
374 msleep(&p->p_itcallout, &p->p_mtx, PWAIT,
"ritwait", 0);
375 KASSERT(!timevalisset(&p->p_realtimer.it_value),
376 (
"realtime timer is still armed"));
381 if (p->p_sysent->sv_onexit != NULL)
382 p->p_sysent->sv_onexit(p);
402 if (td->td_pflags & TDP_GEOM)
408 if (p->p_leader->p_peers != NULL) {
410 if (p->p_leader->p_peers != NULL) {
412 while (q->p_peers != p)
414 q->p_peers = p->p_peers;
430 if (p->p_textvp != NULL) {
434 if (p->p_textdvp != NULL) {
438 if (p->p_binname != NULL) {
439 free(p->p_binname, M_PARGS);
459 WITNESS_WARN(WARN_PANIC, NULL,
"process (pid %d) exiting", p->p_pid);
465 LIST_REMOVE(p, p_list);
472 p->p_list.le_prev = NULL;
478 p->p_flag &= ~(P_TRACED | P_PPWAIT | P_PPTRACE);
492 q = LIST_FIRST(&p->p_children);
495 for (; q != NULL; q = nq) {
496 nq = LIST_NEXT(q, p_sibling);
499 q->p_sigparent = SIGCHLD;
501 if ((q->p_flag & P_TRACED) == 0) {
503 if (q->p_state == PRS_ZOMBIE) {
513 if (q->p_ksi == NULL) {
516 ksiginfo_copy(q->p_ksi, ksi);
517 ksi->ksi_flags |= KSI_INS;
521 PROC_LOCK(q->p_reaper);
522 pksignal(q->p_reaper, SIGCHLD, ksi1);
523 PROC_UNLOCK(q->p_reaper);
524 }
else if (q->p_pdeathsig > 0) {
552 q->p_flag &= ~P_TRACED;
553 q->p_flag2 &= ~P2_PTRACE_FSTP;
556 FOREACH_THREAD_IN_PROC(q, tdt) {
557 tdt->td_dbgflags &= ~(TDB_SUSPEND | TDB_XSIG |
562 q->p_flag &= ~P_STOPPED_TRACE;
564 }
else if ((q->p_flag & (P_STOPPED_TRACE |
565 P_STOPPED_SIG)) != 0) {
578 while ((q = LIST_FIRST(&p->p_orphans)) != NULL) {
580 KASSERT(q->p_oppid == p->p_pid,
581 (
"orphan %p of %p has unexpected oppid %d", q, p,
583 q->p_oppid = q->p_reaper->p_pid;
590 if (q->p_pdeathsig > 0)
592 CTR2(KTR_PTRACE,
"exit: pid %d, clearing orphan %d", p->p_pid,
599 if (SDT_PROBES_ENABLED()) {
600 int reason = CLD_EXITED;
601 if (WCOREDUMP(signo))
603 else if (WIFSIGNALED(signo))
605 SDT_PROBE1(proc, , , exit, reason);
613 if (p->p_sysent->sv_ontdexit != NULL)
614 p->p_sysent->sv_ontdexit(td);
621 if (dtrace_fasttrap_exit)
622 dtrace_fasttrap_exit(p);
628 KNOTE_LOCKED(p->p_klist, NOTE_EXIT);
644 PROC_LOCK(p->p_pptr);
645 mtx_lock(&p->p_pptr->p_sigacts->ps_mtx);
646 if (p->p_pptr->p_sigacts->ps_flag &
647 (PS_NOCLDWAIT | PS_CLDSIGIGN)) {
650 mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx);
654 p->p_sigparent = SIGCHLD;
655 PROC_LOCK(p->p_pptr);
664 mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx);
666 if (p->p_pptr == p->p_reaper || p->p_pptr ==
initproc) {
668 }
else if (p->p_sigparent != 0) {
669 if (p->p_sigparent == SIGCHLD) {
676 PROC_LOCK(p->p_pptr);
679 if (signal_parent == 1) {
681 }
else if (signal_parent == 2) {
707 cv_broadcast(&p->p_pwait);
710 p->p_state = PRS_ZOMBIE;
711 PROC_UNLOCK(p->p_pptr);
717 ruadd(&p->p_ru, &p->p_rux, &p->p_stats->p_cru, &p->p_crux);
728#ifndef _SYS_SYSPROTO_H_
744 if (nargs < 0 || nargs > nitems(uargs))
748 if (uap->
args != NULL) {
749 error = copyin(uap->
args, uargs,
750 nargs *
sizeof(
void *));
769kern_abort2(
struct thread *td,
const char *why,
int nargs,
void **uargs)
771 struct proc *p = td->td_proc;
780 sb =
sbuf_new(NULL, NULL, 512, SBUF_FIXEDLEN);
783 p->p_comm, p->p_pid, td->td_ucred->cr_uid);
792 KASSERT(nargs >= 0 && nargs <= 16, (
"called with too many args (%d)",
807 for (i = 0;i < nargs; i++)
808 sbuf_printf(sb,
"%s%p", i == 0 ?
"" :
", ", uargs[i]);
818 if (sig == SIGKILL) {
835owait(
struct thread *td,
struct owait_args *uap __unused)
839 error =
kern_wait(td, WAIT_ANY, &status, 0, NULL);
841 td->td_retval[1] = status;
852 struct rusage ru, *rup;
855 if (uap->rusage != NULL)
859 error =
kern_wait(td, uap->pid, &status, uap->options, rup);
860 if (uap->status != NULL && error == 0 && td->td_retval[0] != 0)
861 error = copyout(&status, uap->status,
sizeof(status));
862 if (uap->rusage != NULL && error == 0 && td->td_retval[0] != 0)
863 error = copyout(&ru, uap->rusage,
sizeof(
struct rusage));
870 struct __wrusage wru, *wrup;
876 idtype = uap->idtype;
879 if (uap->wrusage != NULL)
884 if (uap->info != NULL) {
886 bzero(sip,
sizeof(*sip));
894 error =
kern_wait6(td, idtype,
id, &status, uap->options, wrup, sip);
896 if (uap->status != NULL && error == 0 && td->td_retval[0] != 0)
897 error = copyout(&status, uap->status,
sizeof(status));
898 if (uap->wrusage != NULL && error == 0 && td->td_retval[0] != 0)
899 error = copyout(&wru, uap->wrusage,
sizeof(wru));
900 if (uap->info != NULL && error == 0)
901 error = copyout(&si, uap->info,
sizeof(si));
911proc_reap(
struct thread *td,
struct proc *p,
int *status,
int options)
916 PROC_LOCK_ASSERT(p, MA_OWNED);
917 KASSERT(p->p_state == PRS_ZOMBIE, (
"proc_reap: !PRS_ZOMBIE"));
924 *status = KW_EXITCODE(p->p_xexit, p->p_xsig);
925 if (options & WNOWAIT) {
943 if (p->p_oppid != p->p_pptr->p_pid) {
949 "wait: traced child %d moved back to parent %d", p->p_pid,
955 cv_broadcast(&p->p_pwait);
966 sx_xlock(PIDHASHLOCK(p->p_pid));
967 LIST_REMOVE(p, p_hash);
968 sx_xunlock(PIDHASHLOCK(p->p_pid));
969 LIST_REMOVE(p, p_sibling);
976 if (p->p_procdesc != NULL)
993 p->p_xexit = p->p_xsig = 0;
996 ruadd(&q->p_stats->p_cru, &q->p_crux, &p->p_ru, &p->p_rux);
1002 (void)
chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0);
1010 racct_sub(p, RACCT_NPROC, 1);
1023 p->p_sigacts = NULL;
1036 mac_proc_destroy(p);
1039 KASSERT(FIRST_THREAD_IN_PROC(p),
1040 (
"proc_reap: no residual thread!"));
1042 atomic_add_int(&
nprocs, -1);
1047 int *status,
int options,
struct __wrusage *wrusage, siginfo_t *siginfo,
1058 if (p->p_procdesc == NULL ||
1059 (p->p_pptr == td->td_proc &&
1060 (p->p_flag & P_TRACED) != 0)) {
1067 if (p->p_pid != (pid_t)
id) {
1073 if (p->p_pgid != (pid_t)
id) {
1079 if (p->p_session->s_sid != (pid_t)
id) {
1085 if (p->p_ucred->cr_uid != (uid_t)
id) {
1091 if (p->p_ucred->cr_gid != (gid_t)
id) {
1097 if (p->p_ucred->cr_prison->pr_id != (
int)
id) {
1117 if (((options & WEXITED) == 0) && (p->p_state == PRS_ZOMBIE)) {
1130 if ((p->p_sigparent != SIGCHLD) ^
1131 ((options & WLINUXCLONE) != 0)) {
1136 if (siginfo != NULL) {
1137 bzero(siginfo,
sizeof(*siginfo));
1138 siginfo->si_errno = 0;
1146 siginfo->si_signo = SIGCHLD;
1152 if (WCOREDUMP(p->p_xsig)) {
1153 siginfo->si_code = CLD_DUMPED;
1154 siginfo->si_status = WTERMSIG(p->p_xsig);
1155 }
else if (WIFSIGNALED(p->p_xsig)) {
1156 siginfo->si_code = CLD_KILLED;
1157 siginfo->si_status = WTERMSIG(p->p_xsig);
1159 siginfo->si_code = CLD_EXITED;
1160 siginfo->si_status = p->p_xexit;
1163 siginfo->si_pid = p->p_pid;
1164 siginfo->si_uid = p->p_ucred->cr_uid;
1179 if (wrusage != NULL) {
1180 rup = &wrusage->wru_self;
1183 calcru(p, &rup->ru_utime, &rup->ru_stime);
1186 rup = &wrusage->wru_children;
1187 *rup = p->p_stats->p_cru;
1188 calccru(p, &rup->ru_utime, &rup->ru_stime);
1191 if (p->p_state == PRS_ZOMBIE && !check_only) {
1199kern_wait(
struct thread *td, pid_t pid,
int *status,
int options,
1200 struct rusage *rusage)
1202 struct __wrusage wru, *wrup;
1212 if (pid == WAIT_ANY) {
1215 }
else if (pid < 0) {
1232 options |= WEXITED | WTRAPPED;
1233 ret =
kern_wait6(td, idtype,
id, status, options, wrup, NULL);
1235 *rusage = wru.wru_self;
1241 int *status,
int options,
int si_code)
1245 PROC_LOCK_ASSERT(p, MA_OWNED);
1247 MPASS(si_code == CLD_TRAPPED || si_code == CLD_STOPPED ||
1248 si_code == CLD_CONTINUED);
1250 cont = si_code == CLD_CONTINUED;
1251 if ((options & WNOWAIT) == 0) {
1253 p->p_flag &= ~P_CONTINUED;
1255 p->p_flag |= P_WAITED;
1257 (td->td_proc->p_sysent->sv_flags & SV_SIG_WAITNDQ) == 0) {
1258 PROC_LOCK(td->td_proc);
1260 PROC_UNLOCK(td->td_proc);
1264 if (siginfo != NULL) {
1265 siginfo->si_code = si_code;
1266 siginfo->si_status = cont ? SIGCONT : p->p_xsig;
1269 *status = cont ? SIGCONT : W_STOPCODE(p->p_xsig);
1271 td->td_retval[0] = p->p_pid;
1275kern_wait6(
struct thread *td, idtype_t idtype, id_t
id,
int *status,
1276 int options,
struct __wrusage *wrusage, siginfo_t *siginfo)
1280 int error, nfound, ret;
1283 AUDIT_ARG_VALUE((
int)idtype);
1284 AUDIT_ARG_PID((pid_t)
id);
1285 AUDIT_ARG_VALUE(options);
1289 if ((pid_t)
id == WAIT_MYPGRP && (idtype == P_PID || idtype == P_PGID)) {
1291 id = (id_t)q->p_pgid;
1297 if ((options & ~(WUNTRACED | WNOHANG | WCONTINUED | WNOWAIT |
1298 WEXITED | WTRAPPED | WLINUXCLONE)) != 0)
1300 if ((options & (WEXITED | WUNTRACED | WCONTINUED | WTRAPPED)) == 0) {
1311 if (q->p_flag & P_STATCHILD) {
1313 q->p_flag &= ~P_STATCHILD;
1319 LIST_FOREACH(p, &q->p_children, p_sibling) {
1322 wrusage, siginfo, 0);
1325 else if (ret != 1) {
1326 td->td_retval[0] = pid;
1331 PROC_LOCK_ASSERT(p, MA_OWNED);
1333 if ((options & WTRAPPED) != 0 &&
1334 (p->p_flag & P_TRACED) != 0) {
1337 ((p->p_flag & (P_STOPPED_TRACE | P_STOPPED_SIG)) &&
1338 p->p_suspcount == p->p_numthreads &&
1339 (p->p_flag & P_WAITED) == 0);
1343 "wait: returning trapped pid %d status %#x "
1344 "(xstat %d) xthread %d",
1345 p->p_pid, W_STOPCODE(p->p_xsig), p->p_xsig,
1346 p->p_xthread != NULL ?
1347 p->p_xthread->td_tid : -1);
1349 options, CLD_TRAPPED);
1353 if ((options & WUNTRACED) != 0 &&
1354 (p->p_flag & P_STOPPED_SIG) != 0) {
1356 report = (p->p_suspcount == p->p_numthreads &&
1357 ((p->p_flag & P_WAITED) == 0));
1361 options, CLD_STOPPED);
1365 if ((options & WCONTINUED) != 0 &&
1366 (p->p_flag & P_CONTINUED) != 0) {
1387 LIST_FOREACH(p, &q->p_orphans, p_orphan) {
1391 KASSERT(ret != -1, (
"reaped an orphan (pid %d)",
1392 (
int)td->td_retval[0]));
1403 if (options & WNOHANG) {
1405 td->td_retval[0] = 0;
1409 if (q->p_flag & P_STATCHILD) {
1410 q->p_flag &= ~P_STATCHILD;
1415 error = msleep(q, &q->p_mtx, PWAIT | PCATCH | PDROP,
"wait", 0);
1426 KASSERT((
child->p_flag & P_TRACED) != 0,
1427 (
"proc_add_orphan: not traced"));
1429 if (LIST_EMPTY(&
parent->p_orphans)) {
1430 child->p_treeflag |= P_TREE_FIRST_ORPHAN;
1431 LIST_INSERT_HEAD(&
parent->p_orphans,
child, p_orphan);
1433 LIST_INSERT_AFTER(LIST_FIRST(&
parent->p_orphans),
1436 child->p_treeflag |= P_TREE_ORPHANED;
1448 PROC_LOCK_ASSERT(
child, MA_OWNED);
1452 PROC_LOCK(
child->p_pptr);
1454 PROC_UNLOCK(
child->p_pptr);
1455 LIST_REMOVE(
child, p_sibling);
1456 LIST_INSERT_HEAD(&
parent->p_children,
child, p_sibling);
1459 if ((
child->p_flag & P_TRACED) != 0) {
int acct_process(struct thread *td)
void stopprofclock(struct proc *p)
void pdescfree(struct thread *td)
void funsetownlst(struct sigiolst *sigiolst)
void fdescfree(struct thread *td)
void knlist_detach(struct knlist *knl)
void exec_free_abi_mappings(struct proc *p)
int sys_wait4(struct thread *td, struct wait4_args *uap)
void proc_clear_orphan(struct proc *p)
SYSCTL_INT(_kern, OID_AUTO, kill_on_debugger_exit, CTLFLAG_RWTUN, &kern_kill_on_dbg_exit, 0, "Kill ptraced processes when debugger exits")
void reaper_abandon_children(struct proc *p, bool exiting)
int sys_exit(struct thread *td, struct exit_args *uap)
SDT_PROBE_DEFINE1(proc,,, exit, "int")
int sys_abort2(struct thread *td, struct abort2_args *uap)
int kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rusage)
void proc_add_orphan(struct proc *child, struct proc *parent)
void proc_reap(struct thread *td, struct proc *p, int *status, int options)
SYSCTL_BOOL(_kern, OID_AUTO, wait_dequeue_sigchld, CTLFLAG_RWTUN, &kern_wait_dequeue_sigchld, 0, "Dequeue SIGCHLD on wait(2) for live process")
static bool kern_wait_dequeue_sigchld
void exit1(struct thread *td, int rval, int signo)
void exit_onexit(struct proc *p)
int sys_wait6(struct thread *td, struct wait6_args *uap)
struct proc * proc_realparent(struct proc *child)
int kern_abort2(struct thread *td, const char *why, int nargs, void **uargs)
static void report_alive_proc(struct thread *td, struct proc *p, siginfo_t *siginfo, int *status, int options, int si_code)
static int kern_kill_on_dbg_exit
int kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo)
static void reaper_clear(struct proc *p)
SDT_PROVIDER_DECLARE(proc)
void proc_reparent(struct proc *child, struct proc *parent, bool set_oppid)
static int proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo, int check_only)
int __exclusive_cache_line nprocs
void prison_proc_free(struct prison *pr)
void free(void *addr, struct malloc_type *mtp)
void mtx_spin_wait_unlocked(struct mtx *m)
struct mtx __exclusive_cache_line Giant
struct sx __exclusive_cache_line proctree_lock
void pargs_drop(struct pargs *pa)
struct mtx __exclusive_cache_line ppeers_lock
void proc_id_clear(int type, pid_t id)
int leavepgrp(struct proc *p)
struct sx __exclusive_cache_line allproc_lock
int p_canwait(struct thread *td, struct proc *p)
void proc_unset_cred(struct proc *p)
void ruadd(struct rusage *ru, struct rusage_ext *rux, struct rusage *ru2, struct rusage_ext *rux2)
void lim_free(struct plimit *limp)
void calccru(struct proc *p, struct timeval *up, struct timeval *sp)
void calcru(struct proc *p, struct timeval *up, struct timeval *sp)
int chgproccnt(struct uidinfo *uip, int diff, rlim_t max)
void panic(const char *fmt,...)
int pksignal(struct proc *p, int sig, ksiginfo_t *ksi)
void sigqueue_flush(sigqueue_t *sq)
void sigacts_free(struct sigacts *ps)
void sigqueue_delete_proc(struct proc *p, int signo)
void sigqueue_take(ksiginfo_t *ksi)
void childproc_exited(struct proc *p)
void kern_psignal(struct proc *p, int sig)
ksiginfo_t * ksiginfo_alloc(int wait)
void ksiginfo_free(ksiginfo_t *ksi)
void wakeup(const void *ident)
void tidhash_remove(struct thread *td)
int thread_suspend_check(int return_instead)
int thread_single(struct proc *p, int mode)
void thread_wait(struct proc *p)
void itimers_exit(struct proc *p)
int _callout_stop_safe(struct callout *c, int flags, callout_func_t *drain)
void umtx_thread_exit(struct thread *td)
void sched_exit(struct proc *p, struct thread *td)
int printf(const char *fmt,...)
void log(int level, const char *fmt,...)
int sbuf_finish(struct sbuf *s)
void sbuf_delete(struct sbuf *s)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
char * sbuf_data(struct sbuf *s)
void sbuf_clear(struct sbuf *s)
int sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
int sbuf_cat(struct sbuf *s, const char *str)
int sbuf_trim(struct sbuf *s)
void seltdfini(struct thread *td)
void procdesc_reap(struct proc *p)
int procdesc_exit(struct proc *p)
void ptrace_unsuspend(struct proc *p)
void vrele(struct vnode *vp)