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>diff -r1.198 -r1.199 src/sys/kern/kern_fork.c
(kamil)
--- src/sys/kern/kern_fork.c 2017/01/10 00:48:37 1.198
+++ src/sys/kern/kern_fork.c 2017/01/13 23:00:35 1.199
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: kern_fork.c,v 1.198 2017/01/10 00:48:37 kamil Exp $ */ | 1 | /* $NetBSD: kern_fork.c,v 1.199 2017/01/13 23:00:35 kamil Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | 8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | |
9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. | 9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -57,27 +57,27 @@ | @@ -57,27 +57,27 @@ | |||
57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
64 | * SUCH DAMAGE. | 64 | * SUCH DAMAGE. | |
65 | * | 65 | * | |
66 | * @(#)kern_fork.c 8.8 (Berkeley) 2/14/95 | 66 | * @(#)kern_fork.c 8.8 (Berkeley) 2/14/95 | |
67 | */ | 67 | */ | |
68 | 68 | |||
69 | #include <sys/cdefs.h> | 69 | #include <sys/cdefs.h> | |
70 | __KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.198 2017/01/10 00:48:37 kamil Exp $"); | 70 | __KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.199 2017/01/13 23:00:35 kamil Exp $"); | |
71 | 71 | |||
72 | #include "opt_ktrace.h" | 72 | #include "opt_ktrace.h" | |
73 | #include "opt_dtrace.h" | 73 | #include "opt_dtrace.h" | |
74 | 74 | |||
75 | #include <sys/param.h> | 75 | #include <sys/param.h> | |
76 | #include <sys/systm.h> | 76 | #include <sys/systm.h> | |
77 | #include <sys/filedesc.h> | 77 | #include <sys/filedesc.h> | |
78 | #include <sys/kernel.h> | 78 | #include <sys/kernel.h> | |
79 | #include <sys/pool.h> | 79 | #include <sys/pool.h> | |
80 | #include <sys/mount.h> | 80 | #include <sys/mount.h> | |
81 | #include <sys/proc.h> | 81 | #include <sys/proc.h> | |
82 | #include <sys/ras.h> | 82 | #include <sys/ras.h> | |
83 | #include <sys/resourcevar.h> | 83 | #include <sys/resourcevar.h> | |
@@ -209,27 +209,27 @@ static struct timeval fork_tfmrate = { 1 | @@ -209,27 +209,27 @@ static struct timeval fork_tfmrate = { 1 | |||
209 | */ | 209 | */ | |
210 | int | 210 | int | |
211 | fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize, | 211 | fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize, | |
212 | void (*func)(void *), void *arg, register_t *retval, | 212 | void (*func)(void *), void *arg, register_t *retval, | |
213 | struct proc **rnewprocp) | 213 | struct proc **rnewprocp) | |
214 | { | 214 | { | |
215 | struct proc *p1, *p2, *parent; | 215 | struct proc *p1, *p2, *parent; | |
216 | struct plimit *p1_lim; | 216 | struct plimit *p1_lim; | |
217 | uid_t uid; | 217 | uid_t uid; | |
218 | struct lwp *l2; | 218 | struct lwp *l2; | |
219 | int count; | 219 | int count; | |
220 | vaddr_t uaddr; | 220 | vaddr_t uaddr; | |
221 | int tnprocs; | 221 | int tnprocs; | |
222 | int tracefork; | 222 | int tracefork, tracevforkdone; | |
223 | int error = 0; | 223 | int error = 0; | |
224 | 224 | |||
225 | p1 = l1->l_proc; | 225 | p1 = l1->l_proc; | |
226 | uid = kauth_cred_getuid(l1->l_cred); | 226 | uid = kauth_cred_getuid(l1->l_cred); | |
227 | tnprocs = atomic_inc_uint_nv(&nprocs); | 227 | tnprocs = atomic_inc_uint_nv(&nprocs); | |
228 | 228 | |||
229 | /* | 229 | /* | |
230 | * Although process entries are dynamically created, we still keep | 230 | * Although process entries are dynamically created, we still keep | |
231 | * a global limit on the maximum number we will create. | 231 | * a global limit on the maximum number we will create. | |
232 | */ | 232 | */ | |
233 | if (__predict_false(tnprocs >= maxproc)) | 233 | if (__predict_false(tnprocs >= maxproc)) | |
234 | error = -1; | 234 | error = -1; | |
235 | else | 235 | else | |
@@ -461,39 +461,46 @@ fork1(struct lwp *l1, int flags, int exi | @@ -461,39 +461,46 @@ fork1(struct lwp *l1, int flags, int exi | |||
461 | /* | 461 | /* | |
462 | * It's now safe for the scheduler and other processes to see the | 462 | * It's now safe for the scheduler and other processes to see the | |
463 | * child process. | 463 | * child process. | |
464 | */ | 464 | */ | |
465 | mutex_enter(proc_lock); | 465 | mutex_enter(proc_lock); | |
466 | 466 | |||
467 | if (p1->p_session->s_ttyvp != NULL && p1->p_lflag & PL_CONTROLT) | 467 | if (p1->p_session->s_ttyvp != NULL && p1->p_lflag & PL_CONTROLT) | |
468 | p2->p_lflag |= PL_CONTROLT; | 468 | p2->p_lflag |= PL_CONTROLT; | |
469 | 469 | |||
470 | LIST_INSERT_HEAD(&parent->p_children, p2, p_sibling); | 470 | LIST_INSERT_HEAD(&parent->p_children, p2, p_sibling); | |
471 | p2->p_exitsig = exitsig; /* signal for parent on exit */ | 471 | p2->p_exitsig = exitsig; /* signal for parent on exit */ | |
472 | 472 | |||
473 | /* | 473 | /* | |
474 | * We don't want to tracefork vfork()ed processes because they | 474 | * Trace fork(2) and vfork(2)-like events on demand in a debugger. | |
475 | * will not receive the SIGTRAP until it is too late. | |||
476 | */ | 475 | */ | |
477 | tracefork = (p1->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) == | 476 | tracefork = (p1->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) == | |
478 | (PSL_TRACEFORK|PSL_TRACED) && (flags && FORK_PPWAIT) == 0; | 477 | (PSL_TRACEFORK|PSL_TRACED) && (flags && FORK_PPWAIT) == 0; | |
478 | tracevforkdone = (p1->p_slflag & (PSL_TRACEVFORK_DONE|PSL_TRACED)) == | |||
479 | (PSL_TRACEVFORK_DONE|PSL_TRACED) && (flags && FORK_PPWAIT); | |||
479 | if (tracefork) { | 480 | if (tracefork) { | |
480 | proc_changeparent(p2, p1->p_pptr); | 481 | proc_changeparent(p2, p1->p_pptr); | |
481 | /* | 482 | /* | |
482 | * Set ptrace status. | 483 | * Set ptrace status. | |
483 | */ | 484 | */ | |
484 | p1->p_fpid = p2->p_pid; | 485 | p1->p_fpid = p2->p_pid; | |
485 | p2->p_fpid = p1->p_pid; | 486 | p2->p_fpid = p1->p_pid; | |
486 | } | 487 | } | |
488 | if (tracevforkdone) { | |||
489 | /* | |||
490 | * Set ptrace status. | |||
491 | */ | |||
492 | p1->p_vfpid_done = p2->p_pid; | |||
493 | } | |||
487 | 494 | |||
488 | LIST_INSERT_AFTER(p1, p2, p_pglist); | 495 | LIST_INSERT_AFTER(p1, p2, p_pglist); | |
489 | LIST_INSERT_HEAD(&allproc, p2, p_list); | 496 | LIST_INSERT_HEAD(&allproc, p2, p_list); | |
490 | 497 | |||
491 | p2->p_trace_enabled = trace_is_enabled(p2); | 498 | p2->p_trace_enabled = trace_is_enabled(p2); | |
492 | #ifdef __HAVE_SYSCALL_INTERN | 499 | #ifdef __HAVE_SYSCALL_INTERN | |
493 | (*p2->p_emul->e_syscall_intern)(p2); | 500 | (*p2->p_emul->e_syscall_intern)(p2); | |
494 | #endif | 501 | #endif | |
495 | 502 | |||
496 | /* | 503 | /* | |
497 | * Update stats now that we know the fork was successful. | 504 | * Update stats now that we know the fork was successful. | |
498 | */ | 505 | */ | |
499 | uvmexp.forks++; | 506 | uvmexp.forks++; | |
@@ -566,26 +573,26 @@ fork1(struct lwp *l1, int flags, int exi | @@ -566,26 +573,26 @@ fork1(struct lwp *l1, int flags, int exi | |||
566 | } | 573 | } | |
567 | mutex_exit(p2->p_lock); | 574 | mutex_exit(p2->p_lock); | |
568 | 575 | |||
569 | /* | 576 | /* | |
570 | * Preserve synchronization semantics of vfork. If waiting for | 577 | * Preserve synchronization semantics of vfork. If waiting for | |
571 | * child to exec or exit, sleep until it clears LP_VFORKWAIT. | 578 | * child to exec or exit, sleep until it clears LP_VFORKWAIT. | |
572 | */ | 579 | */ | |
573 | while (p2->p_lflag & PL_PPWAIT) | 580 | while (p2->p_lflag & PL_PPWAIT) | |
574 | cv_wait(&p1->p_waitcv, proc_lock); | 581 | cv_wait(&p1->p_waitcv, proc_lock); | |
575 | 582 | |||
576 | /* | 583 | /* | |
577 | * Let the parent know that we are tracing its child. | 584 | * Let the parent know that we are tracing its child. | |
578 | */ | 585 | */ | |
579 | if (tracefork) { | 586 | if (tracefork || tracevforkdone) { | |
580 | ksiginfo_t ksi; | 587 | ksiginfo_t ksi; | |
581 | 588 | |||
582 | KSI_INIT_EMPTY(&ksi); | 589 | KSI_INIT_EMPTY(&ksi); | |
583 | ksi.ksi_signo = SIGTRAP; | 590 | ksi.ksi_signo = SIGTRAP; | |
584 | ksi.ksi_code = TRAP_CHLD; | 591 | ksi.ksi_code = TRAP_CHLD; | |
585 | ksi.ksi_lid = l1->l_lid; | 592 | ksi.ksi_lid = l1->l_lid; | |
586 | kpsignal(p1, &ksi, NULL); | 593 | kpsignal(p1, &ksi, NULL); | |
587 | } | 594 | } | |
588 | mutex_exit(proc_lock); | 595 | mutex_exit(proc_lock); | |
589 | 596 | |||
590 | return 0; | 597 | return 0; | |
591 | } | 598 | } |
--- src/sys/kern/sys_ptrace_common.c 2017/01/06 22:53:17 1.8
+++ src/sys/kern/sys_ptrace_common.c 2017/01/13 23:00:35 1.9
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: sys_ptrace_common.c,v 1.8 2017/01/06 22:53:17 kamil Exp $ */ | 1 | /* $NetBSD: sys_ptrace_common.c,v 1.9 2017/01/13 23:00:35 kamil Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Andrew Doran. | 8 | * by Andrew Doran. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -108,27 +108,27 @@ | @@ -108,27 +108,27 @@ | |||
108 | 108 | |||
109 | /* | 109 | /* | |
110 | * References: | 110 | * References: | |
111 | * (1) Bach's "The Design of the UNIX Operating System", | 111 | * (1) Bach's "The Design of the UNIX Operating System", | |
112 | * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, | 112 | * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, | |
113 | * (3) the "4.4BSD Programmer's Reference Manual" published | 113 | * (3) the "4.4BSD Programmer's Reference Manual" published | |
114 | * by USENIX and O'Reilly & Associates. | 114 | * by USENIX and O'Reilly & Associates. | |
115 | * The 4.4BSD PRM does a reasonably good job of documenting what the various | 115 | * The 4.4BSD PRM does a reasonably good job of documenting what the various | |
116 | * ptrace() requests should actually do, and its text is quoted several times | 116 | * ptrace() requests should actually do, and its text is quoted several times | |
117 | * in this file. | 117 | * in this file. | |
118 | */ | 118 | */ | |
119 | 119 | |||
120 | #include <sys/cdefs.h> | 120 | #include <sys/cdefs.h> | |
121 | __KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.8 2017/01/06 22:53:17 kamil Exp $"); | 121 | __KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.9 2017/01/13 23:00:35 kamil Exp $"); | |
122 | 122 | |||
123 | #ifdef _KERNEL_OPT | 123 | #ifdef _KERNEL_OPT | |
124 | #include "opt_ptrace.h" | 124 | #include "opt_ptrace.h" | |
125 | #include "opt_ktrace.h" | 125 | #include "opt_ktrace.h" | |
126 | #include "opt_pax.h" | 126 | #include "opt_pax.h" | |
127 | #endif | 127 | #endif | |
128 | 128 | |||
129 | #include <sys/param.h> | 129 | #include <sys/param.h> | |
130 | #include <sys/systm.h> | 130 | #include <sys/systm.h> | |
131 | #include <sys/proc.h> | 131 | #include <sys/proc.h> | |
132 | #include <sys/errno.h> | 132 | #include <sys/errno.h> | |
133 | #include <sys/exec.h> | 133 | #include <sys/exec.h> | |
134 | #include <sys/pax.h> | 134 | #include <sys/pax.h> | |
@@ -780,26 +780,28 @@ do_ptrace(struct ptrace_methods *ptm, st | @@ -780,26 +780,28 @@ do_ptrace(struct ptrace_methods *ptm, st | |||
780 | CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); | 780 | CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); | |
781 | 781 | |||
782 | /* give process back to original parent or init */ | 782 | /* give process back to original parent or init */ | |
783 | if (t->p_opptr != t->p_pptr) { | 783 | if (t->p_opptr != t->p_pptr) { | |
784 | struct proc *pp = t->p_opptr; | 784 | struct proc *pp = t->p_opptr; | |
785 | proc_reparent(t, pp ? pp : initproc); | 785 | proc_reparent(t, pp ? pp : initproc); | |
786 | } | 786 | } | |
787 | 787 | |||
788 | /* not being traced any more */ | 788 | /* not being traced any more */ | |
789 | t->p_opptr = NULL; | 789 | t->p_opptr = NULL; | |
790 | } | 790 | } | |
791 | sendsig: | 791 | sendsig: | |
792 | t->p_fpid = 0; | 792 | t->p_fpid = 0; | |
793 | t->p_vfpid = 0; | |||
794 | t->p_vfpid_done = 0; | |||
793 | /* Finally, deliver the requested signal (or none). */ | 795 | /* Finally, deliver the requested signal (or none). */ | |
794 | if (t->p_stat == SSTOP) { | 796 | if (t->p_stat == SSTOP) { | |
795 | /* | 797 | /* | |
796 | * Unstop the process. If it needs to take a | 798 | * Unstop the process. If it needs to take a | |
797 | * signal, make all efforts to ensure that at | 799 | * signal, make all efforts to ensure that at | |
798 | * an LWP runs to see it. | 800 | * an LWP runs to see it. | |
799 | */ | 801 | */ | |
800 | t->p_xsig = signo; | 802 | t->p_xsig = signo; | |
801 | if (resume_all) | 803 | if (resume_all) | |
802 | proc_unstop(t); | 804 | proc_unstop(t); | |
803 | else | 805 | else | |
804 | lwp_unstop(lt); | 806 | lwp_unstop(lt); | |
805 | } else if (t->p_sigctx.ps_faked) { | 807 | } else if (t->p_sigctx.ps_faked) { | |
@@ -845,55 +847,80 @@ do_ptrace(struct ptrace_methods *ptm, st | @@ -845,55 +847,80 @@ do_ptrace(struct ptrace_methods *ptm, st | |||
845 | signo = SIGSTOP; | 847 | signo = SIGSTOP; | |
846 | goto sendsig; | 848 | goto sendsig; | |
847 | 849 | |||
848 | case PT_GET_EVENT_MASK: | 850 | case PT_GET_EVENT_MASK: | |
849 | if (data != sizeof(pe)) { | 851 | if (data != sizeof(pe)) { | |
850 | DPRINTF(("ptrace(%d): %d != %zu\n", req, | 852 | DPRINTF(("ptrace(%d): %d != %zu\n", req, | |
851 | data, sizeof(pe))); | 853 | data, sizeof(pe))); | |
852 | error = EINVAL; | 854 | error = EINVAL; | |
853 | break; | 855 | break; | |
854 | } | 856 | } | |
855 | memset(&pe, 0, sizeof(pe)); | 857 | memset(&pe, 0, sizeof(pe)); | |
856 | pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? | 858 | pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? | |
857 | PTRACE_FORK : 0; | 859 | PTRACE_FORK : 0; | |
860 | pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ? | |||
861 | PTRACE_VFORK : 0; | |||
862 | pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ? | |||
863 | PTRACE_VFORK_DONE : 0; | |||
858 | error = copyout(&pe, addr, sizeof(pe)); | 864 | error = copyout(&pe, addr, sizeof(pe)); | |
859 | break; | 865 | break; | |
860 | 866 | |||
861 | case PT_SET_EVENT_MASK: | 867 | case PT_SET_EVENT_MASK: | |
862 | if (data != sizeof(pe)) { | 868 | if (data != sizeof(pe)) { | |
863 | DPRINTF(("ptrace(%d): %d != %zu\n", req, data, | 869 | DPRINTF(("ptrace(%d): %d != %zu\n", req, data, | |
864 | sizeof(pe))); | 870 | sizeof(pe))); | |
865 | error = EINVAL; | 871 | error = EINVAL; | |
866 | break; | 872 | break; | |
867 | } | 873 | } | |
868 | if ((error = copyin(addr, &pe, sizeof(pe))) != 0) | 874 | if ((error = copyin(addr, &pe, sizeof(pe))) != 0) | |
869 | return error; | 875 | return error; | |
870 | if (pe.pe_set_event & PTRACE_FORK) | 876 | if (pe.pe_set_event & PTRACE_FORK) | |
871 | SET(t->p_slflag, PSL_TRACEFORK); | 877 | SET(t->p_slflag, PSL_TRACEFORK); | |
872 | else | 878 | else | |
873 | CLR(t->p_slflag, PSL_TRACEFORK); | 879 | CLR(t->p_slflag, PSL_TRACEFORK); | |
880 | #if notyet | |||
881 | if (pe.pe_set_event & PTRACE_VFORK) | |||
882 | SET(t->p_slflag, PSL_TRACEVFORK); | |||
883 | else | |||
884 | CLR(t->p_slflag, PSL_TRACEVFORK); | |||
885 | #else | |||
886 | if (pe.pe_set_event & PTRACE_VFORK) { | |||
887 | error = ENOTSUP; | |||
888 | break; | |||
889 | } | |||
890 | #endif | |||
891 | if (pe.pe_set_event & PTRACE_VFORK_DONE) | |||
892 | SET(t->p_slflag, PSL_TRACEVFORK_DONE); | |||
893 | else | |||
894 | CLR(t->p_slflag, PSL_TRACEVFORK_DONE); | |||
874 | break; | 895 | break; | |
875 | 896 | |||
876 | case PT_GET_PROCESS_STATE: | 897 | case PT_GET_PROCESS_STATE: | |
877 | if (data != sizeof(ps)) { | 898 | if (data != sizeof(ps)) { | |
878 | DPRINTF(("ptrace(%d): %d != %zu\n", req, data, | 899 | DPRINTF(("ptrace(%d): %d != %zu\n", req, data, | |
879 | sizeof(ps))); | 900 | sizeof(ps))); | |
880 | error = EINVAL; | 901 | error = EINVAL; | |
881 | break; | 902 | break; | |
882 | } | 903 | } | |
883 | memset(&ps, 0, sizeof(ps)); | 904 | memset(&ps, 0, sizeof(ps)); | |
884 | if (t->p_fpid) { | 905 | if (t->p_fpid) { | |
885 | ps.pe_report_event = PTRACE_FORK; | 906 | ps.pe_report_event = PTRACE_FORK; | |
886 | ps.pe_other_pid = t->p_fpid; | 907 | ps.pe_other_pid = t->p_fpid; | |
908 | } else if (t->p_vfpid) { | |||
909 | ps.pe_report_event = PTRACE_VFORK; | |||
910 | ps.pe_other_pid = t->p_vfpid; | |||
911 | } else if (t->p_vfpid_done) { | |||
912 | ps.pe_report_event = PTRACE_VFORK_DONE; | |||
913 | ps.pe_other_pid = t->p_vfpid_done; | |||
887 | } | 914 | } | |
888 | error = copyout(&ps, addr, sizeof(ps)); | 915 | error = copyout(&ps, addr, sizeof(ps)); | |
889 | break; | 916 | break; | |
890 | 917 | |||
891 | case PT_LWPINFO: | 918 | case PT_LWPINFO: | |
892 | if (data != sizeof(pl)) { | 919 | if (data != sizeof(pl)) { | |
893 | DPRINTF(("ptrace(%d): %d != %zu\n", req, data, | 920 | DPRINTF(("ptrace(%d): %d != %zu\n", req, data, | |
894 | sizeof(pl))); | 921 | sizeof(pl))); | |
895 | error = EINVAL; | 922 | error = EINVAL; | |
896 | break; | 923 | break; | |
897 | } | 924 | } | |
898 | error = copyin(addr, &pl, sizeof(pl)); | 925 | error = copyin(addr, &pl, sizeof(pl)); | |
899 | if (error) | 926 | if (error) |
--- src/sys/sys/proc.h 2016/10/19 09:44:01 1.335
+++ src/sys/sys/proc.h 2017/01/13 23:00:35 1.336
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: proc.h,v 1.335 2016/10/19 09:44:01 skrll Exp $ */ | 1 | /* $NetBSD: proc.h,v 1.336 2017/01/13 23:00:35 kamil Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Andrew Doran. | 8 | * by Andrew Doran. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -300,26 +300,28 @@ struct proc { | @@ -300,26 +300,28 @@ struct proc { | |||
300 | void *p_tracep; /* k: Trace private data */ | 300 | void *p_tracep; /* k: Trace private data */ | |
301 | struct vnode *p_textvp; /* :: Vnode of executable */ | 301 | struct vnode *p_textvp; /* :: Vnode of executable */ | |
302 | 302 | |||
303 | struct emul *p_emul; /* :: emulation information */ | 303 | struct emul *p_emul; /* :: emulation information */ | |
304 | void *p_emuldata; /* :: per-proc emul data, or NULL */ | 304 | void *p_emuldata; /* :: per-proc emul data, or NULL */ | |
305 | const struct execsw *p_execsw; /* :: exec package information */ | 305 | const struct execsw *p_execsw; /* :: exec package information */ | |
306 | struct klist p_klist; /* p: knotes attached to proc */ | 306 | struct klist p_klist; /* p: knotes attached to proc */ | |
307 | 307 | |||
308 | LIST_HEAD(, lwp) p_sigwaiters; /* p: LWPs waiting for signals */ | 308 | LIST_HEAD(, lwp) p_sigwaiters; /* p: LWPs waiting for signals */ | |
309 | sigpend_t p_sigpend; /* p: pending signals */ | 309 | sigpend_t p_sigpend; /* p: pending signals */ | |
310 | struct lcproc *p_lwpctl; /* p, a: _lwp_ctl() information */ | 310 | struct lcproc *p_lwpctl; /* p, a: _lwp_ctl() information */ | |
311 | pid_t p_ppid; /* :: cached parent pid */ | 311 | pid_t p_ppid; /* :: cached parent pid */ | |
312 | pid_t p_fpid; /* :: forked pid */ | 312 | pid_t p_fpid; /* :: forked pid */ | |
313 | pid_t p_vfpid; /* :: vforked pid */ | |||
314 | pid_t p_vfpid_done; /* :: vforked done pid */ | |||
313 | u_int p_nsems; /* Count of semaphores */ | 315 | u_int p_nsems; /* Count of semaphores */ | |
314 | 316 | |||
315 | /* | 317 | /* | |
316 | * End area that is zeroed on creation | 318 | * End area that is zeroed on creation | |
317 | */ | 319 | */ | |
318 | #define p_endzero p_startcopy | 320 | #define p_endzero p_startcopy | |
319 | 321 | |||
320 | /* | 322 | /* | |
321 | * The following fields are all copied upon creation in fork. | 323 | * The following fields are all copied upon creation in fork. | |
322 | */ | 324 | */ | |
323 | #define p_startcopy p_sigctx | 325 | #define p_startcopy p_sigctx | |
324 | 326 | |||
325 | struct sigctx p_sigctx; /* p: Shared signal state */ | 327 | struct sigctx p_sigctx; /* p: Shared signal state */ | |
@@ -388,26 +390,29 @@ struct proc { | @@ -388,26 +390,29 @@ struct proc { | |||
388 | #define PS_STOPFORK 0x00800000 /* Child will be stopped on fork(2) */ | 390 | #define PS_STOPFORK 0x00800000 /* Child will be stopped on fork(2) */ | |
389 | #define PS_STOPEXEC 0x01000000 /* Will be stopped on exec(2) */ | 391 | #define PS_STOPEXEC 0x01000000 /* Will be stopped on exec(2) */ | |
390 | #define PS_STOPEXIT 0x02000000 /* Will be stopped at process exit */ | 392 | #define PS_STOPEXIT 0x02000000 /* Will be stopped at process exit */ | |
391 | #define PS_NOTIFYSTOP 0x10000000 /* Notify parent of successful STOP */ | 393 | #define PS_NOTIFYSTOP 0x10000000 /* Notify parent of successful STOP */ | |
392 | #define PS_COREDUMP 0x20000000 /* Process core-dumped */ | 394 | #define PS_COREDUMP 0x20000000 /* Process core-dumped */ | |
393 | #define PS_CONTINUED 0x40000000 /* Process is continued */ | 395 | #define PS_CONTINUED 0x40000000 /* Process is continued */ | |
394 | #define PS_STOPPING 0x80000000 /* Transitioning SACTIVE -> SSTOP */ | 396 | #define PS_STOPPING 0x80000000 /* Transitioning SACTIVE -> SSTOP */ | |
395 | 397 | |||
396 | /* | 398 | /* | |
397 | * These flags are kept in p_slflag and are protected by the proc_lock | 399 | * These flags are kept in p_slflag and are protected by the proc_lock | |
398 | * and p_lock. Access from process context only. | 400 | * and p_lock. Access from process context only. | |
399 | */ | 401 | */ | |
400 | #define PSL_TRACEFORK 0x00000001 /* traced process wants fork events */ | 402 | #define PSL_TRACEFORK 0x00000001 /* traced process wants fork events */ | |
403 | #define PSL_TRACEVFORK 0x00000002 /* traced process wants vfork events */ | |||
404 | #define PSL_TRACEVFORK_DONE \ | |||
405 | 0x00000004 /* traced process wants vfork done events */ | |||
401 | #define PSL_TRACED 0x00000800 /* Debugged process being traced */ | 406 | #define PSL_TRACED 0x00000800 /* Debugged process being traced */ | |
402 | #define PSL_FSTRACE 0x00010000 /* Debugger process being traced by procfs */ | 407 | #define PSL_FSTRACE 0x00010000 /* Debugger process being traced by procfs */ | |
403 | #define PSL_CHTRACED 0x00400000 /* Child has been traced & reparented */ | 408 | #define PSL_CHTRACED 0x00400000 /* Child has been traced & reparented */ | |
404 | #define PSL_SYSCALL 0x04000000 /* process has PT_SYSCALL enabled */ | 409 | #define PSL_SYSCALL 0x04000000 /* process has PT_SYSCALL enabled */ | |
405 | #define PSL_SYSCALLEMU 0x08000000 /* cancel in-progress syscall */ | 410 | #define PSL_SYSCALLEMU 0x08000000 /* cancel in-progress syscall */ | |
406 | 411 | |||
407 | /* | 412 | /* | |
408 | * Kept in p_stflag and protected by p_stmutex. | 413 | * Kept in p_stflag and protected by p_stmutex. | |
409 | */ | 414 | */ | |
410 | #define PST_PROFIL 0x00000020 /* Has started profiling */ | 415 | #define PST_PROFIL 0x00000020 /* Has started profiling */ | |
411 | 416 | |||
412 | /* | 417 | /* | |
413 | * Kept in p_lflag and protected by the proc_lock. Access | 418 | * Kept in p_lflag and protected by the proc_lock. Access |
--- src/sys/sys/ptrace.h 2017/01/06 22:53:17 1.52
+++ src/sys/sys/ptrace.h 2017/01/13 23:00:35 1.53
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ptrace.h,v 1.52 2017/01/06 22:53:17 kamil Exp $ */ | 1 | /* $NetBSD: ptrace.h,v 1.53 2017/01/13 23:00:35 kamil Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1984, 1993 | 4 | * Copyright (c) 1984, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -83,27 +83,29 @@ | @@ -83,27 +83,29 @@ | |||
83 | /* 20 */ "PT_GET_SIGINFO", | 83 | /* 20 */ "PT_GET_SIGINFO", | |
84 | 84 | |||
85 | /* PT_{G,S}EVENT_MASK */ | 85 | /* PT_{G,S}EVENT_MASK */ | |
86 | typedef struct ptrace_event { | 86 | typedef struct ptrace_event { | |
87 | int pe_set_event; | 87 | int pe_set_event; | |
88 | } ptrace_event_t; | 88 | } ptrace_event_t; | |
89 | 89 | |||
90 | /* PT_GET_PROCESS_STATE */ | 90 | /* PT_GET_PROCESS_STATE */ | |
91 | typedef struct ptrace_state { | 91 | typedef struct ptrace_state { | |
92 | int pe_report_event; | 92 | int pe_report_event; | |
93 | pid_t pe_other_pid; | 93 | pid_t pe_other_pid; | |
94 | } ptrace_state_t; | 94 | } ptrace_state_t; | |
95 | 95 | |||
96 | #define PTRACE_FORK 0x0001 /* Report forks */ | 96 | #define PTRACE_FORK 0x0001 /* Report forks */ | |
97 | #define PTRACE_VFORK 0x0002 /* Report vforks */ | |||
98 | #define PTRACE_VFORK_DONE 0x0004 /* Report parent resumed from vforks */ | |||
97 | 99 | |||
98 | /* | 100 | /* | |
99 | * Argument structure for PT_IO. | 101 | * Argument structure for PT_IO. | |
100 | */ | 102 | */ | |
101 | struct ptrace_io_desc { | 103 | struct ptrace_io_desc { | |
102 | int piod_op; /* I/O operation (see below) */ | 104 | int piod_op; /* I/O operation (see below) */ | |
103 | void *piod_offs; /* child offset */ | 105 | void *piod_offs; /* child offset */ | |
104 | void *piod_addr; /* parent offset */ | 106 | void *piod_addr; /* parent offset */ | |
105 | size_t piod_len; /* request length (in)/actual count (out) */ | 107 | size_t piod_len; /* request length (in)/actual count (out) */ | |
106 | }; | 108 | }; | |
107 | 109 | |||
108 | /* piod_op */ | 110 | /* piod_op */ | |
109 | #define PIOD_READ_D 1 /* read from D space */ | 111 | #define PIOD_READ_D 1 /* read from D space */ |