Author: markj
Date: Sat Aug  9 15:00:03 2014
New Revision: 269754
URL: http://svnweb.freebsd.org/changeset/base/269754

Log:
  MFC r265308:
  If the traced process stops because it received a signal, libproc needs
  to ensure that the signal is forwarded when proc_continue() is called.

Modified:
  stable/10/lib/libproc/libproc.h
  stable/10/lib/libproc/proc_bkpt.c
  stable/10/lib/libproc/proc_util.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libproc/libproc.h
==============================================================================
--- stable/10/lib/libproc/libproc.h     Sat Aug  9 14:33:44 2014        
(r269753)
+++ stable/10/lib/libproc/libproc.h     Sat Aug  9 15:00:03 2014        
(r269754)
@@ -102,6 +102,7 @@ typedef struct lwpstatus {
 #define PR_FAULTED     2
 #define PR_SYSENTRY    3
 #define PR_SYSEXIT     4
+#define PR_SIGNALLED   5
        int pr_what;
 #define FLTBPT         -1
 } lwpstatus_t;

Modified: stable/10/lib/libproc/proc_bkpt.c
==============================================================================
--- stable/10/lib/libproc/proc_bkpt.c   Sat Aug  9 14:33:44 2014        
(r269753)
+++ stable/10/lib/libproc/proc_bkpt.c   Sat Aug  9 15:00:03 2014        
(r269754)
@@ -55,13 +55,6 @@ __FBSDID("$FreeBSD$");
 #error "Add support for your architecture"
 #endif
 
-static void
-proc_cont(struct proc_handle *phdl)
-{
-
-       ptrace(PT_CONTINUE, proc_getpid(phdl), (caddr_t)1, 0);
-}
-
 static int
 proc_stop(struct proc_handle *phdl)
 {
@@ -87,7 +80,7 @@ proc_bkptset(struct proc_handle *phdl, u
 {
        struct ptrace_io_desc piod;
        unsigned long paddr, caddr;
-       int ret = 0;
+       int ret = 0, stopped;
 
        *saved = 0;
        if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
@@ -98,9 +91,12 @@ proc_bkptset(struct proc_handle *phdl, u
 
        DPRINTFX("adding breakpoint at 0x%lx", address);
 
-       if (phdl->status != PS_STOP)
+       stopped = 0;
+       if (phdl->status != PS_STOP) {
                if (proc_stop(phdl) != 0)
                        return (-1);
+               stopped = 1;
+       }
 
        /*
         * Read the original instruction.
@@ -135,9 +131,9 @@ proc_bkptset(struct proc_handle *phdl, u
        }
 
 done:
-       if (phdl->status != PS_STOP)
+       if (stopped)
                /* Restart the process if we had to stop it. */
-               proc_cont(phdl);
+               proc_continue(phdl);
 
        return (ret);
 }
@@ -148,7 +144,7 @@ proc_bkptdel(struct proc_handle *phdl, u
 {
        struct ptrace_io_desc piod;
        unsigned long paddr, caddr;
-       int ret = 0;
+       int ret = 0, stopped;
 
        if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
            phdl->status == PS_IDLE) {
@@ -158,9 +154,12 @@ proc_bkptdel(struct proc_handle *phdl, u
 
        DPRINTFX("removing breakpoint at 0x%lx", address);
 
-       if (phdl->status != PS_STOP)
+       stopped = 0;
+       if (phdl->status != PS_STOP) {
                if (proc_stop(phdl) != 0)
                        return (-1);
+               stopped = 1;
+       }
 
        /*
         * Overwrite the breakpoint instruction that we setup previously.
@@ -177,9 +176,9 @@ proc_bkptdel(struct proc_handle *phdl, u
                ret = -1;
        }
 
-       if (phdl->status != PS_STOP)
+       if (stopped)
                /* Restart the process if we had to stop it. */
-               proc_cont(phdl);
+               proc_continue(phdl);
  
        return (ret);
 }

Modified: stable/10/lib/libproc/proc_util.c
==============================================================================
--- stable/10/lib/libproc/proc_util.c   Sat Aug  9 14:33:44 2014        
(r269753)
+++ stable/10/lib/libproc/proc_util.c   Sat Aug  9 15:00:03 2014        
(r269754)
@@ -35,10 +35,9 @@
 #include <sys/wait.h>
 #include <err.h>
 #include <errno.h>
-#include <unistd.h>
-#include <stdio.h>
 #include <signal.h>
 #include <string.h>
+#include <unistd.h>
 #include "_libproc.h"
 
 int
@@ -59,11 +58,14 @@ proc_clearflags(struct proc_handle *phdl
 int
 proc_continue(struct proc_handle *phdl)
 {
+       int pending = 0;
 
        if (phdl == NULL)
                return (-1);
 
-       if (ptrace(PT_CONTINUE, phdl->pid, (caddr_t)(uintptr_t) 1, 0) != 0)
+       if (phdl->status == PS_STOP && WSTOPSIG(phdl->wstat) != SIGTRAP)
+               pending = WSTOPSIG(phdl->wstat);
+       if (ptrace(PT_CONTINUE, phdl->pid, (caddr_t)(uintptr_t)1, pending) != 0)
                return (-1);
 
        phdl->status = PS_RUN;
@@ -208,12 +210,16 @@ proc_getlwpstatus(struct proc_handle *ph
                return (NULL);
        siginfo = &lwpinfo.pl_siginfo;
        if (lwpinfo.pl_event == PL_EVENT_SIGNAL &&
-           (lwpinfo.pl_flags & PL_FLAG_SI) &&
-           siginfo->si_signo == SIGTRAP &&
-           (siginfo->si_code == TRAP_BRKPT ||
-           siginfo->si_code == TRAP_TRACE)) {
-               psp->pr_why = PR_FAULTED;
-               psp->pr_what = FLTBPT;
+           (lwpinfo.pl_flags & PL_FLAG_SI) != 0) {
+               if (siginfo->si_signo == SIGTRAP &&
+                   (siginfo->si_code == TRAP_BRKPT ||
+                   siginfo->si_code == TRAP_TRACE)) {
+                       psp->pr_why = PR_FAULTED;
+                       psp->pr_what = FLTBPT;
+               } else {
+                       psp->pr_why = PR_SIGNALLED;
+                       psp->pr_what = siginfo->si_signo;
+               }
        } else if (lwpinfo.pl_flags & PL_FLAG_SCE) {
                psp->pr_why = PR_SYSENTRY;
        } else if (lwpinfo.pl_flags & PL_FLAG_SCX) {
_______________________________________________
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