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.