From fe6dcaae7a2deebf79a7d104452568ef751e1a43 Mon Sep 17 00:00:00 2001 From: markj Date: Sat, 9 Aug 2014 15:00:05 +0000 Subject: [PATCH] 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. git-svn-id: svn://svn.freebsd.org/base/stable/9@269755 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- lib/libproc/libproc.h | 1 + lib/libproc/proc_bkpt.c | 29 ++++++++++++++--------------- lib/libproc/proc_util.c | 24 +++++++++++++++--------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/libproc/libproc.h b/lib/libproc/libproc.h index d80e88c46..be77e4b59 100644 --- a/lib/libproc/libproc.h +++ b/lib/libproc/libproc.h @@ -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; diff --git a/lib/libproc/proc_bkpt.c b/lib/libproc/proc_bkpt.c index e30fdf52f..386439ba3 100644 --- a/lib/libproc/proc_bkpt.c +++ b/lib/libproc/proc_bkpt.c @@ -49,13 +49,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) { @@ -81,7 +74,7 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, { 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 || @@ -92,9 +85,12 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, 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. @@ -129,9 +125,9 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, } 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); } @@ -142,7 +138,7 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address, { 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) { @@ -152,9 +148,12 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address, 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. @@ -171,9 +170,9 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address, 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); } diff --git a/lib/libproc/proc_util.c b/lib/libproc/proc_util.c index 1c3d5229c..4d9aa20b3 100644 --- a/lib/libproc/proc_util.c +++ b/lib/libproc/proc_util.c @@ -35,10 +35,9 @@ #include #include #include -#include -#include #include #include +#include #include "_libproc.h" int @@ -59,11 +58,14 @@ proc_clearflags(struct proc_handle *phdl, int mask) 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 *phdl) 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) { -- 2.45.0