Rework the fork(2)/vfork(2) event signalling under ptrace(2)

Remove the constraint of SIGTRAP event being maskable by a tracee.

Now all SIGTRAP TRAP_CHLD events are delivered to debugger.

This code touches MD specific logic and the child_return routine.
It's an intermediate step with a room for refactoring in future and
right now the least invasive approach. This allows to assert expected
behavior in already existing ATF tests and make the code prettier
in future keeping the same semantics. Probably there is a need for a MI
wrapper of child_return for shared functionality between ports.
This commit is contained in:
kamil 2019-04-03 08:07:59 +00:00
parent bd33a461ed
commit 857b4b62b8
14 changed files with 202 additions and 51 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.42 2013/06/26 15:09:59 matt Exp $ */
/* $NetBSD: syscall.c,v 1.43 2019/04/03 08:07:59 kamil Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -89,7 +89,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.42 2013/06/26 15:09:59 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.43 2019/04/03 08:07:59 kamil Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -221,6 +221,18 @@ void
child_return(void *arg)
{
struct lwp * const l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
/*
* Return values in the frame set by cpu_lwp_fork().

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.65 2018/05/25 15:37:57 martin Exp $ */
/* $NetBSD: syscall.c,v 1.66 2019/04/03 08:07:59 kamil Exp $ */
/*-
* Copyright (c) 2000, 2003 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
#include <sys/param.h>
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.65 2018/05/25 15:37:57 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.66 2019/04/03 08:07:59 kamil Exp $");
#include <sys/cpu.h>
#include <sys/device.h>
@ -287,6 +287,19 @@ void
child_return(void *arg)
{
lwp_t * const l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
struct trapframe * const tf = lwp_trapframe(l);
tf->tf_r0 = 0;
@ -305,4 +318,3 @@ cpu_spawn_return(struct lwp *l)
userret(l);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.107 2015/03/02 11:05:12 martin Exp $ */
/* $NetBSD: trap.c,v 1.108 2019/04/03 08:07:59 kamil Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@ -58,7 +58,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.107 2015/03/02 11:05:12 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.108 2019/04/03 08:07:59 kamil Exp $");
/* #define INTRDEBUG */
/* #define TRAPDEBUG */
@ -986,6 +986,18 @@ void
child_return(void *arg)
{
struct lwp *l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
/*
* Return values in the frame set by cpu_lwp_fork().

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.7 2018/11/14 21:10:59 scole Exp $ */
/* $NetBSD: syscall.c,v 1.8 2019/04/03 08:07:59 kamil Exp $ */
/*
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -32,7 +32,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.7 2018/11/14 21:10:59 scole Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.8 2019/04/03 08:07:59 kamil Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -79,6 +79,23 @@ void
child_return(void *arg)
{
panic("XXX %s: not implemented\n", __func__);
#ifdef notyet
struct lwp *l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
#endif
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: m68k_syscall.c,v 1.51 2018/12/19 13:57:48 maxv Exp $ */
/* $NetBSD: m68k_syscall.c,v 1.52 2019/04/03 08:07:59 kamil Exp $ */
/*-
* Portions Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: m68k_syscall.c,v 1.51 2018/12/19 13:57:48 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: m68k_syscall.c,v 1.52 2019/04/03 08:07:59 kamil Exp $");
#include "opt_execfmt.h"
#include "opt_compat_netbsd.h"
@ -394,6 +394,19 @@ void
child_return(void *arg)
{
struct lwp *l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
/* See cpu_lwp_fork() */
struct frame *f = (struct frame *)l->l_md.md_regs;

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.246 2018/02/08 19:16:24 bouyer Exp $ */
/* $NetBSD: trap.c,v 1.247 2019/04/03 08:08:00 kamil Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.246 2018/02/08 19:16:24 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.247 2019/04/03 08:08:00 kamil Exp $");
#include "opt_cputype.h" /* which mips CPU levels do we support? */
#include "opt_ddb.h"
@ -129,6 +129,18 @@ child_return(void *arg)
{
struct lwp *l = arg;
struct trapframe *utf = l->l_md.md_utf;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
utf->tf_regs[_R_V0] = 0;
utf->tf_regs[_R_V1] = 1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.53 2013/11/03 22:22:03 mrg Exp $ */
/* $NetBSD: syscall.c,v 1.54 2019/04/03 08:08:00 kamil Exp $ */
/*
* Copyright (C) 2002 Matt Thomas
@ -61,12 +61,25 @@
#define EMULNAME(x) (x)
#define EMULNAMEU(x) (x)
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.53 2013/11/03 22:22:03 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.54 2019/04/03 08:08:00 kamil Exp $");
void
child_return(void *arg)
{
struct lwp * const l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
struct trapframe * const tf = l->l_md.md_utf;
tf->tf_fixreg[FIRSTARG] = 0;

View File

@ -31,7 +31,7 @@
#include "opt_modular.h"
__RCSID("$NetBSD: riscv_machdep.c,v 1.2 2017/03/16 16:13:21 chs Exp $");
__RCSID("$NetBSD: riscv_machdep.c,v 1.3 2019/04/03 08:08:00 kamil Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -120,6 +120,18 @@ child_return(void *arg)
{
struct lwp * const l = arg;
struct trapframe * const tf = l->l_md.md_utf;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
tf->tf_a0 = 0;
tf->tf_a1 = 1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.77 2016/12/23 07:15:28 cherry Exp $ */
/* $NetBSD: vm_machdep.c,v 1.78 2019/04/03 08:08:00 kamil Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
@ -81,7 +81,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.77 2016/12/23 07:15:28 cherry Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.78 2019/04/03 08:08:00 kamil Exp $");
#include "opt_kstack_debug.h"
@ -244,6 +244,18 @@ child_return(void *arg)
{
struct lwp *l = arg;
struct trapframe *tf = l->l_md.md_regs;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
tf->tf_r0 = 0; /* fork(2) returns 0 in child */
tf->tf_ssr |= PSL_TBIT; /* syscall succeeded */

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.29 2015/10/04 08:19:13 joerg Exp $ */
/* $NetBSD: syscall.c,v 1.30 2019/04/03 08:08:00 kamil Exp $ */
/*
* Copyright (c) 1996
@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.29 2015/10/04 08:19:13 joerg Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.30 2019/04/03 08:08:00 kamil Exp $");
#include "opt_sparc_arch.h"
#include "opt_multiprocessor.h"
@ -286,6 +286,18 @@ void
child_return(void *arg)
{
struct lwp *l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
/*
* Return values in the frame set by cpu_lwp_fork().
@ -304,4 +316,3 @@ cpu_spawn_return(struct lwp *l)
userret(l, l->l_md.md_tf->tf_pc, 0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.46 2015/11/09 20:26:15 christos Exp $ */
/* $NetBSD: syscall.c,v 1.47 2019/04/03 08:08:00 kamil Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.46 2015/11/09 20:26:15 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.47 2019/04/03 08:08:00 kamil Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -368,6 +368,18 @@ void
child_return(void *arg)
{
struct lwp *l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
/*
* Return values in the frame set by cpu_lwp_fork().

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.24 2017/05/22 16:53:05 ragge Exp $ */
/* $NetBSD: syscall.c,v 1.25 2019/04/03 08:08:00 kamil Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
@ -28,7 +28,7 @@
/* All bugs are subject to removal without further notice */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.24 2017/05/22 16:53:05 ragge Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.25 2019/04/03 08:08:00 kamil Exp $");
#include "opt_multiprocessor.h"
@ -132,6 +132,18 @@ void
child_return(void *arg)
{
struct lwp *l = arg;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
userret(l, l->l_md.md_utf, 0);
ktrsysret(SYS_fork, 0, 0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.16 2017/08/12 07:21:57 maxv Exp $ */
/* $NetBSD: syscall.c,v 1.17 2019/04/03 08:08:00 kamil Exp $ */
/*-
* Copyright (c) 1998, 2000, 2009 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.16 2017/08/12 07:21:57 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.17 2019/04/03 08:08:00 kamil Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -61,6 +61,18 @@ child_return(void *arg)
{
struct lwp *l = arg;
struct trapframe *tf = l->l_md.md_regs;
struct proc *p = l->l_proc;
if (p->p_slflag & PSL_TRACED) {
mutex_enter(p->p_lock);
p->p_xsig = SIGTRAP;
p->p_sigctx.ps_faked = true; // XXX
p->p_sigctx.ps_info._signo = p->p_xsig;
p->p_sigctx.ps_info._code = TRAP_CHLD;
sigswitch(0, SIGTRAP, true);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p->p_lock);
}
X86_TF_RAX(tf) = 0;
X86_TF_RFLAGS(tf) &= ~PSL_C;
@ -174,4 +186,3 @@ syscall_intern(struct proc *p)
p->p_md.md_syscall = syscall;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_fork.c,v 1.205 2018/05/01 16:37:23 kamil Exp $ */
/* $NetBSD: kern_fork.c,v 1.206 2019/04/03 08:08:00 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.205 2018/05/01 16:37:23 kamil Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.206 2019/04/03 08:08:00 kamil Exp $");
#include "opt_ktrace.h"
#include "opt_dtrace.h"
@ -501,17 +501,6 @@ fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize,
(*p2->p_emul->e_syscall_intern)(p2);
#endif
/* if we are being traced, give the owner a chance to interfere */
if (p2->p_slflag & PSL_TRACED) {
ksiginfo_t ksi;
KSI_INIT_EMPTY(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_CHLD;
ksi.ksi_lid = l2->l_lid;
kpsignal(p2, &ksi, NULL);
}
/*
* Update stats now that we know the fork was successful.
*/
@ -606,17 +595,18 @@ fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize,
* Let the parent know that we are tracing its child.
*/
if (tracevforkdone) {
ksiginfo_t ksi;
KSI_INIT_EMPTY(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_CHLD;
ksi.ksi_lid = l1->l_lid;
kpsignal(p1, &ksi, NULL);
mutex_enter(p1->p_lock);
p1->p_xsig = SIGTRAP;
p1->p_sigctx.ps_faked = true; // XXX
p1->p_sigctx.ps_info._signo = p1->p_xsig;
p1->p_sigctx.ps_info._code = TRAP_CHLD;
p1->p_vfpid_done = retval[0];
}
mutex_exit(proc_lock);
sigswitch(0, SIGTRAP, false);
// XXX ktrpoint(KTR_PSIG)
mutex_exit(p1->p_lock);
// proc_lock unlocked
} else
mutex_exit(proc_lock);
return 0;
}