Module Name:    src
Committed By:   kamil
Date:           Sat Apr  8 00:25:50 UTC 2017

Modified Files:
        src/sys/arch/amd64/include: ptrace.h
        src/sys/arch/arc/include: ptrace.h
        src/sys/arch/arm/include: ptrace.h
        src/sys/arch/hppa/include: ptrace.h
        src/sys/arch/ia64/include: ptrace.h
        src/sys/arch/m68k/include: ptrace.h
        src/sys/arch/mips/include: ptrace.h
        src/sys/arch/powerpc/include: ptrace.h
        src/sys/arch/sh3/include: ptrace.h
        src/sys/arch/vax/include: ptrace.h
        src/sys/kern: sys_ptrace_common.c
        src/sys/sys: lwp.h
        src/tests/lib/libc/sys: t_ptrace_wait.c

Log Message:
Add new ptrace(2) API: PT_SETSTEP & PT_CLEARSTEP

These operations allow to mark thread as a single-stepping one.

This allows to i.a.:
 - single step and emit a signal (PT_SETSTEP & PT_CONTINUE)
 - single step and trace syscall entry and exit (PT_SETSTEP & PT_SYSCALL)

The former is useful for debuggers like GDB or LLDB. The latter can be used
to singlestep a usermode kernel. These examples don't limit use-cases of
this interface.

Define PT_*STEP only for platforms defining PT_STEP.

Add new ATF tests setstep[1234].

These ptrace(2) operations first appeared in FreeBSD.

Sponsored by <The NetBSD Foundation>


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/amd64/include/ptrace.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arc/include/ptrace.h
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/include/ptrace.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/hppa/include/ptrace.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/ia64/include/ptrace.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/m68k/include/ptrace.h
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/mips/include/ptrace.h
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/powerpc/include/ptrace.h
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/sh3/include/ptrace.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/vax/include/ptrace.h
cvs rdiff -u -r1.20 -r1.21 src/sys/kern/sys_ptrace_common.c
cvs rdiff -u -r1.172 -r1.173 src/sys/sys/lwp.h
cvs rdiff -u -r1.1 -r1.2 src/tests/lib/libc/sys/t_ptrace_wait.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/include/ptrace.h
diff -u src/sys/arch/amd64/include/ptrace.h:1.10 src/sys/arch/amd64/include/ptrace.h:1.11
--- src/sys/arch/amd64/include/ptrace.h:1.10	Thu Feb 23 03:34:22 2017
+++ src/sys/arch/amd64/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.10 2017/02/23 03:34:22 kamil Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.11 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*
  * Copyright (c) 1993 Christopher G. Demetriou
@@ -43,6 +43,8 @@
 #define	PT_SETFPREGS		(PT_FIRSTMACH + 4)
 #define	PT_GETDBREGS		(PT_FIRSTMACH + 5)
 #define	PT_SETDBREGS		(PT_FIRSTMACH + 6)
+#define	PT_SETSTEP		(PT_FIRSTMACH + 7)
+#define	PT_CLEARSTEP		(PT_FIRSTMACH + 8)
 
 #define PT_MACHDEP_STRINGS \
 	"PT_STEP", \
@@ -51,7 +53,9 @@
 	"PT_GETFPREGS", \
 	"PT_SETFPREGS", \
 	"PT_GETDBREGS", \
-	"PT_SETDBREGS",
+	"PT_SETDBREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(r)	(r)->regs[_REG_RIP]

Index: src/sys/arch/arc/include/ptrace.h
diff -u src/sys/arch/arc/include/ptrace.h:1.4 src/sys/arch/arc/include/ptrace.h:1.5
--- src/sys/arch/arc/include/ptrace.h:1.4	Sun Jan 23 21:01:58 2000
+++ src/sys/arch/arc/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,6 +1,6 @@
-/*	$NetBSD: ptrace.h,v 1.4 2000/01/23 21:01:58 soda Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.5 2017/04/08 00:25:49 kamil Exp $	*/
 /*      $OpenBSD: ptrace.h,v 1.1.1.1 1996/06/24 09:07:18 pefo Exp $	*/
 
-#include <mips/ptrace.h>
-
 #define	PT_STEP		(PT_FIRSTMACH + 0)
