summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_fork.c19
-rw-r--r--sys/kern/subr_syscall.c5
-rw-r--r--sys/sys/proc.h4
3 files changed, 21 insertions, 7 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) {
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index ae01bbf..749c18e 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -283,8 +283,6 @@ struct thread {
int td_no_sleeping; /* (k) Sleeping disabled count. */
int td_dom_rr_idx; /* (k) RR Numa domain selection. */
void *td_su; /* (k) FFS SU private */
- u_int td_dbg_sc_code; /* (c) Syscall code to debugger. */
- u_int td_dbg_sc_narg; /* (c) Syscall arg count to debugger.*/
#define td_endzero td_sigmask
/* Copied during fork1() or create_thread(). */
@@ -296,6 +294,8 @@ struct thread {
u_char td_pri_class; /* (t) Scheduling class. */
u_char td_user_pri; /* (t) User pri from estcpu and nice. */
u_char td_base_user_pri; /* (t) Base user pri */
+ u_int td_dbg_sc_code; /* (c) Syscall code to debugger. */
+ u_int td_dbg_sc_narg; /* (c) Syscall arg count to debugger.*/
#define td_endcopy td_pcb
/*
OpenPOWER on IntegriCloud