summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_procdesc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/sys_procdesc.c')
-rw-r--r--sys/kern/sys_procdesc.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c
index 0bf79b8..ac625f7 100644
--- a/sys/kern/sys_procdesc.c
+++ b/sys/kern/sys_procdesc.c
@@ -333,6 +333,7 @@ procdesc_reap(struct proc *p)
pd = p->p_procdesc;
pd->pd_proc = NULL;
+ p->p_procdesc = NULL;
procdesc_free(pd);
}
@@ -358,14 +359,20 @@ procdesc_close(struct file *fp, struct thread *td)
pd->pd_flags |= PDF_CLOSED;
PROCDESC_UNLOCK(pd);
p = pd->pd_proc;
- PROC_LOCK(p);
- if (p->p_state == PRS_ZOMBIE) {
+ if (p == NULL) {
+ /*
+ * This is the case where process' exit status was already
+ * collected and procdesc_reap() was already called.
+ */
+ sx_xunlock(&proctree_lock);
+ } else if (p->p_state == PRS_ZOMBIE) {
/*
* If the process is already dead and just awaiting reaping,
* do that now. This will release the process's reference to
* the process descriptor when it calls back into
* procdesc_reap().
*/
+ PROC_LOCK(p);
PROC_SLOCK(p);
proc_reap(curthread, p, NULL, 0, NULL);
} else {
@@ -376,6 +383,7 @@ procdesc_close(struct file *fp, struct thread *td)
* process from its descriptor so that its exit status will
* be reported normally.
*/
+ PROC_LOCK(p);
pd->pd_proc = NULL;
p->p_procdesc = NULL;
procdesc_free(pd);
OpenPOWER on IntegriCloud