Module Name: src
Committed By: kamil
Date: Fri Jan 13 23:00:35 UTC 2017
Modified Files:
src/sys/kern: kern_fork.c sys_ptrace_common.c
src/sys/sys: proc.h ptrace.h
Log Message:
Add support for PTRACE_VFORK_DONE and stub for PTRACE_VFORK in ptrace(2)
PTRACE_VFORK is supposed to be used to track vfork(2)-like events, when
parent gives birth to new process child and stops till it exits or calls
exec().
Currently PTRACE_VFORK is a stub.
PTRACE_VFORK_DONE is notification to notify a debugger that a parent has
resumed after vfork(2)-like action.
PTRACE_VFORK_DONE throws SIGTRAP with TRAP_CHLD.
Sponsored by <The NetBSD Foundation>
To generate a diff of this commit:
cvs rdiff -u -r1.198 -r1.199 src/sys/kern/kern_fork.c
cvs rdiff -u -r1.8 -r1.9 src/sys/kern/sys_ptrace_common.c
cvs rdiff -u -r1.335 -r1.336 src/sys/sys/proc.h
cvs rdiff -u -r1.52 -r1.53 src/sys/sys/ptrace.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_fork.c
diff -u src/sys/kern/kern_fork.c:1.198 src/sys/kern/kern_fork.c:1.199
--- src/sys/kern/kern_fork.c:1.198 Tue Jan 10 00:48:37 2017
+++ src/sys/kern/kern_fork.c Fri Jan 13 23:00:35 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_fork.c,v 1.198 2017/01/10 00:48:37 kamil Exp $ */
+/* $NetBSD: kern_fork.c,v 1.199 2017/01/13 23:00:35 kamil Exp $ */
/*-
* Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.198 2017/01/10 00:48:37 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.199 2017/01/13 23:00:35 kamil Exp $");
#include "opt_ktrace.h"
#include "opt_dtrace.h"
@@ -219,7 +219,7 @@ fork1(struct lwp *l1, int flags, int exi
int count;
vaddr_t uaddr;
int tnprocs;
- int tracefork;
+ int tracefork, tracevforkdone;
int error = 0;
p1 = l1->l_proc;
@@ -471,11 +471,12 @@ fork1(struct lwp *l1, int flags, int exi
p2->p_exitsig = exitsig; /* signal for parent on exit */
/*
- * We don't want to tracefork vfork()ed processes because they
- * will not receive the SIGTRAP until it is too late.
+ * Trace fork(2) and vfork(2)-like events on demand in a debugger.
*/
tracefork = (p1->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) ==
(PSL_TRACEFORK|PSL_TRACED) && (flags && FORK_PPWAIT) == 0;
+ tracevforkdone = (p1->p_slflag & (PSL_TRACEVFORK_DONE|PSL_TRACED)) ==
+ (PSL_TRACEVFORK_DONE|PSL_TRACED) && (flags && FORK_PPWAIT);
if (tracefork) {
proc_changeparent(p2, p1->p_pptr);
/*
@@ -484,6 +485,12 @@ fork1(struct lwp *l1, int flags, int exi
p1->p_fpid = p2->p_pid;
p2->p_fpid = p1->p_pid;
}
+ if (tracevforkdone) {
+ /*
+ * Set ptrace status.
+ */
+ p1->p_vfpid_done = p2->p_pid;
+ }
LIST_INSERT_AFTER(p1, p2, p_pglist);
LIST_INSERT_HEAD(&allproc, p2, p_list);
@@ -576,7 +583,7 @@ fork1(struct lwp *l1, int flags, int exi
/*
* Let the parent know that we are tracing its child.
*/
- if (tracefork) {
+ if (tracefork || tracevforkdone) {
ksiginfo_t ksi;
KSI_INIT_EMPTY(&ksi);
Index: src/sys/kern/sys_ptrace_common.c
diff -u src/sys/kern/sys_ptrace_common.c:1.8 src/sys/kern/sys_ptrace_common.c:1.9
--- src/sys/kern/sys_ptrace_common.c:1.8 Fri Jan 6 22:53:17 2017
+++ src/sys/kern/sys_ptrace_common.c Fri Jan 13 23:00:35 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_ptrace_common.c,v 1.8 2017/01/06 22:53:17 kamil Exp $ */
+/* $NetBSD: sys_ptrace_common.c,v 1.9 2017/01/13 23:00:35 kamil Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.8 2017/01/06 22:53:17 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.9 2017/01/13 23:00:35 kamil Exp $");
#ifdef _KERNEL_OPT
#include "opt_ptrace.h"
@@ -790,6 +790,8 @@ do_ptrace(struct ptrace_methods *ptm, st
}
sendsig:
t->p_fpid = 0;
+ t->p_vfpid = 0;
+ t->p_vfpid_done = 0;
/* Finally, deliver the requested signal (or none). */
if (t->p_stat == SSTOP) {
/*
@@ -855,6 +857,10 @@ do_ptrace(struct ptrace_methods *ptm, st
memset(&pe, 0, sizeof(pe));
pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ?
PTRACE_FORK : 0;
+ pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ?
+ PTRACE_VFORK : 0;
+ pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ?
+ PTRACE_VFORK_DONE : 0;
error = copyout(&pe, addr, sizeof(pe));
break;
@@ -871,6 +877,21 @@ do_ptrace(struct ptrace_methods *ptm, st
SET(t->p_slflag, PSL_TRACEFORK);
else
CLR(t->p_slflag, PSL_TRACEFORK);
+#if notyet
+ if (pe.pe_set_event & PTRACE_VFORK)
+ SET(t->p_slflag, PSL_TRACEVFORK);
+ else
+ CLR(t->p_slflag, PSL_TRACEVFORK);
+#else
+ if (pe.pe_set_event & PTRACE_VFORK) {
+ error = ENOTSUP;
+ break;
+ }
+#endif
+ if (pe.pe_set_event & PTRACE_VFORK_DONE)
+ SET(t->p_slflag, PSL_TRACEVFORK_DONE);
+ else
+ CLR(t->p_slflag, PSL_TRACEVFORK_DONE);
break;
case PT_GET_PROCESS_STATE:
@@ -884,6 +905,12 @@ do_ptrace(struct ptrace_methods *ptm, st
if (t->p_fpid) {
ps.pe_report_event = PTRACE_FORK;
ps.pe_other_pid = t->p_fpid;
+ } else if (t->p_vfpid) {
+ ps.pe_report_event = PTRACE_VFORK;
+ ps.pe_other_pid = t->p_vfpid;
+ } else if (t->p_vfpid_done) {
+ ps.pe_report_event = PTRACE_VFORK_DONE;
+ ps.pe_other_pid = t->p_vfpid_done;
}
error = copyout(&ps, addr, sizeof(ps));
break;
Index: src/sys/sys/proc.h
diff -u src/sys/sys/proc.h:1.335 src/sys/sys/proc.h:1.336
--- src/sys/sys/proc.h:1.335 Wed Oct 19 09:44:01 2016
+++ src/sys/sys/proc.h Fri Jan 13 23:00:35 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.335 2016/10/19 09:44:01 skrll Exp $ */
+/* $NetBSD: proc.h,v 1.336 2017/01/13 23:00:35 kamil Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -310,6 +310,8 @@ struct proc {
struct lcproc *p_lwpctl; /* p, a: _lwp_ctl() information */
pid_t p_ppid; /* :: cached parent pid */
pid_t p_fpid; /* :: forked pid */
+ pid_t p_vfpid; /* :: vforked pid */
+ pid_t p_vfpid_done; /* :: vforked done pid */
u_int p_nsems; /* Count of semaphores */
/*
@@ -398,6 +400,9 @@ struct proc {
* and p_lock. Access from process context only.
*/
#define PSL_TRACEFORK 0x00000001 /* traced process wants fork events */
+#define PSL_TRACEVFORK 0x00000002 /* traced process wants vfork events */
+#define PSL_TRACEVFORK_DONE \
+ 0x00000004 /* traced process wants vfork done events */
#define PSL_TRACED 0x00000800 /* Debugged process being traced */
#define PSL_FSTRACE 0x00010000 /* Debugger process being traced by procfs */
#define PSL_CHTRACED 0x00400000 /* Child has been traced & reparented */
Index: src/sys/sys/ptrace.h
diff -u src/sys/sys/ptrace.h:1.52 src/sys/sys/ptrace.h:1.53
--- src/sys/sys/ptrace.h:1.52 Fri Jan 6 22:53:17 2017
+++ src/sys/sys/ptrace.h Fri Jan 13 23:00:35 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ptrace.h,v 1.52 2017/01/06 22:53:17 kamil Exp $ */
+/* $NetBSD: ptrace.h,v 1.53 2017/01/13 23:00:35 kamil Exp $ */
/*-
* Copyright (c) 1984, 1993
@@ -93,7 +93,9 @@ typedef struct ptrace_state {
pid_t pe_other_pid;
} ptrace_state_t;
-#define PTRACE_FORK 0x0001 /* Report forks */
+#define PTRACE_FORK 0x0001 /* Report forks */
+#define PTRACE_VFORK 0x0002 /* Report vforks */
+#define PTRACE_VFORK_DONE 0x0004 /* Report parent resumed from vforks */
/*
* Argument structure for PT_IO.