+
+#include <mips/ptrace.h>

Index: src/sys/arch/arm/include/ptrace.h
diff -u src/sys/arch/arm/include/ptrace.h:1.9 src/sys/arch/arm/include/ptrace.h:1.10
--- src/sys/arch/arm/include/ptrace.h:1.9	Fri Nov 25 02:19:19 2016
+++ src/sys/arch/arm/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.9 2016/11/25 02:19:19 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.10 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*
  * Copyright (c) 1995 Frank Lancaster
@@ -42,15 +42,21 @@
 /* 3 and 4 are for FPE registers */
 #define	PT_GETFPREGS	(PT_FIRSTMACH + 5)
 #define	PT_SETFPREGS	(PT_FIRSTMACH + 6)
+#ifndef _KERNEL
+#define PT_SETSTEP	(PT_FIRSTMACH + 7) /* Not implemented */
+#define PT_CLEARSTEP	(PT_FIRSTMACH + 8) /* Not implemented */
+#endif
 
 #define PT_MACHDEP_STRINGS \
-	"(unused)", \
+	"PT_STEP", \
 	"PT_GETREGS", \
 	"PT_SETREGS", \
 	"old PT_GETFPREGS", \
 	"old PT_SETFPREGS", \
 	"PT_GETFPREGS", \
-	"PT_SETFPREGS",
+	"PT_SETFPREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(_r)		(_r)->r_pc

Index: src/sys/arch/hppa/include/ptrace.h
diff -u src/sys/arch/hppa/include/ptrace.h:1.6 src/sys/arch/hppa/include/ptrace.h:1.7
--- src/sys/arch/hppa/include/ptrace.h:1.6	Fri Nov 25 02:27:43 2016
+++ src/sys/arch/hppa/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.6 2016/11/25 02:27:43 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.7 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*	$OpenBSD: ptrace.h,v 1.2 1998/12/01 03:05:44 mickey Exp $	*/
 
@@ -36,13 +36,17 @@
 #define	PT_SETREGS	(PT_FIRSTMACH + 2)
 #define	PT_GETFPREGS	(PT_FIRSTMACH + 3)
 #define	PT_SETFPREGS	(PT_FIRSTMACH + 4)
+#define	PT_SETSTEP	(PT_FIRSTMACH + 5)
+#define	PT_CLEARSTEP	(PT_FIRSTMACH + 6)
 
 #define PT_MACHDEP_STRINGS \
 	"PT_STEP", \
 	"PT_GETREGS", \
 	"PT_SETREGS", \
 	"PT_GETFPREGS", \
-	"PT_SETFPREGS",
+	"PT_SETFPREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(r)	(r)->r_pcoqh

Index: src/sys/arch/ia64/include/ptrace.h
diff -u src/sys/arch/ia64/include/ptrace.h:1.3 src/sys/arch/ia64/include/ptrace.h:1.4
--- src/sys/arch/ia64/include/ptrace.h:1.3	Tue Sep 15 15:49:02 2015
+++ src/sys/arch/ia64/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.3 2015/09/15 15:49:02 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.4 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*
  * Copyright (c) 1994 Christopher G. Demetriou
@@ -38,13 +38,17 @@
 #define	PT_SETREGS	(PT_FIRSTMACH + 2)
 #define	PT_GETFPREGS	(PT_FIRSTMACH + 3)
 #define	PT_SETFPREGS	(PT_FIRSTMACH + 4)
+#define	PT_SETSTEP	(PT_FIRSTMACH + 5)
+#define	PT_CLEARSTEP	(PT_FIRSTMACH + 6)
 
 #define PT_MACHDEP_STRINGS \
 	"PT_STEP", \
 	"PT_GETREGS", \
 	"PT_SETREGS", \
 	"PT_GETFPREGS", \
-	"PT_SETFPREGS",
+	"PT_SETFPREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(r)	(r)->r_special.iip

Index: src/sys/arch/m68k/include/ptrace.h
diff -u src/sys/arch/m68k/include/ptrace.h:1.10 src/sys/arch/m68k/include/ptrace.h:1.11
--- src/sys/arch/m68k/include/ptrace.h:1.10	Fri Sep 25 16:05:17 2015
+++ src/sys/arch/m68k/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.10 2015/09/25 16:05:17 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.11 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*
  * Copyright (c) 1993 Christopher G. Demetriou
