summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_process.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-08-15 21:33:20 +0000
committerkib <kib@FreeBSD.org>2016-08-15 21:33:20 +0000
commit408eededdb2bb7077a33012ddbd6270510245b89 (patch)
treeaab983f61a25cca07298ad57e075b24c546692cc /sys/kern/sys_process.c
parente4842c451d2fcb20d4e7734a423b4dda17c5e79b (diff)
downloadFreeBSD-src-408eededdb2bb7077a33012ddbd6270510245b89.zip
FreeBSD-src-408eededdb2bb7077a33012ddbd6270510245b89.tar.gz
MFC r303423:
Force SIGSTOP to be the first signal reported after the attach.
Diffstat (limited to 'sys/kern/sys_process.c')
-rw-r--r--sys/kern/sys_process.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index f1477ce..751db15 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -692,6 +692,17 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
#define PROC_WRITE(w, t, a) proc_write_ ## w (t, a)
#endif
+void
+proc_set_traced(struct proc *p)
+{
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ p->p_flag |= P_TRACED;
+ p->p_flag2 |= P2_PTRACE_FSTP;
+ p->p_ptevents = PTRACE_DEFAULT;
+ p->p_oppid = p->p_pptr->p_pid;
+}
+
int
kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
{
@@ -899,11 +910,9 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
switch (req) {
case PT_TRACE_ME:
/* set my trace flag and "owner" so it can read/write me */
- p->p_flag |= P_TRACED;
- p->p_ptevents = PTRACE_DEFAULT;
+ proc_set_traced(p);
if (p->p_flag & P_PPWAIT)
p->p_flag |= P_PPTRACE;
- p->p_oppid = p->p_pptr->p_pid;
CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid);
break;
@@ -918,9 +927,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
* The old parent is remembered so we can put things back
* on a "detach".
*/
- p->p_flag |= P_TRACED;
- p->p_ptevents = PTRACE_DEFAULT;
- p->p_oppid = p->p_pptr->p_pid;
+ proc_set_traced(p);
if (p->p_pptr != td->td_proc) {
proc_reparent(p, td->td_proc);
}
@@ -1088,6 +1095,17 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
p->p_pid, data);
p->p_oppid = 0;
p->p_ptevents = 0;
+ FOREACH_THREAD_IN_PROC(p, td3) {
+ if ((td3->td_dbgflags & TDB_FSTP) != 0) {
+ sigqueue_delete(&td3->td_sigqueue,
+ SIGSTOP);
+ }
+ td3->td_dbgflags &= ~(TDB_XSIG | TDB_FSTP);
+ }
+ if ((p->p_flag2 & P2_PTRACE_FSTP) != 0) {
+ sigqueue_delete(&p->p_sigqueue, SIGSTOP);
+ p->p_flag2 &= ~P2_PTRACE_FSTP;
+ }
/* should we send SIGCHLD? */
/* childproc_continued(p); */
@@ -1108,7 +1126,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
if (req == PT_DETACH) {
FOREACH_THREAD_IN_PROC(p, td3)
- td3->td_dbgflags &= ~TDB_SUSPEND;
+ td3->td_dbgflags &= ~TDB_SUSPEND;
}
/*
* unsuspend all threads, to not let a thread run,
OpenPOWER on IntegriCloud