diff --git a/sys/fs/procfs/procfs_ctl.c b/sys/fs/procfs/procfs_ctl.c index dc267f6..0c2f746 100644 --- a/sys/fs/procfs/procfs_ctl.c +++ b/sys/fs/procfs/procfs_ctl.c @@ -143,10 +143,8 @@ procfs_control(struct thread *td, struct proc *p, int op) p->p_flag |= P_TRACED; faultin(p); p->p_xstat = 0; /* XXX ? */ - if (p->p_pptr != td->td_proc) { - p->p_oppid = p->p_pptr->p_pid; + if (p->p_pptr != td->td_proc) proc_reparent(p, td->td_proc); - } kern_psignal(p, SIGSTOP); out: PROC_UNLOCK(p); @@ -223,18 +221,9 @@ out: /* give process back to original parent */ sx_xlock(&proctree_lock); - if (p->p_oppid != p->p_pptr->p_pid) { - struct proc *pp; - - pp = pfind(p->p_oppid); - PROC_LOCK(p); - if (pp) { - PROC_UNLOCK(pp); - proc_reparent(p, pp); - } - } else - PROC_LOCK(p); - p->p_oppid = 0; + PROC_LOCK(p); + if (p->p_pptr != p->p_rpptr) + proc_ptrace_restore(p); p->p_flag &= ~P_WAITED; /* XXX ? */ sx_xunlock(&proctree_lock); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 9efaac2..6027605 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -418,6 +418,7 @@ exit1(struct thread *td, int rv) for (; q != NULL; q = nq) { nq = LIST_NEXT(q, p_sibling); PROC_LOCK(q); + q->p_rpptr = initproc; proc_reparent(q, initproc); q->p_sigparent = SIGCHLD; /* @@ -732,6 +733,26 @@ sys_wait6(struct thread *td, struct wait6_args *uap) return (error); } +void +proc_ptrace_restore(struct proc *p) +{ + struct proc *t; + + t = p->p_rpptr; + PROC_LOCK(t); + if ((t->p_flag & P_WEXIT) != 0) { + PROC_UNLOCK(t); + t = initproc; + PROC_LOCK(t); + } + proc_reparent(p, t); + PROC_UNLOCK(p); + pksignal(t, SIGCHLD, p->p_ksi); + wakeup(t); + cv_broadcast(&p->p_pwait); + PROC_UNLOCK(t); +} + /* * Reap the remains of a zombie process and optionally return status and * rusage. Asserts and will release both the proctree_lock and the process @@ -740,7 +761,7 @@ sys_wait6(struct thread *td, struct wait6_args *uap) void proc_reap(struct thread *td, struct proc *p, int *status, int options) { - struct proc *q, *t; + struct proc *q; sx_assert(&proctree_lock, SA_XLOCKED); PROC_LOCK_ASSERT(p, MA_OWNED); @@ -766,25 +787,19 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options) PROC_LOCK(q); sigqueue_take(p->p_ksi); PROC_UNLOCK(q); - PROC_UNLOCK(p); /* * If we got the child via a ptrace 'attach', we need to give it back * to the old parent. */ - if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) { - PROC_LOCK(p); - proc_reparent(p, t); - p->p_oppid = 0; - PROC_UNLOCK(p); - pksignal(t, SIGCHLD, p->p_ksi); - wakeup(t); - cv_broadcast(&p->p_pwait); - PROC_UNLOCK(t); + if (p->p_rpptr != p->p_pptr) { + proc_ptrace_restore(p); sx_xunlock(&proctree_lock); return; } + PROC_UNLOCK(p); + /* * Remove other references to this process to ensure we have an * exclusive reference. diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 8135afb..46a9e92 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -614,7 +614,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, pptr = initproc; else pptr = p1; - p2->p_pptr = pptr; + p2->p_rpptr = p2->p_pptr = pptr; LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling); sx_xunlock(&proctree_lock); @@ -1014,7 +1014,6 @@ fork_return(struct thread *td, struct trapframe *frame) */ dbg = p->p_pptr->p_pptr; p->p_flag |= P_TRACED; - p->p_oppid = p->p_pptr->p_pid; proc_reparent(p, dbg); sx_xunlock(&proctree_lock); td->td_dbgflags |= TDB_CHILD; diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 821c779..4c2a47e 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -826,7 +826,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) p->p_flag |= P_TRACED; if (p->p_flag & P_PPWAIT) p->p_flag |= P_PPTRACE; - p->p_oppid = p->p_pptr->p_pid; break; case PT_ATTACH: @@ -841,7 +840,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) * on a "detach". */ p->p_flag |= P_TRACED; - p->p_oppid = p->p_pptr->p_pid; if (p->p_pptr != td->td_proc) { proc_reparent(p, td->td_proc); } @@ -916,25 +914,16 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) break; case PT_DETACH: /* reset process parent */ - if (p->p_oppid != p->p_pptr->p_pid) { - struct proc *pp; - + if (p->p_pptr != p->p_rpptr) { PROC_LOCK(p->p_pptr); sigqueue_take(p->p_ksi); PROC_UNLOCK(p->p_pptr); - PROC_UNLOCK(p); - pp = pfind(p->p_oppid); - if (pp == NULL) - pp = initproc; - else - PROC_UNLOCK(pp); + proc_ptrace_restore(p); PROC_LOCK(p); - proc_reparent(p, pp); - if (pp == initproc) + if (p->p_pptr == initproc) p->p_sigparent = SIGCHLD; } - p->p_oppid = 0; p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK); /* should we send SIGCHLD? */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index fbd064c..761f704 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -509,6 +509,7 @@ struct proc { LIST_ENTRY(proc) p_hash; /* (d) Hash chain. */ LIST_ENTRY(proc) p_pglist; /* (g + e) List of processes in pgrp. */ struct proc *p_pptr; /* (c + e) Pointer to parent process. */ + struct proc *p_rpptr; /* (c + e) Pointer to real parent process. */ LIST_ENTRY(proc) p_sibling; /* (e) List of sibling processes. */ LIST_HEAD(, proc) p_children; /* (e) Pointer to list of children. */ struct mtx p_mtx; /* (n) Lock for this struct. */ @@ -517,8 +518,7 @@ struct proc { #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. */ struct itimerval p_realtimer; /* (c) Alarm timer. */ @@ -889,6 +889,7 @@ void proc_linkup0(struct proc *p, struct thread *td); void proc_linkup(struct proc *p, struct thread *td); void proc_reap(struct thread *td, struct proc *p, int *status, int options); void proc_reparent(struct proc *child, struct proc *newparent); +void proc_ptrace_restore(struct proc *p); struct pstats *pstats_alloc(void); void pstats_fork(struct pstats *src, struct pstats *dst); void pstats_free(struct pstats *ps);