@@ -40,13 +40,17 @@
 #define	PT_SETREGS	(PT_FIRSTMACH + 2)
 #define	PT_GETFPREGS	(PT_FIRSTMACH + 3)
 #define	PT_SETFPREGS	(PT_FIRSTMACH + 4)
+#define	PT_SETSTEP	(PT_FIRSTMACH + 5)
+#define	PT_CLEARSTEP	(PT_FIRSTMACH + 6)
 
 #define PT_MACHDEP_STRINGS \
 	"PT_STEP", \
 	"PT_GETREGS", \
 	"PT_SETREGS", \
 	"PT_GETFPREGS", \
-	"PT_SETFPREGS",
+	"PT_SETFPREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(r)	(r)->r_pc

Index: src/sys/arch/mips/include/ptrace.h
diff -u src/sys/arch/mips/include/ptrace.h:1.14 src/sys/arch/mips/include/ptrace.h:1.15
--- src/sys/arch/mips/include/ptrace.h:1.14	Fri Sep 25 16:05:17 2015
+++ src/sys/arch/mips/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.14 2015/09/25 16:05:17 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.15 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -39,19 +39,26 @@
 #ifndef _MIPS_PTRACE_H_
 #define _MIPS_PTRACE_H_
 
-/*#define	PT_STEP		(PT_FIRSTMACH + 0)*/
+/* MIPS PT_STEP PT_FIRSTMACH+0 might be defined by a port specific header */
 #define	PT_GETREGS	(PT_FIRSTMACH + 1)
 #define	PT_SETREGS	(PT_FIRSTMACH + 2)
 
 #define	PT_GETFPREGS	(PT_FIRSTMACH + 3)
 #define	PT_SETFPREGS	(PT_FIRSTMACH + 4)
 
+#ifdef PT_STEP
+#define	PT_SETSTEP	(PT_FIRSTMACH + 5)
+#define	PT_CLEARSTEP	(PT_FIRSTMACH + 6)
+#endif
+
 #define PT_MACHDEP_STRINGS \
-	"(unused)", \
+	"PT_STEP", \
 	"PT_GETREGS", \
 	"PT_SETREGS", \
 	"PT_GETFPREGS", \
-	"PT_SETFPREGS",
+	"PT_SETFPREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(r)	(r)->r_regs[35]

Index: src/sys/arch/powerpc/include/ptrace.h
diff -u src/sys/arch/powerpc/include/ptrace.h:1.12 src/sys/arch/powerpc/include/ptrace.h:1.13
--- src/sys/arch/powerpc/include/ptrace.h:1.12	Tue Sep 15 15:49:03 2015
+++ src/sys/arch/powerpc/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.12 2015/09/15 15:49:03 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.13 2017/04/08 00:25:49 kamil Exp $	*/
 
 #ifndef _POWERPC_PTRACE_H
 #define	_POWERPC_PTRACE_H
@@ -10,12 +10,15 @@
 #define	PT_SETFPREGS	(PT_FIRSTMACH + 4)
 #define	PT_GETVECREGS	(PT_FIRSTMACH + 5)
 #define	PT_SETVECREGS	(PT_FIRSTMACH + 6)
+#define	PT_SETSTEP	(PT_FIRSTMACH + 7)
+#define	PT_CLEARSTEP	(PT_FIRSTMACH + 8)
 
 #define	PT_MACHDEP_STRINGS				\
 	"PT_STEP",					\
 	"PT_GETREGS",		"PT_SETREGS",		\
 	"PT_GETFPREGS",		"PT_SETFPREGS",		\
-	"PT_GETVECREGS",	"PT_SETVECREGS",
+	"PT_GETVECREGS",	"PT_SETVECREGS",	\
+	"PT_SETSTEP",		"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(r)	(r)->pc

