Index: sys/kern/kern_exit.c =================================================================== --- sys/kern/kern_exit.c +++ sys/kern/kern_exit.c @@ -108,8 +108,7 @@ sx_assert(&proctree_lock, SX_LOCKED); if ((child->p_treeflag & P_TREE_ORPHANED) == 0) { - if (child->p_oppid == 0 || - child->p_pptr->p_pid == child->p_oppid) + if (child->p_pptr->p_pid == child->p_oppid) parent = child->p_pptr; else parent = initproc; @@ -854,7 +853,7 @@ * If we got the child via a ptrace 'attach', we need to give it back * to the old parent. */ - if (p->p_oppid != 0 && p->p_oppid != p->p_pptr->p_pid) { + if (p->p_oppid != p->p_pptr->p_pid) { PROC_UNLOCK(p); t = proc_realparent(p); PROC_LOCK(t); @@ -862,8 +861,7 @@ CTR2(KTR_PTRACE, "wait: traced child %d moved back to parent %d", p->p_pid, t->p_pid); - proc_reparent(p, t); - p->p_oppid = 0; + proc_reparent_ptrace(p, t); PROC_UNLOCK(p); pksignal(t, SIGCHLD, p->p_ksi); wakeup(t); @@ -872,7 +870,6 @@ sx_xunlock(&proctree_lock); return; } - p->p_oppid = 0; PROC_UNLOCK(p); /* @@ -1334,8 +1331,8 @@ * Make process 'parent' the new parent of process 'child'. * Must be called with an exclusive hold of proctree lock. */ -void -proc_reparent(struct proc *child, struct proc *parent) +static void +proc_reparent_(struct proc *child, struct proc *parent, bool set_oppid) { sx_assert(&proctree_lock, SX_XLOCKED); @@ -1363,4 +1360,20 @@ } child->p_pptr = parent; + if (set_oppid) + child->p_oppid = parent->p_pid; +} + +void +proc_reparent(struct proc *child, struct proc *parent) +{ + + proc_reparent_(child, parent, true); +} + +void +proc_reparent_ptrace(struct proc *child, struct proc *parent) +{ + + proc_reparent_(child, parent, false); } Index: sys/kern/kern_fork.c =================================================================== --- sys/kern/kern_fork.c +++ sys/kern/kern_fork.c @@ -645,6 +645,7 @@ pptr = p1; } p2->p_pptr = pptr; + p2->p_oppid = pptr->p_pid; LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling); LIST_INIT(&p2->p_reaplist); LIST_INSERT_HEAD(&p2->p_reaper->p_reaplist, p2, p_reapsibling); @@ -776,7 +777,7 @@ CTR2(KTR_PTRACE, "do_fork: attaching to new child pid %d: oppid %d", p2->p_pid, p2->p_oppid); - proc_reparent(p2, p1->p_pptr); + proc_reparent_ptrace(p2, p1->p_pptr); } PROC_UNLOCK(p2); sx_xunlock(&proctree_lock); Index: sys/kern/kern_proc.c =================================================================== --- sys/kern/kern_proc.c +++ sys/kern/kern_proc.c @@ -920,8 +920,6 @@ struct sigacts *ps; struct timeval boottime; - /* For proc_realparent. */ - sx_assert(&proctree_lock, SX_LOCKED); PROC_LOCK_ASSERT(p, MA_OWNED); bzero(kp, sizeof(*kp)); @@ -1055,7 +1053,7 @@ kp->ki_acflag = p->p_acflag; kp->ki_lock = p->p_lock; if (p->p_pptr) { - kp->ki_ppid = proc_realparent(p)->p_pid; + kp->ki_ppid = p->p_oppid; if (p->p_flag & P_TRACED) kp->ki_tracer = p->p_pptr->p_pid; } @@ -1640,20 +1638,12 @@ error = sysctl_wire_old_buffer(req, 0); if (error != 0) return (error); - /* - * This lock is only needed to safely grab the parent of a - * traced process. Only grab it if we are producing any - * data to begin with. - */ - sx_slock(&proctree_lock); } iterarg.flags = flags; iterarg.oid_number = oid_number; iterarg.req = req; iterarg.name = name; error = proc_iterate(sysctl_kern_proc_iterate, &iterarg); - if (req->oldptr != NULL) - sx_sunlock(&proctree_lock); return (error); } Index: sys/kern/kern_prot.c =================================================================== --- sys/kern/kern_prot.c +++ sys/kern/kern_prot.c @@ -124,20 +124,9 @@ kern_getppid(struct thread *td) { struct proc *p = td->td_proc; - struct proc *pp; int ppid; - PROC_LOCK(p); - if (!(p->p_flag & P_TRACED)) { - ppid = p->p_pptr->p_pid; - PROC_UNLOCK(p); - } else { - PROC_UNLOCK(p); - sx_slock(&proctree_lock); - pp = proc_realparent(p); - ppid = pp->p_pid; - sx_sunlock(&proctree_lock); - } + ppid = p->p_oppid; return (ppid); } Index: sys/kern/sys_process.c =================================================================== --- sys/kern/sys_process.c +++ sys/kern/sys_process.c @@ -695,7 +695,6 @@ if (stop) p->p_flag2 |= P2_PTRACE_FSTP; p->p_ptevents = PTRACE_DEFAULT; - p->p_oppid = p->p_pptr->p_pid; } int @@ -919,7 +918,7 @@ */ proc_set_traced(p, true); if (p->p_pptr != td->td_proc) { - proc_reparent(p, td->td_proc); + proc_reparent_ptrace(p, td->td_proc); } CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid, p->p_oppid); @@ -1113,7 +1112,7 @@ PROC_UNLOCK(p->p_pptr); pp = proc_realparent(p); - proc_reparent(p, pp); + proc_reparent_ptrace(p, pp); if (pp == initproc) p->p_sigparent = SIGCHLD; CTR3(KTR_PTRACE, @@ -1122,7 +1121,6 @@ } else CTR2(KTR_PTRACE, "PT_DETACH: pid %d, sig %d", p->p_pid, data); - p->p_oppid = 0; p->p_ptevents = 0; FOREACH_THREAD_IN_PROC(p, td3) { if ((td3->td_dbgflags & TDB_FSTP) != 0) { Index: sys/sys/proc.h =================================================================== --- sys/sys/proc.h +++ sys/sys/proc.h @@ -594,8 +594,8 @@ #define p_siglist p_sigqueue.sq_signals /* The following fields are all zeroed upon creation in fork. */ -#define p_startzero p_oppid pid_t p_oppid; /* (c + e) Save ppid in ptrace. XXX */ +#define p_startzero p_vmspace struct vmspace *p_vmspace; /* (b) Address space. */ u_int p_swtick; /* (c) Tick when swapped in or out. */ u_int p_cowgen; /* (c) Generation of COW pointers. */ @@ -1053,6 +1053,7 @@ struct proc *proc_realparent(struct proc *child); void proc_reap(struct thread *td, struct proc *p, int *status, int options); void proc_reparent(struct proc *child, struct proc *newparent); +void proc_reparent_ptrace(struct proc *child, struct proc *newparent); void proc_set_traced(struct proc *p, bool stop); void proc_wkilled(struct proc *p); struct pstats *pstats_alloc(void);