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