diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_fork.c | 19 | ||||
-rw-r--r-- | sys/kern/subr_syscall.c | 5 |
2 files changed, 19 insertions, 5 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index b2727bc..9256f39 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -57,6 +57,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> @@ -1031,8 +1032,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)) == @@ -1049,9 +1050,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. @@ -1061,6 +1062,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); diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c index af09613..71f3d59 100644 --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -83,11 +83,12 @@ syscallenter(struct thread *td, struct syscall_args *sa) if (error == 0) { STOPEVENT(p, S_SCE, sa->narg); - if (p->p_flag & P_TRACED && p->p_stops & S_PT_SCE) { + if (p->p_flag & P_TRACED) { PROC_LOCK(p); td->td_dbg_sc_code = sa->code; td->td_dbg_sc_narg = sa->narg; - ptracestop((td), SIGTRAP); + if (p->p_stops & S_PT_SCE) + ptracestop((td), SIGTRAP); PROC_UNLOCK(p); } if (td->td_dbgflags & TDB_USERWR) { |