Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src PR/43128: Paul Koning: Threads support in ptrace() is insuff...



details:   https://anonhg.NetBSD.org/src/rev/c701f50fbbb0
branches:  trunk
changeset: 753673:c701f50fbbb0
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Apr 06 13:50:22 2010 +0000

description:
PR/43128: Paul Koning: Threads support in ptrace() is insufficient for gdb to
debug threaded live apps: Add an optional lwpid in PT_STEP and PT_CONTINUE to
indicate which lwp to operate on, and implement the glue required to make it
work.

diffstat:

 lib/libc/sys/ptrace.2  |  47 ++++++++++++++++++++++++++++++----
 sys/kern/kern_lwp.c    |  58 +++++++++++++++++++++++++++++++++++++++++--
 sys/kern/kern_sig.c    |   9 +++--
 sys/kern/sys_process.c |  67 ++++++++++++++++++++++++++++++++++++++++++++-----
 sys/sys/lwp.h          |   4 ++-
 5 files changed, 163 insertions(+), 22 deletions(-)

diffs (truncated from 397 to 300 lines):

diff -r 8ba45c41ef19 -r c701f50fbbb0 lib/libc/sys/ptrace.2
--- a/lib/libc/sys/ptrace.2     Tue Apr 06 10:45:15 2010 +0000
+++ b/lib/libc/sys/ptrace.2     Tue Apr 06 13:50:22 2010 +0000
@@ -1,7 +1,7 @@
-.\"    $NetBSD: ptrace.2,v 1.31 2010/03/22 19:30:55 joerg Exp $
+.\"    $NetBSD: ptrace.2,v 1.32 2010/04/06 13:50:22 christos Exp $
 .\"
 .\" This file is in the public domain.
-.Dd March 12, 2007
+.Dd April 6, 2010
 .Dt PTRACE 2
 .Os
 .Sh NAME
@@ -149,7 +149,9 @@
 to indicate that execution is to pick up where it left off.
 .Fa data
 provides a signal number to be delivered to the traced process as it
-resumes execution, or 0 if no signal is to be sent.
+resumes execution, or 0 if no signal is to be sent.  If a negative
+value is supplied, that is the negative of the LWP ID of the thread to
+be resumed, and only that thread executes.
 .It Dv PT_KILL
 The traced process terminates, as if
 .Dv PT_CONTINUE
@@ -256,8 +258,8 @@
 call currently does not stop the child process so it can generate
 inconsistent data.
 .It Dv PT_LWPINFO
-Returns information about the specific thread from the process specified
-in the
+Returns information about a thread from the list of threads for the
+process specified in the
 .Fa pid
 argument.
 The
@@ -274,8 +276,15 @@
 .Pp
 where
 .Fa pl_lwpid
-contains the thread for which to get info.
+contains a thread LWP ID.  Information is returned for the thread
+following the one with the specified ID in the process thread list,
+or for the first thread if
+.Fa pl_lwpid
+is 0.
 Upon return
+.Fa pl_lwpid
+contains the LWP ID of the thread that was found, or 0 if there is
+no thread after the one whose LWP ID was supplied in the call.
 .Fa pl_event
 contains the event that stopped the thread.
 Possible
@@ -303,6 +312,14 @@
 Execution continues as in request PT_CONTINUE; however
 as soon as possible after execution of at least one
 instruction, execution stops again.
+If the
+.Fa data
+argument is greater than 0, it contains the LWP ID of the thread to be
+stepped, and any other threads are continued.  If the 
+.Fa data
+argument is less than zero, it contains the negative of the LWP ID of
+the
+thread to be stepped, and only that thread executes.
 .It Dv PT_GETREGS
 This request reads the traced process' machine registers into the
 .Dq Li "struct reg"
@@ -310,6 +327,10 @@
 .In machine/reg.h )
 pointed to by
 .Fa addr .
+The 
+.Fa data
+argument contains the LWP ID of the thread whose registers are to
+be read.  If zero is supplied, the first thread of the process is read.
 .It Dv PT_SETREGS
 This request is the converse of
 .Dv PT_GETREGS ;
@@ -319,6 +340,10 @@
 .In machine/reg.h )
 pointed to by
 .Fa addr .
+The 
+.Fa data
+argument contains the LWP ID of the thread whose registers are to
+be written.  If zero is supplied, the first thread of the process is written.
 .It Dv PT_GETFPREGS
 This request reads the traced process' floating-point registers into
 the
@@ -327,6 +352,11 @@
 .In machine/reg.h )
 pointed to by
 .Fa addr .
+The 
+.Fa data
+argument contains the LWP ID of the thread whose registers are to
+be read.  If zero is supplied, the first thread of the process is 
+read.
 .It Dv PT_SETFPREGS
 This request is the converse of
 .Dv PT_GETFPREGS ;
@@ -336,6 +366,11 @@
 .In machine/reg.h )
 pointed to by
 .Fa addr .
+The 
+.Fa data
+argument contains the LWP ID of the thread whose registers are to
+be written.  If zero is supplied, the first thread of the process is 
+written.
 .\" .It Dv PT_SYSCALL
 .\" This request is like
 .\" .Dv PT_CONTINUE
