Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_fork.c
Show First 20 Lines • Show All 1,075 Lines • ▼ Show 20 Lines | if (p->p_pptr->p_ptevents & PTRACE_FORK) { | ||||
dbg = p->p_pptr->p_pptr; | dbg = p->p_pptr->p_pptr; | ||||
proc_set_traced(p, true); | proc_set_traced(p, true); | ||||
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 | TDB_SCX | TDB_FSTP; | td->td_dbgflags |= TDB_CHILD | TDB_SCX | TDB_FSTP; | ||||
ptracestop(td, SIGSTOP); | ptracestop(td, SIGSTOP, NULL); | ||||
td->td_dbgflags &= ~(TDB_CHILD | TDB_SCX); | 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); | PROC_UNLOCK(p); | ||||
} else if (p->p_flag & P_TRACED || td->td_dbgflags & TDB_BORN) { | } else if (p->p_flag & P_TRACED || td->td_dbgflags & TDB_BORN) { | ||||
/* | /* | ||||
* This is the start of a new thread in a traced | * This is the start of a new thread in a traced | ||||
* process. Report a system call exit event. | * process. Report a system call exit event. | ||||
*/ | */ | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
td->td_dbgflags |= TDB_SCX; | td->td_dbgflags |= TDB_SCX; | ||||
_STOPEVENT(p, S_SCX, td->td_dbg_sc_code); | _STOPEVENT(p, S_SCX, td->td_dbg_sc_code); | ||||
if ((p->p_ptevents & PTRACE_SCX) != 0 || | if ((p->p_ptevents & PTRACE_SCX) != 0 || | ||||
(td->td_dbgflags & TDB_BORN) != 0) | (td->td_dbgflags & TDB_BORN) != 0) | ||||
ptracestop(td, SIGTRAP); | ptracestop(td, SIGTRAP, NULL); | ||||
td->td_dbgflags &= ~(TDB_SCX | TDB_BORN); | td->td_dbgflags &= ~(TDB_SCX | TDB_BORN); | ||||
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 | ||||
} | } |