Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_fork.c
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/procdesc.h> | #include <sys/procdesc.h> | ||||
#include <sys/pioctl.h> | #include <sys/pioctl.h> | ||||
#include <sys/ptrace.h> | |||||
#include <sys/racct.h> | #include <sys/racct.h> | ||||
#include <sys/resourcevar.h> | #include <sys/resourcevar.h> | ||||
#include <sys/sched.h> | #include <sys/sched.h> | ||||
#include <sys/syscall.h> | #include <sys/syscall.h> | ||||
#include <sys/vmmeter.h> | #include <sys/vmmeter.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/acct.h> | #include <sys/acct.h> | ||||
#include <sys/ktr.h> | #include <sys/ktr.h> | ||||
▲ Show 20 Lines • Show All 958 Lines • ▼ Show 20 Lines | |||||
* be held on return. This function is passed in to fork_exit() as the | * be held on return. This function is passed in to fork_exit() as the | ||||
* first parameter and is called when returning to a new userland process. | * first parameter and is called when returning to a new userland process. | ||||
*/ | */ | ||||
void | void | ||||
fork_return(struct thread *td, struct trapframe *frame) | fork_return(struct thread *td, struct trapframe *frame) | ||||
{ | { | ||||
struct proc *p, *dbg; | struct proc *p, *dbg; | ||||
if (td->td_dbgflags & TDB_STOPATFORK) { | |||||
p = td->td_proc; | p = td->td_proc; | ||||
if (td->td_dbgflags & TDB_STOPATFORK) { | |||||
sx_xlock(&proctree_lock); | sx_xlock(&proctree_lock); | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
if ((p->p_pptr->p_flag & (P_TRACED | P_FOLLOWFORK)) == | if ((p->p_pptr->p_flag & (P_TRACED | P_FOLLOWFORK)) == | ||||
(P_TRACED | P_FOLLOWFORK)) { | (P_TRACED | P_FOLLOWFORK)) { | ||||
/* | /* | ||||
* If debugger still wants auto-attach for the | * If debugger still wants auto-attach for the | ||||
* parent's children, do it now. | * parent's children, do it now. | ||||
*/ | */ | ||||
dbg = p->p_pptr->p_pptr; | dbg = p->p_pptr->p_pptr; | ||||
p->p_flag |= P_TRACED; | p->p_flag |= P_TRACED; | ||||
p->p_oppid = p->p_pptr->p_pid; | p->p_oppid = p->p_pptr->p_pid; | ||||
CTR2(KTR_PTRACE, | CTR2(KTR_PTRACE, | ||||
"fork_return: attaching to new child pid %d: oppid %d", | "fork_return: attaching to new child pid %d: oppid %d", | ||||
p->p_pid, p->p_oppid); | p->p_pid, p->p_oppid); | ||||
proc_reparent(p, dbg); | proc_reparent(p, dbg); | ||||
sx_xunlock(&proctree_lock); | sx_xunlock(&proctree_lock); | ||||
td->td_dbgflags |= TDB_CHILD; | td->td_dbgflags |= TDB_CHILD | TDB_SCX; | ||||
ptracestop(td, SIGSTOP); | ptracestop(td, SIGSTOP); | ||||
td->td_dbgflags &= ~TDB_CHILD; | td->td_dbgflags &= ~(TDB_CHILD | TDB_SCX); | ||||
} else { | } else { | ||||
/* | /* | ||||
* ... otherwise clear the request. | * ... otherwise clear the request. | ||||
*/ | */ | ||||
sx_xunlock(&proctree_lock); | sx_xunlock(&proctree_lock); | ||||
td->td_dbgflags &= ~TDB_STOPATFORK; | td->td_dbgflags &= ~TDB_STOPATFORK; | ||||
cv_broadcast(&p->p_dbgwait); | cv_broadcast(&p->p_dbgwait); | ||||
} | } | ||||
PROC_UNLOCK(p); | |||||
} else if (p->p_flag & P_TRACED) { | |||||
/* | |||||
* This is the start of a new thread in a traced | |||||
* process. Report a system call exit event. | |||||
*/ | |||||
PROC_LOCK(p); | |||||
td->td_dbgflags |= TDB_SCX; | |||||
_STOPEVENT(p, S_SCX, td->td_dbg_sc_code); | |||||
if ((p->p_stops & S_PT_SCX) != 0) | |||||
ptracestop(td, SIGTRAP); | |||||
td->td_dbgflags &= ~TDB_SCX; | |||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
userret(td, frame); | userret(td, frame); | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
if (KTRPOINT(td, KTR_SYSRET)) | if (KTRPOINT(td, KTR_SYSRET)) | ||||
ktrsysret(SYS_fork, 0, 0); | ktrsysret(SYS_fork, 0, 0); | ||||
#endif | #endif | ||||
} | } |