Author: kib
Date: Wed Nov  3 21:24:21 2010
New Revision: 214756
URL: http://svn.freebsd.org/changeset/base/214756

Log:
  MFC r209688:
  Extend ptrace(PT_LWPINFO) to report siginfo for the signal that caused
  debugee stop.

Modified:
  stable/8/sys/kern/kern_sig.c
  stable/8/sys/kern/sys_process.c
  stable/8/sys/sys/proc.h
  stable/8/sys/sys/ptrace.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/kern/kern_sig.c
==============================================================================
--- stable/8/sys/kern/kern_sig.c        Wed Nov  3 21:21:12 2010        
(r214755)
+++ stable/8/sys/kern/kern_sig.c        Wed Nov  3 21:24:21 2010        
(r214756)
@@ -2517,7 +2517,6 @@ issignal(struct thread *td, int stop_all
        struct sigacts *ps;
        struct sigqueue *queue;
        sigset_t sigpending;
-       ksiginfo_t ksi;
        int sig, prop, newsig;
 
        p = td->td_proc;
@@ -2560,10 +2559,10 @@ issignal(struct thread *td, int stop_all
                         * be thrown away.
                         */
                        queue = &td->td_sigqueue;
-                       ksi.ksi_signo = 0;
-                       if (sigqueue_get(queue, sig, &ksi) == 0) {
+                       td->td_dbgksi.ksi_signo = 0;
+                       if (sigqueue_get(queue, sig, &td->td_dbgksi) == 0) {
                                queue = &p->p_sigqueue;
-                               sigqueue_get(queue, sig, &ksi);
+                               sigqueue_get(queue, sig, &td->td_dbgksi);
                        }
 
                        mtx_unlock(&ps->ps_mtx);
@@ -2590,13 +2589,13 @@ issignal(struct thread *td, int stop_all
                                        continue;
                                signotify(td);
                        } else {
-                               if (ksi.ksi_signo != 0) {
-                                       ksi.ksi_flags |= KSI_HEAD;
+                               if (td->td_dbgksi.ksi_signo != 0) {
+                                       td->td_dbgksi.ksi_flags |= KSI_HEAD;
                                        if (sigqueue_add(&td->td_sigqueue, sig,
-                                           &ksi) != 0)
-                                               ksi.ksi_signo = 0;
+                                           &td->td_dbgksi) != 0)
+                                               td->td_dbgksi.ksi_signo = 0;
                                }
-                               if (ksi.ksi_signo == 0)
+                               if (td->td_dbgksi.ksi_signo == 0)
                                        sigqueue_add(&td->td_sigqueue, sig,
                                            NULL);
                        }

Modified: stable/8/sys/kern/sys_process.c
==============================================================================
--- stable/8/sys/kern/sys_process.c     Wed Nov  3 21:21:12 2010        
(r214755)
+++ stable/8/sys/kern/sys_process.c     Wed Nov  3 21:24:21 2010        
(r214756)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 
 #ifdef COMPAT_FREEBSD32
 #include <sys/procfs.h>
+#include <compat/freebsd32/freebsd32_signal.h>
 
 struct ptrace_io_desc32 {
        int             piod_op;
@@ -84,6 +85,15 @@ struct ptrace_vm_entry32 {
        uint32_t        pve_path;
 };
 
+struct ptrace_lwpinfo32 {
+       lwpid_t pl_lwpid;       /* LWP described. */
+       int     pl_event;       /* Event that stopped the LWP. */
+       int     pl_flags;       /* LWP flags. */
+       sigset_t        pl_sigmask;     /* LWP signal mask */
+       sigset_t        pl_siglist;     /* LWP pending signal */
+       struct siginfo32 pl_siginfo;    /* siginfo for signal */
+};
+
 #endif
 
 /*
@@ -495,6 +505,19 @@ ptrace_vm_entry32(struct thread *td, str
        pve32->pve_pathlen = pve.pve_pathlen;
        return (error);
 }
+
+static void
+ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
+    struct ptrace_lwpinfo32 *pl32)
+{
+
+       pl32->pl_lwpid = pl->pl_lwpid;
+       pl32->pl_event = pl->pl_event;
+       pl32->pl_flags = pl->pl_flags;
+       pl32->pl_sigmask = pl->pl_sigmask;
+       pl32->pl_siglist = pl->pl_siglist;
+       siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
+}
 #endif /* COMPAT_FREEBSD32 */
 
 /*
@@ -549,6 +572,7 @@ ptrace(struct thread *td, struct ptrace_
                struct fpreg32 fpreg32;
                struct reg32 reg32;
                struct ptrace_io_desc32 piod32;
+               struct ptrace_lwpinfo32 pl32;
                struct ptrace_vm_entry32 pve32;
 #endif
        } r;
@@ -659,6 +683,8 @@ kern_ptrace(struct thread *td, int req, 
 #ifdef COMPAT_FREEBSD32
        int wrap32 = 0, safe = 0;
        struct ptrace_io_desc32 *piod32 = NULL;
+       struct ptrace_lwpinfo32 *pl32 = NULL;
+       struct ptrace_lwpinfo plr;
 #endif
 
        curp = td->td_proc;
@@ -1100,15 +1126,44 @@ kern_ptrace(struct thread *td, int req, 
                break;
 
        case PT_LWPINFO:
-               if (data <= 0 || data > sizeof(*pl)) {
+               if (data <= 0 ||
+#ifdef COMPAT_FREEBSD32
+                   (!wrap32 && data > sizeof(*pl)) ||
+                   (wrap32 && data > sizeof(*pl32))) {
+#else
+                   data > sizeof(*pl)) {
+#endif
                        error = EINVAL;
                        break;
                }
+#ifdef COMPAT_FREEBSD32
+               if (wrap32) {
+                       pl = &plr;
+                       pl32 = addr;
+               } else
+#endif
                pl = addr;
                pl->pl_lwpid = td2->td_tid;
-               if (td2->td_dbgflags & TDB_XSIG)
-                       pl->pl_event = PL_EVENT_SIGNAL;
                pl->pl_flags = 0;
+               if (td2->td_dbgflags & TDB_XSIG) {
+                       pl->pl_event = PL_EVENT_SIGNAL;
+                       if (td2->td_dbgksi.ksi_signo != 0 &&
+#ifdef COMPAT_FREEBSD32
+                           ((!wrap32 && data >= offsetof(struct ptrace_lwpinfo,
+                           pl_siginfo) + sizeof(pl->pl_siginfo)) ||
+                           (wrap32 && data >= offsetof(struct ptrace_lwpinfo32,
+                           pl_siginfo) + sizeof(struct siginfo32)))
+#else
+                           data >= offsetof(struct ptrace_lwpinfo, pl_siginfo)
+                           + sizeof(pl->pl_siginfo)
+#endif
+                       ){
+                               pl->pl_flags |= PL_FLAG_SI;
+                               pl->pl_siginfo = td2->td_dbgksi.ksi_info;
+                       }
+               }
+               if ((pl->pl_flags & PL_FLAG_SI) == 0)
+                       bzero(&pl->pl_siginfo, sizeof(pl->pl_siginfo));
                if (td2->td_dbgflags & TDB_SCE)
                        pl->pl_flags |= PL_FLAG_SCE;
                else if (td2->td_dbgflags & TDB_SCX)
@@ -1117,6 +1172,10 @@ kern_ptrace(struct thread *td, int req, 
                        pl->pl_flags |= PL_FLAG_EXEC;
                pl->pl_sigmask = td2->td_sigmask;
                pl->pl_siglist = td2->td_siglist;
+#ifdef COMPAT_FREEBSD32
+               if (wrap32)
+                       ptrace_lwpinfo_to32(pl, pl32);
+#endif
                break;
 
        case PT_GETNUMLWPS:

Modified: stable/8/sys/sys/proc.h
==============================================================================
--- stable/8/sys/sys/proc.h     Wed Nov  3 21:21:12 2010        (r214755)
+++ stable/8/sys/sys/proc.h     Wed Nov  3 21:24:21 2010        (r214756)
@@ -257,6 +257,7 @@ struct thread {
        char            td_name[MAXCOMLEN + 1]; /* (*) Thread name. */
        struct file     *td_fpop;       /* (k) file referencing cdev under op */
        int             td_dbgflags;    /* (c) Userland debugger flags */
+       struct ksiginfo td_dbgksi;      /* (c) ksi reflected to debugger. */
        int             td_ng_outbound; /* (k) Thread entered ng from above. */
        struct osd      td_osd;         /* (k) Object specific data. */
 #define        td_endzero td_base_pri

Modified: stable/8/sys/sys/ptrace.h
==============================================================================
--- stable/8/sys/sys/ptrace.h   Wed Nov  3 21:21:12 2010        (r214755)
+++ stable/8/sys/sys/ptrace.h   Wed Nov  3 21:24:21 2010        (r214756)
@@ -33,7 +33,7 @@
 #ifndef        _SYS_PTRACE_H_
 #define        _SYS_PTRACE_H_
 
-#include <sys/_sigset.h>
+#include <sys/signal.h>
 #include <machine/reg.h>
 
 #define        PT_TRACE_ME     0       /* child declares it's being traced */
@@ -102,8 +102,10 @@ struct ptrace_lwpinfo {
 #define        PL_FLAG_SCE     0x04    /* syscall enter point */
 #define        PL_FLAG_SCX     0x08    /* syscall leave point */
 #define        PL_FLAG_EXEC    0x10    /* exec(2) succeeded */
+#define        PL_FLAG_SI      0x20    /* siginfo is valid */
        sigset_t        pl_sigmask;     /* LWP signal mask */
        sigset_t        pl_siglist;     /* LWP pending signal */
+       struct __siginfo pl_siginfo;    /* siginfo for signal */
 };
 
 /* Argument structure for PT_VM_ENTRY. */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to