diff options
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r-- | sys/kern/kern_fork.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 10b2339..99451c0 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/procdesc.h> #include <sys/pioctl.h> +#include <sys/ptrace.h> #include <sys/racct.h> #include <sys/resourcevar.h> #include <sys/sched.h> @@ -478,6 +479,8 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, td2->td_sigstk = td->td_sigstk; td2->td_flags = TDF_INMEM; td2->td_lend_user_pri = PRI_MAX; + td2->td_dbg_sc_code = td->td_dbg_sc_code; + td2->td_dbg_sc_narg = td->td_dbg_sc_narg; #ifdef VIMAGE td2->td_vnet = NULL; @@ -1049,8 +1052,8 @@ fork_return(struct thread *td, struct trapframe *frame) { struct proc *p, *dbg; + p = td->td_proc; if (td->td_dbgflags & TDB_STOPATFORK) { - p = td->td_proc; sx_xlock(&proctree_lock); PROC_LOCK(p); if ((p->p_pptr->p_flag & (P_TRACED | P_FOLLOWFORK)) == @@ -1067,9 +1070,9 @@ fork_return(struct thread *td, struct trapframe *frame) p->p_pid, p->p_oppid); proc_reparent(p, dbg); sx_xunlock(&proctree_lock); - td->td_dbgflags |= TDB_CHILD; + td->td_dbgflags |= TDB_CHILD | TDB_SCX; ptracestop(td, SIGSTOP); - td->td_dbgflags &= ~TDB_CHILD; + td->td_dbgflags &= ~(TDB_CHILD | TDB_SCX); } else { /* * ... otherwise clear the request. @@ -1079,6 +1082,18 @@ fork_return(struct thread *td, struct trapframe *frame) 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); } userret(td, frame); |