aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2004-07-12 05:07:50 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2004-07-12 05:07:50 +0000
commitfbc3247d816a6c4c77324fdbd4e9188abc46aabe (patch)
tree354f543bfcbe27c384ccc9ed5c1d36a3fc6a26d1
parent98c151d6d952b5bc9e0142eb5d08b9e18d661b99 (diff)
downloadsrc-fbc3247d816a6c4c77324fdbd4e9188abc46aabe.tar.gz
src-fbc3247d816a6c4c77324fdbd4e9188abc46aabe.zip
Implement the PT_LWPINFO request. This request can be used by the
tracing process to obtain information about the LWP that caused the traced process to stop. Debuggers can use this information to select the thread currently running on the LWP as the current thread. The request has been made compatible with NetBSD for as much as possible. This implementation differs from NetBSD in the following ways: 1. The data argument is allowed to be smaller than the size of the ptrace_lwpinfo structure known to the kernel, but not 0. This is opposite to what NetBSD allows. The reason for this is that we can extend the structure without affecting older binaries. 2. On NetBSD the tracing process is to set the pl_lwpid field to the Id of the LWP it wants information of. We don't do that. Our ptrace interface allows passing the LWP Id instead of the PID. The tracing process is to set the PID to the LWP Id it wants information of. 3. When the PID is actually the PID of the tracing process, this request returns the information about the LWP that caused the process to stop. This was the whole purpose of the request in the first place. When the traced process has exited, this request will return the LWP Id 0, indicating that the process state is not the result of an event specific to a LWP.
Notes
Notes: svn path=/head/; revision=132016
-rw-r--r--sys/kern/kern_exit.c1
-rw-r--r--sys/kern/kern_sig.c3
-rw-r--r--sys/kern/sys_process.c19
-rw-r--r--sys/sys/proc.h1
-rw-r--r--sys/sys/ptrace.h9
5 files changed, 33 insertions, 0 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 5d0f4c3c879b..056116d96e83 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 d17cbe232c54..bbc9e281e6f9 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 f65b67c75a74..0cae07b970c5 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 8246c599fc43..bf3c78846a76 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 c849eb6fc195..03ff33c13ce6 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) \