Index: src/sys/arch/sh3/include/ptrace.h
diff -u src/sys/arch/sh3/include/ptrace.h:1.12 src/sys/arch/sh3/include/ptrace.h:1.13
--- src/sys/arch/sh3/include/ptrace.h:1.12	Fri Sep 25 16:05:17 2015
+++ src/sys/arch/sh3/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.12 2015/09/25 16:05:17 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.13 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*
  * Copyright (c) 1993 Christopher G. Demetriou
@@ -51,12 +51,19 @@
 #define	PT_SETFPREGS	(PT_FIRSTMACH + 6)
 #endif
 
+#define	PT_SETSTEP	(PT_FIRSTMACH + 7)
+#define	PT_CLEARSTEP	(PT_FIRSTMACH + 8)
+
 #define PT_MACHDEP_STRINGS \
 	"PT_STEP", \
 	"PT___GETREGS40", \
 	"PT___SETREGS40", \
 	"PT_GETREGS", \
-	"PT_SETREGS",
+	"PT_SETREGS", \
+	"PT_GETFPREGS", \
+	"PT_SETFPREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP"
 
 #include <machine/reg.h>
 #define PTRACE_REG_PC(r)	r->r_spc

Index: src/sys/arch/vax/include/ptrace.h
diff -u src/sys/arch/vax/include/ptrace.h:1.6 src/sys/arch/vax/include/ptrace.h:1.7
--- src/sys/arch/vax/include/ptrace.h:1.6	Fri Sep 25 16:05:18 2015
+++ src/sys/arch/vax/include/ptrace.h	Sat Apr  8 00:25:49 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.6 2015/09/25 16:05:18 christos Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.7 2017/04/08 00:25:49 kamil Exp $	*/
 
 /*
  * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
@@ -36,11 +36,15 @@
 #define PT_STEP         (PT_FIRSTMACH + 0)
 #define PT_GETREGS      (PT_FIRSTMACH + 1)
 #define PT_SETREGS      (PT_FIRSTMACH + 2)
+#define PT_SETSTEP      (PT_FIRSTMACH + 3)
+#define PT_CLEARSTEP    (PT_FIRSTMACH + 4)
 
 #define PT_MACHDEP_STRINGS \
 	"PT_STEP", \
 	"PT_GETREGS", \
-	"PT_SETREGS",
+	"PT_SETREGS", \
+	"PT_SETSTEP", \
+	"PT_CLEARSTEP",
 
 #include <machine/reg.h>
 

Index: src/sys/kern/sys_ptrace_common.c
diff -u src/sys/kern/sys_ptrace_common.c:1.20 src/sys/kern/sys_ptrace_common.c:1.21
--- src/sys/kern/sys_ptrace_common.c:1.20	Wed Mar 29 22:48:03 2017
+++ src/sys/kern/sys_ptrace_common.c	Sat Apr  8 00:25:50 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_ptrace_common.c,v 1.20 2017/03/29 22:48:03 kamil Exp $	*/
+/*	$NetBSD: sys_ptrace_common.c,v 1.21 2017/04/08 00:25:50 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.20 2017/03/29 22:48:03 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.21 2017/04/08 00:25:50 kamil Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ptrace.h"
@@ -229,6 +229,8 @@ ptrace_listener_cb(kauth_cred_t cred, ka
 
 #ifdef PT_STEP
 	case PT_STEP:
+	case PT_SETSTEP:
+	case PT_CLEARSTEP:
 #endif
 	case PT_CONTINUE:
 	case PT_KILL:
@@ -452,6 +454,8 @@ do_ptrace(struct ptrace_methods *ptm, st
 	case  PT_DUMPCORE:
 #ifdef PT_STEP
 	case  PT_STEP:
+	case  PT_SETSTEP:
+	case  PT_CLEARSTEP:
 #endif
 	case  PT_SET_EVENT_MASK:
 	case  PT_GET_EVENT_MASK:
@@ -532,6 +536,8 @@ do_ptrace(struct ptrace_methods *ptm, st
 	switch (req) {
 #ifdef PT_STEP
 	case PT_STEP:
+	case PT_SETSTEP:
+	case PT_CLEARSTEP:
 #endif
 	case PT_CONTINUE:
 	case PT_DETACH:
@@ -797,13 +803,18 @@ do_ptrace(struct ptrace_methods *ptm, st
 		 * the requested thread, and clear it for other threads.
 		 */
 		LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
