diff options
-rw-r--r-- | sys/kern/kern_exit.c | 1 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 3 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 19 | ||||
-rw-r--r-- | sys/sys/proc.h | 1 | ||||
-rw-r--r-- | sys/sys/ptrace.h | 9 |
5 files changed, 33 insertions, 0 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 5d0f4c3..056116d 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -429,6 +429,7 @@ retry: mtx_lock(&Giant); PROC_LOCK(p); p->p_xstat = rv; + p->p_xlwpid = td->td_tid; *p->p_ru = p->p_stats->p_ru; mtx_lock_spin(&sched_lock); calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL); diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index d17cbe2..bbc9e28 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1882,6 +1882,7 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target) goto out; p->p_flag |= P_STOPPED_SIG; p->p_xstat = sig; + p->p_xlwpid = td->td_tid; mtx_lock_spin(&sched_lock); FOREACH_THREAD_IN_PROC(p, td0) { if (TD_IS_SLEEPING(td0) && @@ -2011,6 +2012,7 @@ ptracestop(struct thread *td, int sig) &p->p_mtx.mtx_object, "Stopping for traced signal"); p->p_xstat = sig; + p->p_xlwpid = td->td_tid; PROC_LOCK(p->p_pptr); psignal(p->p_pptr, SIGCHLD); PROC_UNLOCK(p->p_pptr); @@ -2154,6 +2156,7 @@ issignal(td) &p->p_mtx.mtx_object, "Catching SIGSTOP"); p->p_flag |= P_STOPPED_SIG; p->p_xstat = sig; + p->p_xlwpid = td->td_tid; mtx_lock_spin(&sched_lock); FOREACH_THREAD_IN_PROC(p, td0) { if (TD_IS_SLEEPING(td0) && diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index f65b67c..0cae07b 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -305,6 +305,7 @@ ptrace(struct thread *td, struct ptrace_args *uap) */ union { struct ptrace_io_desc piod; + struct ptrace_lwpinfo pl; struct dbreg dbreg; struct fpreg fpreg; struct reg reg; @@ -317,6 +318,7 @@ ptrace(struct thread *td, struct ptrace_args *uap) case PT_GETREGS: case PT_GETFPREGS: case PT_GETDBREGS: + case PT_LWPINFO: break; case PT_SETREGS: error = copyin(uap->addr, &r.reg, sizeof r.reg); @@ -354,6 +356,9 @@ ptrace(struct thread *td, struct ptrace_args *uap) case PT_GETDBREGS: error = copyout(&r.dbreg, uap->addr, sizeof r.dbreg); break; + case PT_LWPINFO: + error = copyout(&r.pl, uap->addr, uap->data); + break; } return (error); @@ -367,6 +372,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) struct proc *curp, *p, *pp; struct thread *td2 = NULL; struct ptrace_io_desc *piod; + struct ptrace_lwpinfo *pl; int error, write, tmp; int proctree_locked = 0; lwpid_t tid = 0; @@ -606,6 +612,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) /* deliver or queue signal */ if (P_SHOULDSTOP(p)) { p->p_xstat = data; + p->p_xlwpid = 0; p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG); mtx_lock_spin(&sched_lock); thread_unsuspend(p); @@ -727,6 +734,17 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) PROC_UNLOCK(p); return (error); + case PT_LWPINFO: + if (data == 0 || data > sizeof(*pl)) + return (EINVAL); + pl = addr; + _PHOLD(p); + pl->pl_lwpid = p->p_xlwpid; + _PRELE(p); + PROC_UNLOCK(p); + pl->pl_event = PL_EVENT_SIGNAL; + return (0); + default: #ifdef __HAVE_PTRACE_MACHDEP if (req >= PT_FIRSTMACH) { @@ -764,6 +782,7 @@ stopevent(struct proc *p, unsigned int event, unsigned int val) p->p_step = 1; do { p->p_xstat = val; + p->p_xlwpid = 0; p->p_stype = event; /* Which event caused the stop? */ wakeup(&p->p_stype); /* Wake up any PIOCWAIT'ing procs */ msleep(&p->p_step, &p->p_mtx, PWAIT, "stopevent", 0); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 8246c59..bf3c788 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -602,6 +602,7 @@ struct proc { #define p_endcopy p_xstat u_short p_xstat; /* (c) Exit status; also stop sig. */ + lwpid_t p_xlwpid; /* (c) Thread corresponding p_xstat. */ int p_numthreads; /* (j) Number of threads. */ int p_numksegrps; /* (?) number of ksegrps */ struct mdproc p_md; /* Any machine-dependent fields. */ diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h index c849eb6..03ff33c 100644 --- a/sys/sys/ptrace.h +++ b/sys/sys/ptrace.h @@ -47,6 +47,7 @@ #define PT_ATTACH 10 /* trace some running process */ #define PT_DETACH 11 /* stop tracing a process */ #define PT_IO 12 /* do I/O to/from stopped process. */ +#define PT_LWPINFO 13 /* Info about the LWP that stopped. */ #define PT_TO_SCE 20 #define PT_TO_SCX 21 @@ -77,6 +78,14 @@ struct ptrace_io_desc { #define PIOD_READ_I 3 /* Read from I space */ #define PIOD_WRITE_I 4 /* Write to I space */ +/* Argument structure for PT_LWPINFO. */ +struct ptrace_lwpinfo { + lwpid_t pl_lwpid; /* LWP described. */ + int pl_event; /* Event that stopped the LWP. */ +#define PL_EVENT_NONE 0 +#define PL_EVENT_SIGNAL 1 +}; + #ifdef _KERNEL #define PTRACESTOP_SC(p, td, flag) \ |