diff options
Diffstat (limited to 'sys/kern')
-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 |
3 files changed, 23 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); |