deduplicate the complex lock reparent dance.
This commit is contained in:
parent
e8fde31e58
commit
9b5ab01589
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_exit.c,v 1.262 2016/11/04 18:12:06 christos Exp $ */
|
||||
/* $NetBSD: kern_exit.c,v 1.263 2016/11/04 18:14:04 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -67,7 +67,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.262 2016/11/04 18:12:06 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.263 2016/11/04 18:14:04 christos Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_dtrace.h"
|
||||
|
@ -1204,6 +1204,33 @@ proc_free(struct proc *p, struct wrusage *wru)
|
|||
proc_free_mem(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the parent of a process for tracing purposes.
|
||||
*/
|
||||
void
|
||||
proc_changeparent(struct proc *t, struct proc *p)
|
||||
{
|
||||
SET(t->p_slflag, PSL_TRACED);
|
||||
t->p_opptr = t->p_pptr;
|
||||
if (t->p_pptr == p)
|
||||
return;
|
||||
struct proc *parent = t->p_pptr;
|
||||
|
||||
if (parent->p_lock < t->p_lock) {
|
||||
if (!mutex_tryenter(parent->p_lock)) {
|
||||
mutex_exit(t->p_lock);
|
||||
mutex_enter(parent->p_lock);
|
||||
mutex_enter(t->p_lock);
|
||||
}
|
||||
} else if (parent->p_lock > t->p_lock) {
|
||||
mutex_enter(parent->p_lock);
|
||||
}
|
||||
parent->p_slflag |= PSL_CHTRACED;
|
||||
proc_reparent(t, p);
|
||||
if (parent->p_lock != t->p_lock)
|
||||
mutex_exit(parent->p_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* make process 'parent' the new parent of process 'child'.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_fork.c,v 1.195 2016/01/09 07:52:38 dholland Exp $ */
|
||||
/* $NetBSD: kern_fork.c,v 1.196 2016/11/04 18:14:04 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -67,7 +67,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.195 2016/01/09 07:52:38 dholland Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.196 2016/11/04 18:14:04 christos Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_dtrace.h"
|
||||
|
@ -477,26 +477,7 @@ fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize,
|
|||
tracefork = (p1->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) ==
|
||||
(PSL_TRACEFORK|PSL_TRACED) && (flags && FORK_PPWAIT) == 0;
|
||||
if (tracefork) {
|
||||
p2->p_slflag |= PSL_TRACED;
|
||||
p2->p_opptr = p2->p_pptr;
|
||||
if (p2->p_pptr != p1->p_pptr) {
|
||||
struct proc *parent1 = p2->p_pptr;
|
||||
|
||||
if (parent1->p_lock < p2->p_lock) {
|
||||
if (!mutex_tryenter(parent1->p_lock)) {
|
||||
mutex_exit(p2->p_lock);
|
||||
mutex_enter(parent1->p_lock);
|
||||
mutex_enter(p2->p_lock);
|
||||
}
|
||||
} else if (parent1->p_lock > p2->p_lock) {
|
||||
mutex_enter(parent1->p_lock);
|
||||
}
|
||||
parent1->p_slflag |= PSL_CHTRACED;
|
||||
proc_reparent(p2, p1->p_pptr);
|
||||
if (parent1->p_lock != p2->p_lock)
|
||||
mutex_exit(parent1->p_lock);
|
||||
}
|
||||
|
||||
proc_changeparent(p2, p1->p_pptr);
|
||||
/*
|
||||
* Set ptrace status.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_ptrace_common.c,v 1.1 2016/11/02 00:11:59 pgoyette Exp $ */
|
||||
/* $NetBSD: sys_ptrace_common.c,v 1.2 2016/11/04 18:14:04 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
||||
|
@ -118,7 +118,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.1 2016/11/02 00:11:59 pgoyette Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.2 2016/11/04 18:14:04 christos Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_ptrace.h"
|
||||
|
@ -813,25 +813,7 @@ do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid,
|
|||
* proc gets to see all the action.
|
||||
* Stop the target.
|
||||
*/
|
||||
t->p_opptr = t->p_pptr;
|
||||
if (t->p_pptr != p) {
|
||||
struct proc *parent = t->p_pptr;
|
||||
|
||||
if (parent->p_lock < t->p_lock) {
|
||||
if (!mutex_tryenter(parent->p_lock)) {
|
||||
mutex_exit(t->p_lock);
|
||||
mutex_enter(parent->p_lock);
|
||||
mutex_enter(t->p_lock);
|
||||
}
|
||||
} else if (parent->p_lock > t->p_lock) {
|
||||
mutex_enter(parent->p_lock);
|
||||
}
|
||||
parent->p_slflag |= PSL_CHTRACED;
|
||||
proc_reparent(t, p);
|
||||
if (parent->p_lock != t->p_lock)
|
||||
mutex_exit(parent->p_lock);
|
||||
}
|
||||
SET(t->p_slflag, PSL_TRACED);
|
||||
proc_changeparent(t, p);
|
||||
signo = SIGSTOP;
|
||||
goto sendsig;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ptrace.h,v 1.48 2016/11/02 00:12:00 pgoyette Exp $ */
|
||||
/* $NetBSD: ptrace.h,v 1.49 2016/11/04 18:14:04 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1984, 1993
|
||||
|
@ -161,6 +161,7 @@ int process_domem(struct lwp *, struct lwp *, struct uio *);
|
|||
void process_stoptrace(void);
|
||||
|
||||
void proc_reparent(struct proc *, struct proc *);
|
||||
void proc_changeparent(struct proc *, struct proc *);
|
||||
|
||||
|
||||
int do_ptrace(struct ptrace_methods *, struct lwp *, int, pid_t, void *,
|
||||
|
|
Loading…
Reference in New Issue