diff -r 8ba45c41ef19 -r c701f50fbbb0 sys/kern/kern_lwp.c
--- a/sys/kern/kern_lwp.c       Tue Apr 06 10:45:15 2010 +0000
+++ b/sys/kern/kern_lwp.c       Tue Apr 06 13:50:22 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lwp.c,v 1.141 2010/03/01 21:10:17 darran Exp $    */
+/*     $NetBSD: kern_lwp.c,v 1.142 2010/04/06 13:50:22 christos Exp $  */
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -209,7 +209,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.141 2010/03/01 21:10:17 darran Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.142 2010/04/06 13:50:22 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -375,6 +375,44 @@
 }
 
 /*
+ * Restart a stopped LWP.
+ *
+ * Must be called with p_lock held, and the LWP NOT locked.  Will unlock the
+ * LWP before return.
+ */
+void
+lwp_unstop(struct lwp *l)
+{
+       struct proc *p = l->l_proc;
+    
+       KASSERT(mutex_owned(proc_lock));
+       KASSERT(mutex_owned(p->p_lock));
+
+       lwp_lock(l);
+
+       /* If not stopped, then just bail out. */
+       if (l->l_stat != LSSTOP) {
+               lwp_unlock(l);
+               return;
+       }
+
+       p->p_stat = SACTIVE;
+       p->p_sflag &= ~PS_STOPPING;
+
+       if (!p->p_waited)
+               p->p_pptr->p_nstopchild--;
+
+       if (l->l_wchan == NULL) {
+               /* setrunnable() will release the lock. */
+               setrunnable(l);
+       } else {
+               l->l_stat = LSSLEEP;
+               p->p_nrlwps++;
+               lwp_unlock(l);
+       }
+}
+
+/*
  * Wait for an LWP within the current process to exit.  If 'lid' is
  * non-zero, we are waiting for a specific LWP.
  *
@@ -1396,11 +1434,25 @@
        struct proc *p = l->l_proc;
 
        mutex_enter(p->p_lock);
+       lwp_delref2(l);
+       mutex_exit(p->p_lock);
+}
+
+/*
+ * Remove one reference to an LWP.  If this is the last reference,
+ * then we must finalize the LWP's death.  The proc mutex is held
+ * on entry.
+ */
+void
+lwp_delref2(struct lwp *l)
+{
+       struct proc *p = l->l_proc;
+
+       KASSERT(mutex_owned(p->p_lock));
        KASSERT(l->l_stat != LSZOMB);
        KASSERT(l->l_refcnt > 0);
        if (--l->l_refcnt == 0)
                cv_broadcast(&p->p_lwpcv);
-       mutex_exit(p->p_lock);
 }
 
 /*
diff -r 8ba45c41ef19 -r c701f50fbbb0 sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c       Tue Apr 06 10:45:15 2010 +0000
+++ b/sys/kern/kern_sig.c       Tue Apr 06 13:50:22 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sig.c,v 1.304 2010/03/03 00:47:31 yamt Exp $      */
+/*     $NetBSD: kern_sig.c,v 1.305 2010/04/06 13:50:22 christos Exp $  */
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.304 2010/03/03 00:47:31 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.305 2010/04/06 13:50:22 christos Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_compat_sunos.h"
@@ -1725,9 +1725,10 @@
 
        /*
         * If we are no longer being traced, or the parent didn't
-        * give us a signal, look for more signals.
+        * give us a signal, or we're stopping, look for more signals.
         */
-       if ((p->p_slflag & PSL_TRACED) == 0 || p->p_xstat == 0)
+       if ((p->p_slflag & PSL_TRACED) == 0 || p->p_xstat == 0 ||
+           (p->p_sflag & PS_STOPPING) != 0)
                return 0;
 
        /*
diff -r 8ba45c41ef19 -r c701f50fbbb0 sys/kern/sys_process.c
--- a/sys/kern/sys_process.c    Tue Apr 06 10:45:15 2010 +0000
+++ b/sys/kern/sys_process.c    Tue Apr 06 13:50:22 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_process.c,v 1.153 2009/12/17 01:25:10 rmind Exp $  */
+/*     $NetBSD: sys_process.c,v 1.154 2010/04/06 13:50:22 christos Exp $       */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.153 2009/12/17 01:25:10 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.154 2010/04/06 13:50:22 christos Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_ktrace.h"
@@ -227,7 +227,7 @@
                syscallarg(int) data;
        } */
        struct proc *p = l->l_proc;
-       struct lwp *lt;
+       struct lwp *lt, *lt2;
        struct proc *t;                         /* target process */
        struct uio uio;
        struct iovec iov;
@@ -235,7 +235,8 @@
        struct ptrace_lwpinfo pl;
        struct vmspace *vm;
        int error, write, tmp, req, pheld;
-       int signo;
+       int signo = 0;
+       int resume_all;
        ksiginfo_t ksi;
        char *path;
        int len;
@@ -463,6 +464,7 @@
        write = 0;
        *retval = 0;
        tmp = 0;
+       resume_all = 1;
 
        switch (req) {
        case  PT_TRACE_ME:
@@ -597,6 +599,44 @@
                p->p_trace_enabled = trace_is_enabled(p);
 
                /*
+                * Pick up the LWPID, if supplied.  There are two cases:
+                * data < 0 : step or continue single thread, lwp = -data
+                * data > 0 in PT_STEP : step this thread, continue others
+                * For operations other than PT_STEP, data > 0 means
+                * data is the signo to deliver to the process.
+                */
+               tmp = SCARG(uap, data);
+               if (tmp >= 0) {
+#ifdef PT_STEP
+                       if (req == PT_STEP)
+                               signo = 0;
+                       else
+#endif
+                       {
+                               signo = tmp;
+                               tmp = 0;        /* don't search for LWP */
+                       }



Home | Main Index | Thread Index | Old Index