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);