-			if (lt != lt2) {
+			if (ISSET(lt2->l_pflag, LP_SINGLESTEP)) {
+				lwp_lock(lt2);
+				process_sstep(lt2, 1);
+				lwp_unlock(lt2);
+			} else if (lt != lt2) {
 				lwp_lock(lt2);
 				process_sstep(lt2, 0);
 				lwp_unlock(lt2);
 			}
 		}
-		error = process_sstep(lt, req == PT_STEP);
+		error = process_sstep(lt,
+		    ISSET(lt->l_pflag, LP_SINGLESTEP) || req == PT_STEP);
 		if (error)
 			break;
 #endif
@@ -818,6 +829,12 @@ do_ptrace(struct ptrace_methods *ptm, st
 
 			/* not being traced any more */
 			t->p_opptr = NULL;
+
+			/* clear single step */
+			LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
+				CLR(lt2->l_pflag, LP_SINGLESTEP);
+			}
+			CLR(lt->l_pflag, LP_SINGLESTEP);
 		}
 	sendsig:
 		t->p_fpid = 0;
@@ -862,6 +879,36 @@ do_ptrace(struct ptrace_methods *ptm, st
 		SET(t->p_slflag, PSL_SYSCALLEMU);
 		break;
 
+#ifdef PT_STEP
+	case  PT_SETSTEP:
+		write = 1;
+
+	case  PT_CLEARSTEP:
+		/* write = 0 done above. */
+
+		tmp = data;
+		if (tmp != 0 && t->p_nlwps > 1) {
+			lwp_delref(lt);
+			mutex_enter(t->p_lock);
+			lt = lwp_find(t, tmp);
+			if (lt == NULL) {
+				mutex_exit(t->p_lock);
+				error = ESRCH;
+				break;
+			}
+			lwp_addref(lt);
+			mutex_exit(t->p_lock);
+		}
+
+		if (ISSET(lt->l_flag, LW_SYSTEM))
+			error = EINVAL;
+		else if (write)
+			SET(lt->l_pflag, LP_SINGLESTEP);
+		else
+			CLR(lt->l_pflag, LP_SINGLESTEP);
+		break;
+#endif
+
 	case  PT_KILL:
 		/* just send the process a KILL signal. */
 		signo = SIGKILL;

Index: src/sys/sys/lwp.h
diff -u src/sys/sys/lwp.h:1.172 src/sys/sys/lwp.h:1.173
--- src/sys/sys/lwp.h:1.172	Sun Jul  3 14:24:59 2016
+++ src/sys/sys/lwp.h	Sat Apr  8 00:25:50 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: lwp.h,v 1.172 2016/07/03 14:24:59 christos Exp $	*/
+/*	$NetBSD: lwp.h,v 1.173 2017/04/08 00:25:50 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010
@@ -255,6 +255,7 @@ extern int		maxlwp __read_mostly;	/* max
 #define	LP_SYSCTLWRITE	0x00000080 /* sysctl write lock held */
 #define	LP_MUSTJOIN	0x00000100 /* Must join kthread on exit */
 #define	LP_VFORKWAIT	0x00000200 /* Waiting at vfork() for a child */
+#define	LP_SINGLESTEP	0x00000400 /* Single step thread in ptrace(2) */
 #define	LP_TIMEINTR	0x00010000 /* Time this soft interrupt */
 #define	LP_RUNNING	0x20000000 /* Active on a CPU */
 #define	LP_BOUND	0x80000000 /* Bound to a CPU */

Index: src/tests/lib/libc/sys/t_ptrace_wait.c
diff -u src/tests/lib/libc/sys/t_ptrace_wait.c:1.1 src/tests/lib/libc/sys/t_ptrace_wait.c:1.2
--- src/tests/lib/libc/sys/t_ptrace_wait.c:1.1	Sun Apr  2 21:44:00 2017
+++ src/tests/lib/libc/sys/t_ptrace_wait.c	Sat Apr  8 00:25:50 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ptrace_wait.c,v 1.1 2017/04/02 21:44:00 kamil Exp $	*/
+/*	$NetBSD: t_ptrace_wait.c,v 1.2 2017/04/08 00:25:50 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ptrace_wait.c,v 1.1 2017/04/02 21:44:00 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace_wait.c,v 1.2 2017/04/08 00:25:50 kamil Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -4396,7 +4396,7 @@ ATF_TC_BODY(fpregs2, tc)
 
 #if defined(PT_STEP)
 static void
-ptrace_step(int N)
+ptrace_step(int N, int setstep)
 {
 	const int exitval = 5;
 	const int sigval = SIGSTOP;
@@ -4435,15 +4435,32 @@ ptrace_step(int N)
 	validate_status_stopped(status, sigval);
 
 	while (N --> 0) {
-		printf("Before resuming the child process where it left off "
-		    "and without signal to be sent (use PT_STEP)\n");
-		ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
+		if (setstep) {
+			printf("Before resuming the child process where it "
+			    "left off and without signal to be sent (use "
+			    "PT_STEP)\n");
+			ATF_REQUIRE(ptrace(PT_SETSTEP, child, (void *)1, 0)
+			    != -1);
+			ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
+			    != -1);
+		} else {
+			printf("Before resuming the child process where it "
+			    "left off and without signal to be sent (use "
+			    "PT_STEP)\n");
+			ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
+			    != -1);
+		}
 
 		printf("Before calling %s() for the child\n", TWAIT_FNAME);
 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
 		    child);
 
 		validate_status_stopped(status, SIGTRAP);
+
+		if (setstep) {
+			ATF_REQUIRE(ptrace(PT_CLEARSTEP, child, (void *)1, 0)
+			    != -1);
+		}
 	}
 
 	printf("Before resuming the child process where it left off and "
@@ -4470,7 +4487,7 @@ ATF_TC_HEAD(step1, tc)
 
 ATF_TC_BODY(step1, tc)
 {
-	ptrace_step(1);
+	ptrace_step(1, 0);
 }
 #endif
 
@@ -4484,7 +4501,7 @@ ATF_TC_HEAD(step2, tc)
 
 ATF_TC_BODY(step2, tc)
 {
-	ptrace_step(2);
+	ptrace_step(2, 0);
 }
 #endif
 
@@ -4498,7 +4515,7 @@ ATF_TC_HEAD(step3, tc)
 
 ATF_TC_BODY(step3, tc)
 {
-	ptrace_step(3);
+	ptrace_step(3, 0);
 }
 #endif
 
@@ -4512,7 +4529,63 @@ ATF_TC_HEAD(step4, tc)
 
 ATF_TC_BODY(step4, tc)
 {
-	ptrace_step(3);
+	ptrace_step(4, 0);
+}
+#endif
+
+#if defined(PT_STEP)
+ATF_TC(setstep1);
+ATF_TC_HEAD(setstep1, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify single PT_SETSTEP call");
+}
+
+ATF_TC_BODY(setstep1, tc)
+{
+	ptrace_step(1, 1);
+}
+#endif
+
+#if defined(PT_STEP)
+ATF_TC(setstep2);
+ATF_TC_HEAD(setstep2, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify PT_SETSTEP called twice");
+}
+
+ATF_TC_BODY(setstep2, tc)
+{
+	ptrace_step(2, 1);
+}
+#endif
+
+#if defined(PT_STEP)
+ATF_TC(setstep3);
+ATF_TC_HEAD(setstep3, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify PT_SETSTEP called three times");
+}
+
+ATF_TC_BODY(setstep3, tc)
+{
+	ptrace_step(3, 1);
+}
+#endif
+
+#if defined(PT_STEP)
+ATF_TC(setstep4);
+ATF_TC_HEAD(setstep4, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify PT_SETSTEP called four times");
+}
+
+ATF_TC_BODY(setstep4, tc)
+{
+	ptrace_step(4, 1);
 }
 #endif
 
@@ -7535,6 +7608,11 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC_PT_STEP(tp, step3);
 	ATF_TP_ADD_TC_PT_STEP(tp, step4);
 
+	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
+	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
+	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
+	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
+
 	ATF_TP_ADD_TC(tp, kill1);
 	ATF_TP_ADD_TC(tp, kill2);
 

Reply via email to