t_ptrace_wait.c revision 1.48
11.48Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.48 2018/05/20 03:51:31 kamil Exp $	*/
21.1Skamil
31.1Skamil/*-
41.1Skamil * Copyright (c) 2016 The NetBSD Foundation, Inc.
51.1Skamil * All rights reserved.
61.1Skamil *
71.1Skamil * Redistribution and use in source and binary forms, with or without
81.1Skamil * modification, are permitted provided that the following conditions
91.1Skamil * are met:
101.1Skamil * 1. Redistributions of source code must retain the above copyright
111.1Skamil *    notice, this list of conditions and the following disclaimer.
121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright
131.1Skamil *    notice, this list of conditions and the following disclaimer in the
141.1Skamil *    documentation and/or other materials provided with the distribution.
151.1Skamil *
161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Skamil * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Skamil * POSSIBILITY OF SUCH DAMAGE.
271.1Skamil */
281.1Skamil
291.1Skamil#include <sys/cdefs.h>
301.48Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.48 2018/05/20 03:51:31 kamil Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/types.h>
341.39Skamil#include <sys/mman.h>
351.1Skamil#include <sys/ptrace.h>
361.1Skamil#include <sys/resource.h>
371.1Skamil#include <sys/stat.h>
381.1Skamil#include <sys/syscall.h>
391.1Skamil#include <sys/sysctl.h>
401.1Skamil#include <sys/wait.h>
411.1Skamil#include <machine/reg.h>
421.1Skamil#include <elf.h>
431.1Skamil#include <err.h>
441.1Skamil#include <errno.h>
451.1Skamil#include <lwp.h>
461.1Skamil#include <sched.h>
471.1Skamil#include <signal.h>
481.1Skamil#include <stdint.h>
491.1Skamil#include <stdio.h>
501.1Skamil#include <stdlib.h>
511.1Skamil#include <strings.h>
521.26Skamil#include <time.h>
531.1Skamil#include <unistd.h>
541.1Skamil
551.1Skamil#include <atf-c.h>
561.1Skamil
571.1Skamil#include "h_macros.h"
581.1Skamil
591.1Skamil#include "t_ptrace_wait.h"
601.1Skamil#include "msg.h"
611.1Skamil
621.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
631.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
641.1Skamil
651.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
661.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
671.1Skamil
681.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
691.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
701.1Skamil
711.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
721.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
731.13Schristos
741.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
751.13Schristos    strerror(errno))
761.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
771.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
781.13Schristos
791.13Schristosstatic int debug = 0;
801.13Schristos
811.13Schristos#define DPRINTF(a, ...)	do  \
821.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
831.13Schristos    while (/*CONSTCOND*/0)
841.1Skamil
851.34Skamil/// ----------------------------------------------------------------------------
861.34Skamil
871.33Skamilstatic void
881.33Skamiltraceme_raise(int sigval)
891.1Skamil{
901.1Skamil	const int exitval = 5;
911.1Skamil	pid_t child, wpid;
921.1Skamil#if defined(TWAIT_HAVE_STATUS)
931.1Skamil	int status;
941.1Skamil#endif
951.1Skamil
961.45Skamil	struct ptrace_siginfo info;
971.45Skamil	memset(&info, 0, sizeof(info));
981.45Skamil
991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1011.1Skamil	if (child == 0) {
1021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1041.1Skamil
1051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1071.1Skamil
1081.36Skamil		switch (sigval) {
1091.36Skamil		case SIGKILL:
1101.36Skamil			/* NOTREACHED */
1111.36Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
1121.36Skamil		default:
1131.36Skamil			DPRINTF("Before exiting of the child process\n");
1141.36Skamil			_exit(exitval);
1151.36Skamil		}
1161.1Skamil	}
1171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1181.1Skamil
1191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1211.1Skamil
1221.36Skamil	switch (sigval) {
1231.36Skamil	case SIGKILL:
1241.36Skamil		validate_status_signaled(status, sigval, 0);
1251.36Skamil		break;
1261.36Skamil	default:
1271.36Skamil		validate_status_stopped(status, sigval);
1281.1Skamil
1291.45Skamil		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1301.45Skamil		        "child\n");
1311.45Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1321.45Skamil		                       sizeof(info)) != -1);
1331.45Skamil
1341.45Skamil		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1351.45Skamil		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1361.45Skamil		        "si_errno=%#x\n",
1371.45Skamil		        info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1381.45Skamil		        info.psi_siginfo.si_errno);
1391.45Skamil
1401.45Skamil		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1411.45Skamil		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1421.45Skamil
1431.36Skamil		DPRINTF("Before resuming the child process where it left off "
1441.36Skamil		    "and without signal to be sent\n");
1451.36Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1461.1Skamil
1471.36Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1481.36Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1491.36Skamil		                      child);
1501.36Skamil		break;
1511.36Skamil	}
1521.1Skamil
1531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1551.1Skamil}
1561.1Skamil
1571.33Skamil#define TRACEME_RAISE(test, sig)						\
1581.33SkamilATF_TC(test);									\
1591.33SkamilATF_TC_HEAD(test, tc)								\
1601.33Skamil{										\
1611.33Skamil	atf_tc_set_md_var(tc, "descr",						\
1621.33Skamil	    "Verify " #sig " followed by _exit(2) in a child");			\
1631.33Skamil}										\
1641.33Skamil										\
1651.33SkamilATF_TC_BODY(test, tc)								\
1661.33Skamil{										\
1671.33Skamil										\
1681.33Skamil	traceme_raise(sig);							\
1691.33Skamil}
1701.33Skamil
1711.36SkamilTRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
1721.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
1731.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
1741.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
1751.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
1761.33Skamil
1771.34Skamil/// ----------------------------------------------------------------------------
1781.1Skamil
1791.1Skamilstatic void
1801.34Skamiltraceme_sighandler_catch(int sigsent, void (*sah)(int arg), int *traceme_caught)
1811.1Skamil{
1821.1Skamil	const int exitval = 5;
1831.34Skamil	const int sigval = SIGSTOP;
1841.1Skamil	pid_t child, wpid;
1851.1Skamil	struct sigaction sa;
1861.1Skamil#if defined(TWAIT_HAVE_STATUS)
1871.1Skamil	int status;
1881.1Skamil#endif
1891.1Skamil
1901.45Skamil	struct ptrace_siginfo info;
1911.45Skamil	memset(&info, 0, sizeof(info));
1921.45Skamil
1931.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1941.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1951.1Skamil	if (child == 0) {
1961.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1971.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1981.1Skamil
1991.34Skamil		sa.sa_handler = sah;
2001.1Skamil		sa.sa_flags = SA_SIGINFO;
2011.1Skamil		sigemptyset(&sa.sa_mask);
2021.1Skamil
2031.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
2041.1Skamil
2051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2071.1Skamil
2081.34Skamil		FORKEE_ASSERT_EQ(*traceme_caught, 1);
2091.1Skamil
2101.13Schristos		DPRINTF("Before exiting of the child process\n");
2111.1Skamil		_exit(exitval);
2121.1Skamil	}
2131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2141.1Skamil
2151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2171.1Skamil
2181.1Skamil	validate_status_stopped(status, sigval);
2191.1Skamil
2201.45Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
2211.45Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
2221.45Skamil	                != -1);
2231.45Skamil
2241.45Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2251.45Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
2261.45Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2271.45Skamil	    info.psi_siginfo.si_errno);
2281.45Skamil
2291.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
2301.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
2311.45Skamil
2321.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2331.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2351.1Skamil
2361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2381.1Skamil
2391.1Skamil	validate_status_exited(status, exitval);
2401.1Skamil
2411.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2431.1Skamil}
2441.1Skamil
2451.34Skamil#define TRACEME_SIGHANDLER_CATCH(test, sig)					\
2461.34SkamilATF_TC(test);									\
2471.34SkamilATF_TC_HEAD(test, tc)								\
2481.34Skamil{										\
2491.34Skamil	atf_tc_set_md_var(tc, "descr",						\
2501.34Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
2511.34Skamil	    "handled correctly and caught by a signal handler");		\
2521.34Skamil}										\
2531.34Skamil										\
2541.34Skamilstatic int test##_caught = 0;							\
2551.34Skamil										\
2561.34Skamilstatic void									\
2571.34Skamiltest##_sighandler(int arg)							\
2581.34Skamil{										\
2591.34Skamil	FORKEE_ASSERT_EQ(arg, sig);						\
2601.34Skamil										\
2611.34Skamil	++ test##_caught;							\
2621.34Skamil}										\
2631.34Skamil										\
2641.34SkamilATF_TC_BODY(test, tc)								\
2651.34Skamil{										\
2661.34Skamil										\
2671.34Skamil	traceme_sighandler_catch(sig, test##_sighandler, & test##_caught);	\
2681.34Skamil}
2691.34Skamil
2701.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered.
2711.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch1, SIGABRT) /* abort trap */
2721.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch2, SIGHUP)  /* hangup */
2731.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch3, SIGCONT) /* continued? */
2741.34Skamil
2751.34Skamil/// ----------------------------------------------------------------------------
2761.34Skamil
2771.35Skamilstatic void
2781.35Skamiltraceme_signal_nohandler(int sigsent)
2791.1Skamil{
2801.35Skamil	const int sigval = SIGSTOP;
2811.35Skamil	int exitval = 0;
2821.1Skamil	pid_t child, wpid;
2831.1Skamil#if defined(TWAIT_HAVE_STATUS)
2841.1Skamil	int status;
2851.35Skamil	int expect_core = (sigsent == SIGABRT) ? 1 : 0;
2861.1Skamil#endif
2871.1Skamil
2881.45Skamil	struct ptrace_siginfo info;
2891.45Skamil	memset(&info, 0, sizeof(info));
2901.45Skamil
2911.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2921.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2931.1Skamil	if (child == 0) {
2941.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2951.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2961.1Skamil
2971.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2981.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2991.1Skamil
3001.35Skamil		switch (sigsent) {
3011.35Skamil		case SIGCONT:
3021.48Skamil		case SIGSTOP:
3031.35Skamil			_exit(exitval);
3041.35Skamil		default:
3051.35Skamil			/* NOTREACHED */
3061.35Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
3071.35Skamil		}
3081.1Skamil	}
3091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3101.1Skamil
3111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3131.1Skamil
3141.1Skamil	validate_status_stopped(status, sigval);
3151.1Skamil
3161.45Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3171.45Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
3181.45Skamil	                != -1);
3191.45Skamil
3201.45Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3211.45Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3221.45Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3231.45Skamil	    info.psi_siginfo.si_errno);
3241.45Skamil
3251.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3261.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3271.45Skamil
3281.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
3291.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
3301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
3311.1Skamil
3321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3341.1Skamil
3351.35Skamil	switch (sigsent) {
3361.48Skamil	case SIGSTOP:
3371.48Skamil		validate_status_stopped(status, sigsent);
3381.48Skamil		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
3391.48Skamil		        "child\n");
3401.48Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
3411.48Skamil		                       sizeof(info)) != -1);
3421.48Skamil
3431.48Skamil		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3441.48Skamil		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3451.48Skamil		        "si_errno=%#x\n",
3461.48Skamil			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3471.48Skamil		        info.psi_siginfo.si_errno);
3481.48Skamil
3491.48Skamil		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3501.48Skamil		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3511.48Skamil
3521.48Skamil		DPRINTF("Before resuming the child process where it left off "
3531.48Skamil		        "and with signal %s to be sent\n", strsignal(sigsent));
3541.48Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3551.48Skamil
3561.48Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3571.48Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3581.48Skamil		                      child);
3591.48Skamil		/* FALLTHROUGH */
3601.35Skamil	case SIGCONT:
3611.35Skamil		validate_status_exited(status, exitval);
3621.35Skamil		break;
3631.35Skamil	default:
3641.35Skamil		validate_status_signaled(status, sigsent, expect_core);
3651.35Skamil		break;
3661.35Skamil	}
3671.1Skamil
3681.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
3691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3701.1Skamil}
3711.1Skamil
3721.35Skamil#define TRACEME_SIGNAL_NOHANDLER(test, sig)					\
3731.35SkamilATF_TC(test);									\
3741.35SkamilATF_TC_HEAD(test, tc)								\
3751.35Skamil{										\
3761.35Skamil	atf_tc_set_md_var(tc, "descr",						\
3771.35Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
3781.35Skamil	    "handled correctly in a child without a signal handler");		\
3791.35Skamil}										\
3801.35Skamil										\
3811.35SkamilATF_TC_BODY(test, tc)								\
3821.35Skamil{										\
3831.35Skamil										\
3841.35Skamil	traceme_signal_nohandler(sig);						\
3851.35Skamil}
3861.35Skamil
3871.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */
3881.48SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */
3891.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */
3901.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP)  /* hangup */
3911.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */
3921.35Skamil
3931.35Skamil/// ----------------------------------------------------------------------------
3941.35Skamil
3951.37SkamilATF_TC(traceme_pid1_parent);
3961.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc)
3971.37Skamil{
3981.37Skamil	atf_tc_set_md_var(tc, "descr",
3991.37Skamil	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
4001.37Skamil}
4011.37Skamil
4021.37SkamilATF_TC_BODY(traceme_pid1_parent, tc)
4031.37Skamil{
4041.37Skamil	struct msg_fds parent_child;
4051.37Skamil	int exitval_child1 = 1, exitval_child2 = 2;
4061.37Skamil	pid_t child1, child2, wpid;
4071.37Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4081.37Skamil#if defined(TWAIT_HAVE_STATUS)
4091.37Skamil	int status;
4101.37Skamil#endif
4111.37Skamil
4121.37Skamil	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
4131.37Skamil
4141.37Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
4151.37Skamil	SYSCALL_REQUIRE((child1 = fork()) != -1);
4161.37Skamil	if (child1 == 0) {
4171.37Skamil		DPRINTF("Before forking process PID=%d\n", getpid());
4181.37Skamil		SYSCALL_REQUIRE((child2 = fork()) != -1);
4191.37Skamil		if (child2 != 0) {
4201.37Skamil			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
4211.37Skamil			        getpid(), child2);
4221.37Skamil			_exit(exitval_child1);
4231.37Skamil		}
4241.37Skamil		CHILD_FROM_PARENT("exit child1", parent_child, msg);
4251.37Skamil
4261.37Skamil		DPRINTF("Assert that our parent is PID1 (initproc)\n");
4271.37Skamil		FORKEE_ASSERT_EQ(getppid(), 1);
4281.37Skamil
4291.37Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4301.37Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
4311.37Skamil		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
4321.37Skamil
4331.37Skamil		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
4341.37Skamil
4351.37Skamil		_exit(exitval_child2);
4361.37Skamil	}
4371.37Skamil	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
4381.37Skamil
4391.37Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4401.37Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child1, &status, WEXITED),
4411.37Skamil	                      child1);
4421.37Skamil
4431.37Skamil	validate_status_exited(status, exitval_child1);
4441.37Skamil
4451.37Skamil	DPRINTF("Notify that child1 is dead\n");
4461.37Skamil	PARENT_TO_CHILD("exit child1", parent_child, msg);
4471.37Skamil
4481.37Skamil	DPRINTF("Wait for exiting of child2\n");
4491.37Skamil	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
4501.37Skamil}
4511.37Skamil
4521.37Skamil/// ----------------------------------------------------------------------------
4531.37Skamil
4541.40Skamilstatic void
4551.40Skamiltraceme_vfork_raise(int sigval)
4561.40Skamil{
4571.46Skamil	const int exitval = 5, exitval_watcher = 10;
4581.46Skamil	pid_t child, parent, watcher, wpid;
4591.46Skamil	int rv;
4601.40Skamil#if defined(TWAIT_HAVE_STATUS)
4611.40Skamil	int status;
4621.40Skamil	int expect_core = (sigval == SIGABRT) ? 1 : 0;
4631.40Skamil#endif
4641.40Skamil
4651.46Skamil	/*
4661.46Skamil	 * Spawn a dedicated thread to watch for a stopped child and emit
4671.46Skamil	 * the SIGKILL signal to it.
4681.46Skamil	 *
4691.46Skamil	 * vfork(2) might clobber watcher, this means that it's safer and
4701.46Skamil	 * simpler to reparent this process to initproc and forget about it.
4711.46Skamil	 */
4721.46Skamil	if (sigval == SIGSTOP) {
4731.46Skamil		parent = getpid();
4741.46Skamil
4751.46Skamil		watcher = fork();
4761.46Skamil		ATF_REQUIRE(watcher != 1);
4771.46Skamil		if (watcher == 0) {
4781.46Skamil			/* Double fork(2) trick to reparent to initproc */
4791.46Skamil			watcher = fork();
4801.46Skamil			FORKEE_ASSERT_NEQ(watcher, -1);
4811.46Skamil			if (watcher != 0)
4821.46Skamil				_exit(exitval_watcher);
4831.46Skamil
4841.46Skamil			child = await_stopped_child(parent);
4851.46Skamil
4861.46Skamil			errno = 0;
4871.46Skamil			rv = kill(child, SIGKILL);
4881.46Skamil			FORKEE_ASSERT_EQ(rv, 0);
4891.46Skamil			FORKEE_ASSERT_EQ(errno, 0);
4901.46Skamil
4911.46Skamil			/* This exit value will be collected by initproc */
4921.46Skamil			_exit(0);
4931.46Skamil		}
4941.46Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4951.46Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
4961.46Skamil		                      watcher);
4971.46Skamil
4981.46Skamil		validate_status_exited(status, exitval_watcher);
4991.46Skamil
5001.46Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5011.46Skamil		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(watcher,
5021.46Skamil		                                                   &status, 0));
5031.46Skamil	}
5041.46Skamil
5051.40Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
5061.40Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
5071.40Skamil	if (child == 0) {
5081.40Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5091.40Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5101.40Skamil
5111.40Skamil		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5121.40Skamil		FORKEE_ASSERT(raise(sigval) == 0);
5131.40Skamil
5141.40Skamil		switch (sigval) {
5151.46Skamil		case SIGSTOP:
5161.40Skamil		case SIGKILL:
5171.40Skamil		case SIGABRT:
5181.40Skamil		case SIGHUP:
5191.40Skamil			/* NOTREACHED */
5201.40Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
5211.40Skamil		default:
5221.40Skamil			DPRINTF("Before exiting of the child process\n");
5231.40Skamil			_exit(exitval);
5241.40Skamil		}
5251.40Skamil	}
5261.40Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5271.40Skamil
5281.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5291.40Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5301.40Skamil
5311.40Skamil	switch (sigval) {
5321.40Skamil	case SIGKILL:
5331.40Skamil	case SIGABRT:
5341.40Skamil	case SIGHUP:
5351.40Skamil		validate_status_signaled(status, sigval, expect_core);
5361.40Skamil		break;
5371.40Skamil	case SIGSTOP:
5381.46Skamil		validate_status_signaled(status, SIGKILL, 0);
5391.46Skamil		break;
5401.40Skamil	case SIGCONT:
5411.47Skamil	case SIGTSTP:
5421.47Skamil	case SIGTTIN:
5431.47Skamil	case SIGTTOU:
5441.40Skamil		validate_status_exited(status, exitval);
5451.40Skamil		break;
5461.40Skamil	default:
5471.40Skamil		/* NOTREACHED */
5481.40Skamil		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
5491.40Skamil		break;
5501.40Skamil	}
5511.40Skamil
5521.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5531.40Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5541.40Skamil}
5551.40Skamil
5561.40Skamil#define TRACEME_VFORK_RAISE(test, sig)						\
5571.40SkamilATF_TC(test);									\
5581.40SkamilATF_TC_HEAD(test, tc)								\
5591.40Skamil{										\
5601.40Skamil	atf_tc_set_md_var(tc, "descr",						\
5611.42Skamil	    "Verify PT_TRACE_ME followed by raise of " #sig " in a vfork(2)ed "	\
5621.42Skamil	    "child");								\
5631.40Skamil}										\
5641.40Skamil										\
5651.40SkamilATF_TC_BODY(test, tc)								\
5661.40Skamil{										\
5671.40Skamil										\
5681.40Skamil	traceme_vfork_raise(sig);						\
5691.40Skamil}
5701.40Skamil
5711.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
5721.46SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
5731.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
5741.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
5751.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
5761.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
5771.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
5781.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
5791.40Skamil
5801.40Skamil/// ----------------------------------------------------------------------------
5811.40Skamil
5821.41SkamilATF_TC(traceme_vfork_breakpoint);
5831.41SkamilATF_TC_HEAD(traceme_vfork_breakpoint, tc)
5841.41Skamil{
5851.41Skamil	atf_tc_set_md_var(tc, "descr",
5861.44Skamil	    "Verify PT_TRACE_ME followed by a software breakpoint in a "
5871.44Skamil	    "vfork(2)ed child");
5881.41Skamil}
5891.41Skamil
5901.41SkamilATF_TC_BODY(traceme_vfork_breakpoint, tc)
5911.41Skamil{
5921.41Skamil	pid_t child, wpid;
5931.41Skamil#if defined(TWAIT_HAVE_STATUS)
5941.41Skamil	int status;
5951.41Skamil#endif
5961.41Skamil
5971.41Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
5981.41Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
5991.41Skamil	if (child == 0) {
6001.41Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6011.41Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6021.41Skamil
6031.41Skamil		DPRINTF("Before executing a software breakpoint\n");
6041.41Skamil#ifdef PTRACE_BREAKPOINT_ASM
6051.41Skamil		PTRACE_BREAKPOINT_ASM;
6061.41Skamil#else
6071.41Skamil		/* port me */
6081.41Skamil#endif
6091.41Skamil
6101.41Skamil		/* NOTREACHED */
6111.41Skamil		FORKEE_ASSERTX(0 && "This shall not be reached");
6121.41Skamil	}
6131.41Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6141.41Skamil
6151.41Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6161.41Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6171.41Skamil
6181.41Skamil	validate_status_signaled(status, SIGTRAP, 1);
6191.41Skamil
6201.41Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6211.41Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6221.41Skamil}
6231.41Skamil
6241.41Skamil/// ----------------------------------------------------------------------------
6251.41Skamil
6261.43SkamilATF_TC(traceme_vfork_exec);
6271.43SkamilATF_TC_HEAD(traceme_vfork_exec, tc)
6281.43Skamil{
6291.43Skamil	atf_tc_set_md_var(tc, "descr",
6301.43Skamil	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child");
6311.43Skamil}
6321.43Skamil
6331.43SkamilATF_TC_BODY(traceme_vfork_exec, tc)
6341.43Skamil{
6351.43Skamil	const int sigval = SIGTRAP;
6361.43Skamil	pid_t child, wpid;
6371.43Skamil#if defined(TWAIT_HAVE_STATUS)
6381.43Skamil	int status;
6391.43Skamil#endif
6401.43Skamil
6411.43Skamil	struct ptrace_siginfo info;
6421.43Skamil	memset(&info, 0, sizeof(info));
6431.43Skamil
6441.43Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
6451.43Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
6461.43Skamil	if (child == 0) {
6471.43Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6481.43Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6491.43Skamil
6501.43Skamil		DPRINTF("Before calling execve(2) from child\n");
6511.43Skamil		execlp("/bin/echo", "/bin/echo", NULL);
6521.43Skamil
6531.43Skamil		/* NOTREACHED */
6541.43Skamil		FORKEE_ASSERTX(0 && "Not reached");
6551.43Skamil	}
6561.43Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6571.43Skamil
6581.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6591.43Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6601.43Skamil
6611.43Skamil	validate_status_stopped(status, sigval);
6621.43Skamil
6631.43Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6641.43Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6651.43Skamil
6661.43Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6671.43Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
6681.43Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6691.43Skamil	    info.psi_siginfo.si_errno);
6701.43Skamil
6711.43Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
6721.43Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
6731.43Skamil
6741.43Skamil	DPRINTF("Before resuming the child process where it left off and "
6751.43Skamil	    "without signal to be sent\n");
6761.43Skamil	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6771.43Skamil
6781.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6791.43Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6801.43Skamil
6811.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6821.43Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6831.43Skamil}
6841.43Skamil
6851.43Skamil/// ----------------------------------------------------------------------------
6861.43Skamil
6871.1Skamil#if defined(TWAIT_HAVE_PID)
6881.1SkamilATF_TC(attach1);
6891.1SkamilATF_TC_HEAD(attach1, tc)
6901.1Skamil{
6911.1Skamil	atf_tc_set_md_var(tc, "descr",
6921.1Skamil	    "Assert that tracer sees process termination before the parent");
6931.1Skamil}
6941.1Skamil
6951.26Skamilstatic void
6961.26Skamilattach1_raw(bool raw)
6971.1Skamil{
6981.1Skamil	struct msg_fds parent_tracee, parent_tracer;
6991.1Skamil	const int exitval_tracee = 5;
7001.1Skamil	const int exitval_tracer = 10;
7011.1Skamil	pid_t tracee, tracer, wpid;
7021.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7031.1Skamil#if defined(TWAIT_HAVE_STATUS)
7041.1Skamil	int status;
7051.1Skamil#endif
7061.1Skamil
7071.13Schristos	DPRINTF("Spawn tracee\n");
7081.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7091.1Skamil	tracee = atf_utils_fork();
7101.1Skamil	if (tracee == 0) {
7111.1Skamil		// Wait for parent to let us exit
7121.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
7131.1Skamil		_exit(exitval_tracee);
7141.1Skamil	}
7151.1Skamil
7161.13Schristos	DPRINTF("Spawn debugger\n");
7171.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7181.1Skamil	tracer = atf_utils_fork();
7191.1Skamil	if (tracer == 0) {
7201.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
7211.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7221.1Skamil
7231.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
7241.1Skamil		FORKEE_REQUIRE_SUCCESS(
7251.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7261.1Skamil
7271.1Skamil		forkee_status_stopped(status, SIGSTOP);
7281.1Skamil
7291.1Skamil		/* Resume tracee with PT_CONTINUE */
7301.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7311.1Skamil
7321.1Skamil		/* Inform parent that tracer has attached to tracee */
7331.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
7341.1Skamil
7351.1Skamil		/* Wait for parent to tell use that tracee should have exited */
7361.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
7371.1Skamil
7381.1Skamil		/* Wait for tracee and assert that it exited */
7391.1Skamil		FORKEE_REQUIRE_SUCCESS(
7401.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7411.1Skamil
7421.1Skamil		forkee_status_exited(status, exitval_tracee);
7431.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
7441.1Skamil
7451.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7461.1Skamil		_exit(exitval_tracer);
7471.1Skamil	}
7481.1Skamil
7491.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7501.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
7511.1Skamil
7521.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7531.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
7541.1Skamil
7551.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7561.26Skamil	if (raw)
7571.26Skamil		await_zombie_raw(tracee, 0);
7581.26Skamil	else
7591.26Skamil		await_zombie(tracee);
7601.1Skamil
7611.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
7621.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
7631.1Skamil	    TWAIT_FNAME);
7641.1Skamil	TWAIT_REQUIRE_SUCCESS(
7651.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7661.1Skamil
7671.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7681.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
7691.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
7701.1Skamil	    TWAIT_FNAME);
7711.1Skamil
7721.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7741.1Skamil	    tracer);
7751.1Skamil
7761.1Skamil	validate_status_exited(status, exitval_tracer);
7771.1Skamil
7781.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7791.1Skamil	    TWAIT_FNAME);
7801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7811.1Skamil	    tracee);
7821.1Skamil
7831.1Skamil	validate_status_exited(status, exitval_tracee);
7841.1Skamil
7851.1Skamil	msg_close(&parent_tracer);
7861.1Skamil	msg_close(&parent_tracee);
7871.1Skamil}
7881.26Skamil
7891.26SkamilATF_TC_BODY(attach1, tc)
7901.26Skamil{
7911.26Skamil
7921.26Skamil	/* Reuse this test with race1 */
7931.26Skamil	attach1_raw(false);
7941.26Skamil}
7951.26Skamil
7961.1Skamil#endif
7971.1Skamil
7981.1Skamil#if defined(TWAIT_HAVE_PID)
7991.1SkamilATF_TC(attach2);
8001.1SkamilATF_TC_HEAD(attach2, tc)
8011.1Skamil{
8021.1Skamil	atf_tc_set_md_var(tc, "descr",
8031.1Skamil	    "Assert that any tracer sees process termination before its "
8041.1Skamil	    "parent");
8051.1Skamil}
8061.1Skamil
8071.1SkamilATF_TC_BODY(attach2, tc)
8081.1Skamil{
8091.1Skamil	struct msg_fds parent_tracer, parent_tracee;
8101.1Skamil	const int exitval_tracee = 5;
8111.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
8121.1Skamil	pid_t tracee, tracer, wpid;
8131.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8141.1Skamil#if defined(TWAIT_HAVE_STATUS)
8151.1Skamil	int status;
8161.1Skamil#endif
8171.1Skamil
8181.13Schristos	DPRINTF("Spawn tracee\n");
8191.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8201.1Skamil	tracee = atf_utils_fork();
8211.1Skamil	if (tracee == 0) {
8221.1Skamil		/* Wait for message from the parent */
8231.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
8241.1Skamil		_exit(exitval_tracee);
8251.1Skamil	}
8261.1Skamil
8271.13Schristos	DPRINTF("Spawn debugger\n");
8281.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8291.1Skamil	tracer = atf_utils_fork();
8301.1Skamil	if (tracer == 0) {
8311.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
8321.1Skamil		tracer = atf_utils_fork();
8331.1Skamil		if (tracer != 0)
8341.1Skamil			_exit(exitval_tracer1);
8351.1Skamil
8361.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8371.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8381.1Skamil
8391.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8401.1Skamil		FORKEE_REQUIRE_SUCCESS(
8411.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8421.1Skamil
8431.1Skamil		forkee_status_stopped(status, SIGSTOP);
8441.1Skamil
8451.1Skamil		/* Resume tracee with PT_CONTINUE */
8461.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8471.1Skamil
8481.1Skamil		/* Inform parent that tracer has attached to tracee */
8491.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8501.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8511.1Skamil
8521.1Skamil		/* Wait for tracee and assert that it exited */
8531.1Skamil		FORKEE_REQUIRE_SUCCESS(
8541.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8551.1Skamil
8561.1Skamil		forkee_status_exited(status, exitval_tracee);
8571.1Skamil
8581.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8591.1Skamil		_exit(exitval_tracer2);
8601.1Skamil	}
8611.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
8621.1Skamil	    "%s()\n", TWAIT_FNAME);
8631.1Skamil	TWAIT_REQUIRE_SUCCESS(
8641.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
8651.1Skamil
8661.1Skamil	validate_status_exited(status, exitval_tracer1);
8671.1Skamil
8681.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
8691.1Skamil	    TWAIT_FNAME);
8701.1Skamil	TWAIT_REQUIRE_SUCCESS(
8711.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
8721.1Skamil
8731.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8741.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8751.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8761.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8771.1Skamil
8781.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8791.1Skamil	await_zombie(tracee);
8801.1Skamil
8811.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8821.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8831.1Skamil	TWAIT_REQUIRE_SUCCESS(
8841.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8851.1Skamil
8861.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8871.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8881.1Skamil
8891.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8901.1Skamil	    TWAIT_FNAME);
8911.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
8921.1Skamil	    tracee);
8931.1Skamil
8941.1Skamil	validate_status_exited(status, exitval_tracee);
8951.1Skamil
8961.1Skamil	msg_close(&parent_tracer);
8971.1Skamil	msg_close(&parent_tracee);
8981.1Skamil}
8991.1Skamil#endif
9001.1Skamil
9011.1SkamilATF_TC(attach3);
9021.1SkamilATF_TC_HEAD(attach3, tc)
9031.1Skamil{
9041.1Skamil	atf_tc_set_md_var(tc, "descr",
9051.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
9061.1Skamil}
9071.1Skamil
9081.1SkamilATF_TC_BODY(attach3, tc)
9091.1Skamil{
9101.1Skamil	struct msg_fds parent_tracee;
9111.1Skamil	const int exitval_tracee = 5;
9121.1Skamil	pid_t tracee, wpid;
9131.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
9141.1Skamil#if defined(TWAIT_HAVE_STATUS)
9151.1Skamil	int status;
9161.1Skamil#endif
9171.1Skamil
9181.13Schristos	DPRINTF("Spawn tracee\n");
9191.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9201.1Skamil	tracee = atf_utils_fork();
9211.1Skamil	if (tracee == 0) {
9221.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
9231.13Schristos		DPRINTF("Parent should now attach to tracee\n");
9241.1Skamil
9251.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
9261.1Skamil		/* Wait for message from the parent */
9271.1Skamil		_exit(exitval_tracee);
9281.1Skamil	}
9291.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
9301.1Skamil
9311.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
9321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9331.1Skamil
9341.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
9351.1Skamil	    TWAIT_FNAME);
9361.1Skamil	TWAIT_REQUIRE_SUCCESS(
9371.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9381.1Skamil
9391.1Skamil	validate_status_stopped(status, SIGSTOP);
9401.1Skamil
9411.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
9421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9431.1Skamil
9441.13Schristos	DPRINTF("Let the tracee exit now\n");
9451.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
9461.1Skamil
9471.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
9481.1Skamil	TWAIT_REQUIRE_SUCCESS(
9491.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9501.1Skamil
9511.1Skamil	validate_status_exited(status, exitval_tracee);
9521.1Skamil
9531.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
9541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
9551.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
9561.1Skamil
9571.1Skamil	msg_close(&parent_tracee);
9581.1Skamil}
9591.1Skamil
9601.1SkamilATF_TC(attach4);
9611.1SkamilATF_TC_HEAD(attach4, tc)
9621.1Skamil{
9631.1Skamil	atf_tc_set_md_var(tc, "descr",
9641.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
9651.1Skamil}
9661.1Skamil
9671.1SkamilATF_TC_BODY(attach4, tc)
9681.1Skamil{
9691.1Skamil	struct msg_fds parent_tracee;
9701.1Skamil	const int exitval_tracer = 5;
9711.1Skamil	pid_t tracer, wpid;
9721.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
9731.1Skamil#if defined(TWAIT_HAVE_STATUS)
9741.1Skamil	int status;
9751.1Skamil#endif
9761.1Skamil
9771.13Schristos	DPRINTF("Spawn tracer\n");
9781.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9791.1Skamil	tracer = atf_utils_fork();
9801.1Skamil	if (tracer == 0) {
9811.1Skamil
9821.1Skamil		/* Wait for message from the parent */
9831.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
9841.1Skamil
9851.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
9861.1Skamil		    getppid());
9871.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
9881.1Skamil
9891.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
9901.1Skamil		    TWAIT_FNAME);
9911.1Skamil		FORKEE_REQUIRE_SUCCESS(
9921.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
9931.1Skamil
9941.1Skamil		forkee_status_stopped(status, SIGSTOP);
9951.1Skamil
9961.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
9971.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
9981.1Skamil		    != -1);
9991.1Skamil
10001.1Skamil		/* Tell parent we are ready */
10011.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
10021.1Skamil
10031.1Skamil		_exit(exitval_tracer);
10041.1Skamil	}
10051.1Skamil
10061.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
10071.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
10081.13Schristos	DPRINTF("Allow the tracer to exit now\n");
10091.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
10101.1Skamil
10111.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
10121.1Skamil	TWAIT_REQUIRE_SUCCESS(
10131.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
10141.1Skamil
10151.1Skamil	validate_status_exited(status, exitval_tracer);
10161.1Skamil
10171.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
10181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
10191.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
10201.1Skamil
10211.1Skamil	msg_close(&parent_tracee);
10221.1Skamil}
10231.1Skamil
10241.1Skamil#if defined(TWAIT_HAVE_PID)
10251.1SkamilATF_TC(attach5);
10261.1SkamilATF_TC_HEAD(attach5, tc)
10271.1Skamil{
10281.1Skamil	atf_tc_set_md_var(tc, "descr",
10291.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
10301.1Skamil	    "(check getppid(2))");
10311.1Skamil}
10321.1Skamil
10331.1SkamilATF_TC_BODY(attach5, tc)
10341.1Skamil{
10351.1Skamil	struct msg_fds parent_tracer, parent_tracee;
10361.1Skamil	const int exitval_tracee = 5;
10371.1Skamil	const int exitval_tracer = 10;
10381.1Skamil	pid_t parent, tracee, tracer, wpid;
10391.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
10401.1Skamil#if defined(TWAIT_HAVE_STATUS)
10411.1Skamil	int status;
10421.1Skamil#endif
10431.1Skamil
10441.13Schristos	DPRINTF("Spawn tracee\n");
10451.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
10461.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
10471.1Skamil	tracee = atf_utils_fork();
10481.1Skamil	if (tracee == 0) {
10491.1Skamil		parent = getppid();
10501.1Skamil
10511.1Skamil		/* Emit message to the parent */
10521.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
10531.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
10541.1Skamil
10551.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
10561.1Skamil
10571.1Skamil		_exit(exitval_tracee);
10581.1Skamil	}
10591.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
10601.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
10611.1Skamil
10621.13Schristos	DPRINTF("Spawn debugger\n");
10631.1Skamil	tracer = atf_utils_fork();
10641.1Skamil	if (tracer == 0) {
10651.1Skamil		/* No IPC to communicate with the child */
10661.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
10671.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
10681.1Skamil
10691.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
10701.1Skamil		FORKEE_REQUIRE_SUCCESS(
10711.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10721.1Skamil
10731.1Skamil		forkee_status_stopped(status, SIGSTOP);
10741.1Skamil
10751.1Skamil		/* Resume tracee with PT_CONTINUE */
10761.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
10771.1Skamil
10781.1Skamil		/* Inform parent that tracer has attached to tracee */
10791.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
10801.1Skamil
10811.1Skamil		/* Wait for parent to tell use that tracee should have exited */
10821.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
10831.1Skamil
10841.1Skamil		/* Wait for tracee and assert that it exited */
10851.1Skamil		FORKEE_REQUIRE_SUCCESS(
10861.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10871.1Skamil
10881.1Skamil		forkee_status_exited(status, exitval_tracee);
10891.1Skamil
10901.13Schristos		DPRINTF("Before exiting of the tracer process\n");
10911.1Skamil		_exit(exitval_tracer);
10921.1Skamil	}
10931.1Skamil
10941.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
10951.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
10961.1Skamil
10971.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
10981.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
10991.1Skamil
11001.13Schristos	DPRINTF("Detect that tracee is zombie\n");
11011.1Skamil	await_zombie(tracee);
11021.1Skamil
11031.13Schristos	DPRINTF("Assert that there is no status about tracee - "
11041.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
11051.1Skamil	TWAIT_REQUIRE_SUCCESS(
11061.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
11071.1Skamil
11081.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
11091.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
11101.1Skamil
11111.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
11121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
11131.1Skamil	    tracer);
11141.1Skamil
11151.1Skamil	validate_status_exited(status, exitval_tracer);
11161.1Skamil
11171.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
11181.1Skamil	    TWAIT_FNAME);
11191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
11201.1Skamil	    tracee);
11211.1Skamil
11221.1Skamil	validate_status_exited(status, exitval_tracee);
11231.1Skamil
11241.1Skamil	msg_close(&parent_tracer);
11251.1Skamil	msg_close(&parent_tracee);
11261.1Skamil}
11271.1Skamil#endif
11281.1Skamil
11291.1Skamil#if defined(TWAIT_HAVE_PID)
11301.1SkamilATF_TC(attach6);
11311.1SkamilATF_TC_HEAD(attach6, tc)
11321.1Skamil{
11331.1Skamil	atf_tc_set_md_var(tc, "descr",
11341.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
11351.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
11361.1Skamil}
11371.1Skamil
11381.1SkamilATF_TC_BODY(attach6, tc)
11391.1Skamil{
11401.1Skamil	struct msg_fds parent_tracee, parent_tracer;
11411.1Skamil	const int exitval_tracee = 5;
11421.1Skamil	const int exitval_tracer = 10;
11431.1Skamil	pid_t parent, tracee, tracer, wpid;
11441.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
11451.1Skamil#if defined(TWAIT_HAVE_STATUS)
11461.1Skamil	int status;
11471.1Skamil#endif
11481.1Skamil	int name[CTL_MAXNAME];
11491.1Skamil	struct kinfo_proc2 kp;
11501.1Skamil	size_t len = sizeof(kp);
11511.1Skamil	unsigned int namelen;
11521.1Skamil
11531.13Schristos	DPRINTF("Spawn tracee\n");
11541.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
11551.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
11561.1Skamil	tracee = atf_utils_fork();
11571.1Skamil	if (tracee == 0) {
11581.1Skamil		parent = getppid();
11591.1Skamil
11601.1Skamil		/* Emit message to the parent */
11611.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
11621.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
11631.1Skamil
11641.1Skamil		namelen = 0;
11651.1Skamil		name[namelen++] = CTL_KERN;
11661.1Skamil		name[namelen++] = KERN_PROC2;
11671.1Skamil		name[namelen++] = KERN_PROC_PID;
11681.1Skamil		name[namelen++] = getpid();
11691.1Skamil		name[namelen++] = len;
11701.1Skamil		name[namelen++] = 1;
11711.1Skamil
11721.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
11731.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
11741.1Skamil
11751.1Skamil		_exit(exitval_tracee);
11761.1Skamil	}
11771.1Skamil
11781.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
11791.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
11801.1Skamil
11811.13Schristos	DPRINTF("Spawn debugger\n");
11821.1Skamil	tracer = atf_utils_fork();
11831.1Skamil	if (tracer == 0) {
11841.1Skamil		/* No IPC to communicate with the child */
11851.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
11861.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
11871.1Skamil
11881.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
11891.1Skamil		FORKEE_REQUIRE_SUCCESS(
11901.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
11911.1Skamil
11921.1Skamil		forkee_status_stopped(status, SIGSTOP);
11931.1Skamil
11941.1Skamil		/* Resume tracee with PT_CONTINUE */
11951.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
11961.1Skamil
11971.1Skamil		/* Inform parent that tracer has attached to tracee */
11981.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
11991.1Skamil
12001.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
12011.1Skamil
12021.1Skamil		/* Wait for tracee and assert that it exited */
12031.1Skamil		FORKEE_REQUIRE_SUCCESS(
12041.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
12051.1Skamil
12061.1Skamil		forkee_status_exited(status, exitval_tracee);
12071.1Skamil
12081.13Schristos		DPRINTF("Before exiting of the tracer process\n");
12091.1Skamil		_exit(exitval_tracer);
12101.1Skamil	}
12111.1Skamil
12121.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
12131.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
12141.1Skamil
12151.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
12161.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
12171.1Skamil
12181.13Schristos	DPRINTF("Detect that tracee is zombie\n");
12191.1Skamil	await_zombie(tracee);
12201.1Skamil
12211.13Schristos	DPRINTF("Assert that there is no status about tracee - "
12221.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
12231.1Skamil	TWAIT_REQUIRE_SUCCESS(
12241.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
12251.1Skamil
12261.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
12271.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
12281.1Skamil
12291.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
12301.1Skamil	    TWAIT_FNAME);
12311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
12321.1Skamil	    tracer);
12331.1Skamil
12341.1Skamil	validate_status_exited(status, exitval_tracer);
12351.1Skamil
12361.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
12371.1Skamil	    TWAIT_FNAME);
12381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
12391.1Skamil	    tracee);
12401.1Skamil
12411.1Skamil	validate_status_exited(status, exitval_tracee);
12421.1Skamil
12431.1Skamil	msg_close(&parent_tracee);
12441.1Skamil	msg_close(&parent_tracer);
12451.1Skamil}
12461.1Skamil#endif
12471.1Skamil
12481.1Skamil#if defined(TWAIT_HAVE_PID)
12491.1SkamilATF_TC(attach7);
12501.1SkamilATF_TC_HEAD(attach7, tc)
12511.1Skamil{
12521.1Skamil	atf_tc_set_md_var(tc, "descr",
12531.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
12541.1Skamil	    "(check /proc/curproc/status 3rd column)");
12551.1Skamil}
12561.1Skamil
12571.1SkamilATF_TC_BODY(attach7, tc)
12581.1Skamil{
12591.1Skamil	struct msg_fds parent_tracee, parent_tracer;
12601.1Skamil	int rv;
12611.1Skamil	const int exitval_tracee = 5;
12621.1Skamil	const int exitval_tracer = 10;
12631.1Skamil	pid_t parent, tracee, tracer, wpid;
12641.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
12651.1Skamil#if defined(TWAIT_HAVE_STATUS)
12661.1Skamil	int status;
12671.1Skamil#endif
12681.1Skamil	FILE *fp;
12691.1Skamil	struct stat st;
12701.1Skamil	const char *fname = "/proc/curproc/status";
12711.1Skamil	char s_executable[MAXPATHLEN];
12721.1Skamil	int s_pid, s_ppid;
12731.1Skamil	/*
12741.1Skamil	 * Format:
12751.1Skamil	 *  EXECUTABLE PID PPID ...
12761.1Skamil	 */
12771.1Skamil
12781.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
12791.1Skamil	if (rv != 0) {
12801.1Skamil		atf_tc_skip("/proc/curproc/status not found");
12811.1Skamil	}
12821.1Skamil
12831.13Schristos	DPRINTF("Spawn tracee\n");
12841.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
12851.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
12861.1Skamil	tracee = atf_utils_fork();
12871.1Skamil	if (tracee == 0) {
12881.1Skamil		parent = getppid();
12891.1Skamil
12901.1Skamil		// Wait for parent to let us exit
12911.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
12921.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
12931.1Skamil
12941.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
12951.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
12961.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
12971.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
12981.1Skamil
12991.1Skamil		_exit(exitval_tracee);
13001.1Skamil	}
13011.1Skamil
13021.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
13031.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
13041.1Skamil
13051.13Schristos	DPRINTF("Spawn debugger\n");
13061.1Skamil	tracer = atf_utils_fork();
13071.1Skamil	if (tracer == 0) {
13081.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
13091.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
13101.1Skamil
13111.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
13121.1Skamil		FORKEE_REQUIRE_SUCCESS(
13131.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
13141.1Skamil
13151.1Skamil		forkee_status_stopped(status, SIGSTOP);
13161.1Skamil
13171.1Skamil		/* Resume tracee with PT_CONTINUE */
13181.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
13191.1Skamil
13201.1Skamil		/* Inform parent that tracer has attached to tracee */
13211.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
13221.1Skamil
13231.1Skamil		/* Wait for parent to tell use that tracee should have exited */
13241.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
13251.1Skamil
13261.1Skamil		/* Wait for tracee and assert that it exited */
13271.1Skamil		FORKEE_REQUIRE_SUCCESS(
13281.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
13291.1Skamil
13301.1Skamil		forkee_status_exited(status, exitval_tracee);
13311.1Skamil
13321.13Schristos		DPRINTF("Before exiting of the tracer process\n");
13331.1Skamil		_exit(exitval_tracer);
13341.1Skamil	}
13351.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
13361.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
13371.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
13381.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
13391.1Skamil
13401.13Schristos	DPRINTF("Detect that tracee is zombie\n");
13411.1Skamil	await_zombie(tracee);
13421.1Skamil
13431.13Schristos	DPRINTF("Assert that there is no status about tracee - "
13441.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
13451.1Skamil	TWAIT_REQUIRE_SUCCESS(
13461.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
13471.1Skamil
13481.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
13491.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
13501.1Skamil
13511.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
13521.1Skamil	    TWAIT_FNAME);
13531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
13541.1Skamil	    tracer);
13551.1Skamil
13561.1Skamil	validate_status_exited(status, exitval_tracer);
13571.1Skamil
13581.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
13591.1Skamil	    TWAIT_FNAME);
13601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
13611.1Skamil	    tracee);
13621.1Skamil
13631.1Skamil	validate_status_exited(status, exitval_tracee);
13641.1Skamil
13651.1Skamil	msg_close(&parent_tracee);
13661.1Skamil	msg_close(&parent_tracer);
13671.1Skamil}
13681.1Skamil#endif
13691.1Skamil
13701.1SkamilATF_TC(eventmask1);
13711.1SkamilATF_TC_HEAD(eventmask1, tc)
13721.1Skamil{
13731.1Skamil	atf_tc_set_md_var(tc, "descr",
13741.1Skamil	    "Verify that empty EVENT_MASK is preserved");
13751.1Skamil}
13761.1Skamil
13771.1SkamilATF_TC_BODY(eventmask1, tc)
13781.1Skamil{
13791.1Skamil	const int exitval = 5;
13801.1Skamil	const int sigval = SIGSTOP;
13811.1Skamil	pid_t child, wpid;
13821.1Skamil#if defined(TWAIT_HAVE_STATUS)
13831.1Skamil	int status;
13841.1Skamil#endif
13851.1Skamil	ptrace_event_t set_event, get_event;
13861.1Skamil	const int len = sizeof(ptrace_event_t);
13871.1Skamil
13881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13901.1Skamil	if (child == 0) {
13911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13931.1Skamil
13941.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13951.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13961.1Skamil
13971.13Schristos		DPRINTF("Before exiting of the child process\n");
13981.1Skamil		_exit(exitval);
13991.1Skamil	}
14001.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14011.1Skamil
14021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14041.1Skamil
14051.1Skamil	validate_status_stopped(status, sigval);
14061.1Skamil
14071.1Skamil	set_event.pe_set_event = 0;
14081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
14091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
14101.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
14111.1Skamil
14121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14131.1Skamil	    "without signal to be sent\n");
14141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14151.1Skamil
14161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14181.1Skamil
14191.1Skamil	validate_status_exited(status, exitval);
14201.1Skamil
14211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14231.1Skamil}
14241.1Skamil
14251.1SkamilATF_TC(eventmask2);
14261.1SkamilATF_TC_HEAD(eventmask2, tc)
14271.1Skamil{
14281.1Skamil	atf_tc_set_md_var(tc, "descr",
14291.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
14301.1Skamil}
14311.1Skamil
14321.1SkamilATF_TC_BODY(eventmask2, tc)
14331.1Skamil{
14341.1Skamil	const int exitval = 5;
14351.1Skamil	const int sigval = SIGSTOP;
14361.1Skamil	pid_t child, wpid;
14371.1Skamil#if defined(TWAIT_HAVE_STATUS)
14381.1Skamil	int status;
14391.1Skamil#endif
14401.1Skamil	ptrace_event_t set_event, get_event;
14411.1Skamil	const int len = sizeof(ptrace_event_t);
14421.1Skamil
14431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14451.1Skamil	if (child == 0) {
14461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14481.1Skamil
14491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14511.1Skamil
14521.13Schristos		DPRINTF("Before exiting of the child process\n");
14531.1Skamil		_exit(exitval);
14541.1Skamil	}
14551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14561.1Skamil
14571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14591.1Skamil
14601.1Skamil	validate_status_stopped(status, sigval);
14611.1Skamil
14621.1Skamil	set_event.pe_set_event = PTRACE_FORK;
14631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
14641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
14651.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
14661.1Skamil
14671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14681.1Skamil	    "without signal to be sent\n");
14691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14701.1Skamil
14711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14731.1Skamil
14741.1Skamil	validate_status_exited(status, exitval);
14751.1Skamil
14761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14781.1Skamil}
14791.1Skamil
14801.1SkamilATF_TC(eventmask3);
14811.1SkamilATF_TC_HEAD(eventmask3, tc)
14821.1Skamil{
14831.1Skamil	atf_tc_set_md_var(tc, "descr",
14841.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
14851.1Skamil}
14861.1Skamil
14871.1SkamilATF_TC_BODY(eventmask3, tc)
14881.1Skamil{
14891.1Skamil	const int exitval = 5;
14901.1Skamil	const int sigval = SIGSTOP;
14911.1Skamil	pid_t child, wpid;
14921.1Skamil#if defined(TWAIT_HAVE_STATUS)
14931.1Skamil	int status;
14941.1Skamil#endif
14951.1Skamil	ptrace_event_t set_event, get_event;
14961.1Skamil	const int len = sizeof(ptrace_event_t);
14971.1Skamil
14981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15001.1Skamil	if (child == 0) {
15011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15031.1Skamil
15041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15061.1Skamil
15071.13Schristos		DPRINTF("Before exiting of the child process\n");
15081.1Skamil		_exit(exitval);
15091.1Skamil	}
15101.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15111.1Skamil
15121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15141.1Skamil
15151.1Skamil	validate_status_stopped(status, sigval);
15161.1Skamil
15171.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
15181.38Skamil	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
15191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
15201.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
15211.1Skamil
15221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15231.1Skamil	    "without signal to be sent\n");
15241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15251.1Skamil
15261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15281.1Skamil
15291.1Skamil	validate_status_exited(status, exitval);
15301.1Skamil
15311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15331.1Skamil}
15341.1Skamil
15351.1SkamilATF_TC(eventmask4);
15361.1SkamilATF_TC_HEAD(eventmask4, tc)
15371.1Skamil{
15381.1Skamil	atf_tc_set_md_var(tc, "descr",
15391.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
15401.1Skamil}
15411.1Skamil
15421.1SkamilATF_TC_BODY(eventmask4, tc)
15431.1Skamil{
15441.1Skamil	const int exitval = 5;
15451.1Skamil	const int sigval = SIGSTOP;
15461.1Skamil	pid_t child, wpid;
15471.1Skamil#if defined(TWAIT_HAVE_STATUS)
15481.1Skamil	int status;
15491.1Skamil#endif
15501.1Skamil	ptrace_event_t set_event, get_event;
15511.1Skamil	const int len = sizeof(ptrace_event_t);
15521.1Skamil
15531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15551.1Skamil	if (child == 0) {
15561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15581.1Skamil
15591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15611.1Skamil
15621.13Schristos		DPRINTF("Before exiting of the child process\n");
15631.1Skamil		_exit(exitval);
15641.1Skamil	}
15651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15661.1Skamil
15671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15691.1Skamil
15701.1Skamil	validate_status_stopped(status, sigval);
15711.1Skamil
15721.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
15731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
15741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
15751.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
15761.1Skamil
15771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15781.1Skamil	    "without signal to be sent\n");
15791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15801.1Skamil
15811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15831.1Skamil
15841.1Skamil	validate_status_exited(status, exitval);
15851.1Skamil
15861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15881.1Skamil}
15891.1Skamil
15901.1SkamilATF_TC(eventmask5);
15911.1SkamilATF_TC_HEAD(eventmask5, tc)
15921.1Skamil{
15931.1Skamil	atf_tc_set_md_var(tc, "descr",
15941.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
15951.1Skamil}
15961.1Skamil
15971.1SkamilATF_TC_BODY(eventmask5, tc)
15981.1Skamil{
15991.1Skamil	const int exitval = 5;
16001.1Skamil	const int sigval = SIGSTOP;
16011.1Skamil	pid_t child, wpid;
16021.1Skamil#if defined(TWAIT_HAVE_STATUS)
16031.1Skamil	int status;
16041.1Skamil#endif
16051.1Skamil	ptrace_event_t set_event, get_event;
16061.1Skamil	const int len = sizeof(ptrace_event_t);
16071.1Skamil
16081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16101.1Skamil	if (child == 0) {
16111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16131.1Skamil
16141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16161.1Skamil
16171.13Schristos		DPRINTF("Before exiting of the child process\n");
16181.1Skamil		_exit(exitval);
16191.1Skamil	}
16201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16211.1Skamil
16221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16241.1Skamil
16251.1Skamil	validate_status_stopped(status, sigval);
16261.1Skamil
16271.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
16281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
16291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
16301.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
16311.1Skamil
16321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16331.1Skamil	    "without signal to be sent\n");
16341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16351.1Skamil
16361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16381.1Skamil
16391.1Skamil	validate_status_exited(status, exitval);
16401.1Skamil
16411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16431.1Skamil}
16441.1Skamil
16451.1SkamilATF_TC(eventmask6);
16461.1SkamilATF_TC_HEAD(eventmask6, tc)
16471.1Skamil{
16481.1Skamil	atf_tc_set_md_var(tc, "descr",
16491.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
16501.1Skamil}
16511.1Skamil
16521.1SkamilATF_TC_BODY(eventmask6, tc)
16531.1Skamil{
16541.1Skamil	const int exitval = 5;
16551.1Skamil	const int sigval = SIGSTOP;
16561.1Skamil	pid_t child, wpid;
16571.1Skamil#if defined(TWAIT_HAVE_STATUS)
16581.1Skamil	int status;
16591.1Skamil#endif
16601.1Skamil	ptrace_event_t set_event, get_event;
16611.1Skamil	const int len = sizeof(ptrace_event_t);
16621.1Skamil
16631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16651.1Skamil	if (child == 0) {
16661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16681.1Skamil
16691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16711.1Skamil
16721.13Schristos		DPRINTF("Before exiting of the child process\n");
16731.1Skamil		_exit(exitval);
16741.1Skamil	}
16751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16761.1Skamil
16771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16791.1Skamil
16801.1Skamil	validate_status_stopped(status, sigval);
16811.1Skamil
16821.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
16831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
16841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
16851.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
16861.1Skamil
16871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16881.1Skamil	    "without signal to be sent\n");
16891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16901.1Skamil
16911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16931.1Skamil
16941.1Skamil	validate_status_exited(status, exitval);
16951.1Skamil
16961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16981.1Skamil}
16991.1Skamil
17001.28Skamilstatic void
17011.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
17021.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
17031.1Skamil{
17041.1Skamil	const int exitval = 5;
17051.1Skamil	const int exitval2 = 15;
17061.1Skamil	const int sigval = SIGSTOP;
17071.31Skamil	pid_t child, child2 = 0, wpid;
17081.1Skamil#if defined(TWAIT_HAVE_STATUS)
17091.1Skamil	int status;
17101.1Skamil#endif
17111.1Skamil	ptrace_state_t state;
17121.1Skamil	const int slen = sizeof(state);
17131.1Skamil	ptrace_event_t event;
17141.1Skamil	const int elen = sizeof(event);
17151.1Skamil
17161.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17171.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17181.1Skamil	if (child == 0) {
17191.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17201.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17211.1Skamil
17221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17241.1Skamil
17251.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
17261.1Skamil
17271.1Skamil		if (child2 == 0)
17281.1Skamil			_exit(exitval2);
17291.1Skamil
17301.1Skamil		FORKEE_REQUIRE_SUCCESS
17311.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
17321.1Skamil
17331.1Skamil		forkee_status_exited(status, exitval2);
17341.1Skamil
17351.13Schristos		DPRINTF("Before exiting of the child process\n");
17361.1Skamil		_exit(exitval);
17371.1Skamil	}
17381.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17391.1Skamil
17401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17421.1Skamil
17431.1Skamil	validate_status_stopped(status, sigval);
17441.1Skamil
17451.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
17461.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
17471.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
17481.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
17491.30Skamil	event.pe_set_event = 0;
17501.30Skamil	if (trackfork)
17511.30Skamil		event.pe_set_event |= PTRACE_FORK;
17521.30Skamil	if (trackvfork)
17531.30Skamil		event.pe_set_event |= PTRACE_VFORK;
17541.30Skamil	if (trackvforkdone)
17551.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
17561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17571.1Skamil
17581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17591.1Skamil	    "without signal to be sent\n");
17601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17611.1Skamil
17621.29Skamil#if defined(TWAIT_HAVE_PID)
17631.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
17641.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
17651.29Skamil		        child);
17661.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
17671.29Skamil		                      child);
17681.1Skamil
17691.29Skamil		validate_status_stopped(status, SIGTRAP);
17701.1Skamil
17711.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
17721.29Skamil		                       slen) != -1);
17731.31Skamil		if (trackfork && fn == fork) {
17741.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
17751.30Skamil			       PTRACE_FORK);
17761.30Skamil		}
17771.31Skamil		if (trackvfork && fn == vfork) {
17781.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
17791.30Skamil			       PTRACE_VFORK);
17801.30Skamil		}
17811.29Skamil
17821.29Skamil		child2 = state.pe_other_pid;
17831.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
17841.29Skamil
17851.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
17861.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
17871.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
17881.29Skamil		    child2);
17891.1Skamil
17901.29Skamil		validate_status_stopped(status, SIGTRAP);
17911.1Skamil
17921.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
17931.29Skamil		                       slen) != -1);
17941.31Skamil		if (trackfork && fn == fork) {
17951.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
17961.30Skamil			       PTRACE_FORK);
17971.30Skamil		}
17981.31Skamil		if (trackvfork && fn == vfork) {
17991.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
18001.30Skamil			       PTRACE_VFORK);
18011.30Skamil		}
18021.30Skamil
18031.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
18041.29Skamil
18051.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
18061.29Skamil		    "and without signal to be sent\n");
18071.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
18081.29Skamil		                != -1);
18091.29Skamil
18101.29Skamil		DPRINTF("Before resuming the child process where it left off "
18111.29Skamil		        "and without signal to be sent\n");
18121.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18131.30Skamil	}
18141.30Skamil#endif
18151.30Skamil
18161.31Skamil	if (trackvforkdone && fn == vfork) {
18171.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
18181.30Skamil		        child);
18191.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
18201.30Skamil		                      child);
18211.30Skamil
18221.30Skamil		validate_status_stopped(status, SIGTRAP);
18231.30Skamil
18241.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
18251.30Skamil		                       slen) != -1);
18261.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
18271.30Skamil
18281.30Skamil		child2 = state.pe_other_pid;
18291.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
18301.30Skamil		        child2);
18311.30Skamil
18321.30Skamil		DPRINTF("Before resuming the child process where it left off "
18331.30Skamil		        "and without signal to be sent\n");
18341.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18351.30Skamil	}
18361.29Skamil
18371.30Skamil#if defined(TWAIT_HAVE_PID)
18381.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
18391.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
18401.29Skamil		        "\n", TWAIT_FNAME);
18411.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
18421.29Skamil		    child2);
18431.29Skamil
18441.29Skamil		validate_status_exited(status, exitval2);
18451.29Skamil
18461.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
18471.29Skamil		        "process\n", TWAIT_FNAME);
18481.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
18491.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
18501.29Skamil	}
18511.29Skamil#endif
18521.1Skamil
18531.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18541.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18561.1Skamil
18571.1Skamil	validate_status_stopped(status, SIGCHLD);
18581.1Skamil
18591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18601.1Skamil	    "without signal to be sent\n");
18611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18621.1Skamil
18631.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
18641.1Skamil	    TWAIT_FNAME);
18651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18661.1Skamil
18671.1Skamil	validate_status_exited(status, exitval);
18681.1Skamil
18691.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
18701.1Skamil	    TWAIT_FNAME);
18711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18721.1Skamil}
18731.28Skamil
18741.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
18751.32SkamilATF_TC(name);									\
18761.32SkamilATF_TC_HEAD(name, tc)								\
18771.32Skamil{										\
18781.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
18791.32Skamil}										\
18801.32Skamil										\
18811.32SkamilATF_TC_BODY(name, tc)								\
18821.32Skamil{										\
18831.32Skamil										\
18841.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
18851.32Skamil}
18861.32Skamil
18871.32Skamil#define F false
18881.32Skamil#define T true
18891.32Skamil
18901.32Skamil#define F_IF__0(x)
18911.32Skamil#define F_IF__1(x) x
18921.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
18931.32Skamil#define F_IF_(x,y) F_IF__(x,y)
18941.32Skamil#define F_IF(x,y) F_IF_(x,y)
18951.32Skamil
18961.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
18971.32Skamil        "Verify " #function "(2) called with 0"					\
18981.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
18991.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
19001.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
19011.32Skamil        " in EVENT_MASK."							\
19021.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
19031.32Skamil        F_IF(dparentbit," Detach parent in this test.")
19041.1Skamil
19051.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
19061.31Skamil#if defined(TWAIT_HAVE_PID)
19071.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
19081.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
19091.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
19101.31Skamil#endif
19111.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
19121.31Skamil#if defined(TWAIT_HAVE_PID)
19131.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
19141.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
19151.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
19161.31Skamil#endif
19171.1Skamil
19181.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
19191.31Skamil#if defined(TWAIT_HAVE_PID)
19201.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
19211.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
19221.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
19231.31Skamil#endif
19241.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
19251.31Skamil#if defined(TWAIT_HAVE_PID)
19261.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
19271.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
19281.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
19291.31Skamil#endif
19301.31Skamil
19311.31Skamil
19321.31Skamil
19331.1Skamil
19341.1SkamilATF_TC(io_read_d1);
19351.1SkamilATF_TC_HEAD(io_read_d1, tc)
19361.1Skamil{
19371.1Skamil	atf_tc_set_md_var(tc, "descr",
19381.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
19391.1Skamil}
19401.1Skamil
19411.1SkamilATF_TC_BODY(io_read_d1, tc)
19421.1Skamil{
19431.1Skamil	const int exitval = 5;
19441.1Skamil	const int sigval = SIGSTOP;
19451.1Skamil	pid_t child, wpid;
19461.1Skamil	uint8_t lookup_me = 0;
19471.1Skamil	const uint8_t magic = 0xab;
19481.1Skamil	struct ptrace_io_desc io = {
19491.1Skamil		.piod_op = PIOD_READ_D,
19501.1Skamil		.piod_offs = &lookup_me,
19511.1Skamil		.piod_addr = &lookup_me,
19521.1Skamil		.piod_len = sizeof(lookup_me)
19531.1Skamil	};
19541.1Skamil#if defined(TWAIT_HAVE_STATUS)
19551.1Skamil	int status;
19561.1Skamil#endif
19571.1Skamil
19581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19601.1Skamil	if (child == 0) {
19611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19631.1Skamil
19641.1Skamil		lookup_me = magic;
19651.1Skamil
19661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19681.1Skamil
19691.13Schristos		DPRINTF("Before exiting of the child process\n");
19701.1Skamil		_exit(exitval);
19711.1Skamil	}
19721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19731.1Skamil
19741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19761.1Skamil
19771.1Skamil	validate_status_stopped(status, sigval);
19781.1Skamil
19791.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19801.1Skamil	    child, getpid());
19811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19821.1Skamil
19831.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19841.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
19851.1Skamil
19861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19871.1Skamil	    "without signal to be sent\n");
19881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19891.1Skamil
19901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19921.1Skamil
19931.1Skamil	validate_status_exited(status, exitval);
19941.1Skamil
19951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19971.1Skamil}
19981.1Skamil
19991.1SkamilATF_TC(io_read_d2);
20001.1SkamilATF_TC_HEAD(io_read_d2, tc)
20011.1Skamil{
20021.1Skamil	atf_tc_set_md_var(tc, "descr",
20031.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
20041.1Skamil}
20051.1Skamil
20061.1SkamilATF_TC_BODY(io_read_d2, tc)
20071.1Skamil{
20081.1Skamil	const int exitval = 5;
20091.1Skamil	const int sigval = SIGSTOP;
20101.1Skamil	pid_t child, wpid;
20111.1Skamil	uint16_t lookup_me = 0;
20121.1Skamil	const uint16_t magic = 0x1234;
20131.1Skamil	struct ptrace_io_desc io = {
20141.1Skamil		.piod_op = PIOD_READ_D,
20151.1Skamil		.piod_offs = &lookup_me,
20161.1Skamil		.piod_addr = &lookup_me,
20171.1Skamil		.piod_len = sizeof(lookup_me)
20181.1Skamil	};
20191.1Skamil#if defined(TWAIT_HAVE_STATUS)
20201.1Skamil	int status;
20211.1Skamil#endif
20221.1Skamil
20231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20251.1Skamil	if (child == 0) {
20261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20281.1Skamil
20291.1Skamil		lookup_me = magic;
20301.1Skamil
20311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20331.1Skamil
20341.13Schristos		DPRINTF("Before exiting of the child process\n");
20351.1Skamil		_exit(exitval);
20361.1Skamil	}
20371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20381.1Skamil
20391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20411.1Skamil
20421.1Skamil	validate_status_stopped(status, sigval);
20431.1Skamil
20441.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20451.1Skamil	    child, getpid());
20461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20471.1Skamil
20481.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20491.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
20501.1Skamil
20511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20521.1Skamil	    "without signal to be sent\n");
20531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20541.1Skamil
20551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20571.1Skamil
20581.1Skamil	validate_status_exited(status, exitval);
20591.1Skamil
20601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20621.1Skamil}
20631.1Skamil
20641.1SkamilATF_TC(io_read_d3);
20651.1SkamilATF_TC_HEAD(io_read_d3, tc)
20661.1Skamil{
20671.1Skamil	atf_tc_set_md_var(tc, "descr",
20681.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
20691.1Skamil}
20701.1Skamil
20711.1SkamilATF_TC_BODY(io_read_d3, tc)
20721.1Skamil{
20731.1Skamil	const int exitval = 5;
20741.1Skamil	const int sigval = SIGSTOP;
20751.1Skamil	pid_t child, wpid;
20761.1Skamil	uint32_t lookup_me = 0;
20771.1Skamil	const uint32_t magic = 0x1234abcd;
20781.1Skamil	struct ptrace_io_desc io = {
20791.1Skamil		.piod_op = PIOD_READ_D,
20801.1Skamil		.piod_offs = &lookup_me,
20811.1Skamil		.piod_addr = &lookup_me,
20821.1Skamil		.piod_len = sizeof(lookup_me)
20831.1Skamil	};
20841.1Skamil#if defined(TWAIT_HAVE_STATUS)
20851.1Skamil	int status;
20861.1Skamil#endif
20871.1Skamil
20881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20901.1Skamil	if (child == 0) {
20911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20931.1Skamil
20941.1Skamil		lookup_me = magic;
20951.1Skamil
20961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20981.1Skamil
20991.13Schristos		DPRINTF("Before exiting of the child process\n");
21001.1Skamil		_exit(exitval);
21011.1Skamil	}
21021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21031.1Skamil
21041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21061.1Skamil
21071.1Skamil	validate_status_stopped(status, sigval);
21081.1Skamil
21091.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21101.1Skamil	    child, getpid());
21111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21121.1Skamil
21131.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21141.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
21151.1Skamil
21161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21171.1Skamil	    "without signal to be sent\n");
21181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21191.1Skamil
21201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21221.1Skamil
21231.1Skamil	validate_status_exited(status, exitval);
21241.1Skamil
21251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21271.1Skamil}
21281.1Skamil
21291.1SkamilATF_TC(io_read_d4);
21301.1SkamilATF_TC_HEAD(io_read_d4, tc)
21311.1Skamil{
21321.1Skamil	atf_tc_set_md_var(tc, "descr",
21331.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
21341.1Skamil}
21351.1Skamil
21361.1SkamilATF_TC_BODY(io_read_d4, tc)
21371.1Skamil{
21381.1Skamil	const int exitval = 5;
21391.1Skamil	const int sigval = SIGSTOP;
21401.1Skamil	pid_t child, wpid;
21411.1Skamil	uint64_t lookup_me = 0;
21421.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
21431.1Skamil	struct ptrace_io_desc io = {
21441.1Skamil		.piod_op = PIOD_READ_D,
21451.1Skamil		.piod_offs = &lookup_me,
21461.1Skamil		.piod_addr = &lookup_me,
21471.1Skamil		.piod_len = sizeof(lookup_me)
21481.1Skamil	};
21491.1Skamil#if defined(TWAIT_HAVE_STATUS)
21501.1Skamil	int status;
21511.1Skamil#endif
21521.1Skamil
21531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21551.1Skamil	if (child == 0) {
21561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21581.1Skamil
21591.1Skamil		lookup_me = magic;
21601.1Skamil
21611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21631.1Skamil
21641.13Schristos		DPRINTF("Before exiting of the child process\n");
21651.1Skamil		_exit(exitval);
21661.1Skamil	}
21671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21681.1Skamil
21691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21711.1Skamil
21721.1Skamil	validate_status_stopped(status, sigval);
21731.1Skamil
21741.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21751.1Skamil	    child, getpid());
21761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21771.1Skamil
21781.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21791.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
21801.1Skamil
21811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21821.1Skamil	    "without signal to be sent\n");
21831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21841.1Skamil
21851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21871.1Skamil
21881.1Skamil	validate_status_exited(status, exitval);
21891.1Skamil
21901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21921.1Skamil}
21931.1Skamil
21941.1SkamilATF_TC(io_write_d1);
21951.1SkamilATF_TC_HEAD(io_write_d1, tc)
21961.1Skamil{
21971.1Skamil	atf_tc_set_md_var(tc, "descr",
21981.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
21991.1Skamil}
22001.1Skamil
22011.1SkamilATF_TC_BODY(io_write_d1, tc)
22021.1Skamil{
22031.1Skamil	const int exitval = 5;
22041.1Skamil	const int sigval = SIGSTOP;
22051.1Skamil	pid_t child, wpid;
22061.1Skamil	uint8_t lookup_me = 0;
22071.1Skamil	const uint8_t magic = 0xab;
22081.1Skamil	struct ptrace_io_desc io = {
22091.1Skamil		.piod_op = PIOD_WRITE_D,
22101.1Skamil		.piod_offs = &lookup_me,
22111.1Skamil		.piod_addr = &lookup_me,
22121.1Skamil		.piod_len = sizeof(lookup_me)
22131.1Skamil	};
22141.1Skamil#if defined(TWAIT_HAVE_STATUS)
22151.1Skamil	int status;
22161.1Skamil#endif
22171.1Skamil
22181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22201.1Skamil	if (child == 0) {
22211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22231.1Skamil
22241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22261.1Skamil
22271.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22281.1Skamil
22291.13Schristos		DPRINTF("Before exiting of the child process\n");
22301.1Skamil		_exit(exitval);
22311.1Skamil	}
22321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22331.1Skamil
22341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22361.1Skamil
22371.1Skamil	validate_status_stopped(status, sigval);
22381.1Skamil
22391.1Skamil	lookup_me = magic;
22401.1Skamil
22411.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22421.1Skamil	    child, getpid());
22431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22441.1Skamil
22451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22461.1Skamil	    "without signal to be sent\n");
22471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22481.1Skamil
22491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22511.1Skamil
22521.1Skamil	validate_status_exited(status, exitval);
22531.1Skamil
22541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22561.1Skamil}
22571.1Skamil
22581.1SkamilATF_TC(io_write_d2);
22591.1SkamilATF_TC_HEAD(io_write_d2, tc)
22601.1Skamil{
22611.1Skamil	atf_tc_set_md_var(tc, "descr",
22621.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
22631.1Skamil}
22641.1Skamil
22651.1SkamilATF_TC_BODY(io_write_d2, tc)
22661.1Skamil{
22671.1Skamil	const int exitval = 5;
22681.1Skamil	const int sigval = SIGSTOP;
22691.1Skamil	pid_t child, wpid;
22701.1Skamil	uint16_t lookup_me = 0;
22711.1Skamil	const uint16_t magic = 0xab12;
22721.1Skamil	struct ptrace_io_desc io = {
22731.1Skamil		.piod_op = PIOD_WRITE_D,
22741.1Skamil		.piod_offs = &lookup_me,
22751.1Skamil		.piod_addr = &lookup_me,
22761.1Skamil		.piod_len = sizeof(lookup_me)
22771.1Skamil	};
22781.1Skamil#if defined(TWAIT_HAVE_STATUS)
22791.1Skamil	int status;
22801.1Skamil#endif
22811.1Skamil
22821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22841.1Skamil	if (child == 0) {
22851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22871.1Skamil
22881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22901.1Skamil
22911.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22921.1Skamil
22931.13Schristos		DPRINTF("Before exiting of the child process\n");
22941.1Skamil		_exit(exitval);
22951.1Skamil	}
22961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22971.1Skamil
22981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23001.1Skamil
23011.1Skamil	validate_status_stopped(status, sigval);
23021.1Skamil
23031.1Skamil	lookup_me = magic;
23041.1Skamil
23051.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23061.1Skamil	    child, getpid());
23071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23081.1Skamil
23091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23101.1Skamil	    "without signal to be sent\n");
23111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23121.1Skamil
23131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23151.1Skamil
23161.1Skamil	validate_status_exited(status, exitval);
23171.1Skamil
23181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23201.1Skamil}
23211.1Skamil
23221.1SkamilATF_TC(io_write_d3);
23231.1SkamilATF_TC_HEAD(io_write_d3, tc)
23241.1Skamil{
23251.1Skamil	atf_tc_set_md_var(tc, "descr",
23261.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
23271.1Skamil}
23281.1Skamil
23291.1SkamilATF_TC_BODY(io_write_d3, tc)
23301.1Skamil{
23311.1Skamil	const int exitval = 5;
23321.1Skamil	const int sigval = SIGSTOP;
23331.1Skamil	pid_t child, wpid;
23341.1Skamil	uint32_t lookup_me = 0;
23351.1Skamil	const uint32_t magic = 0xab127643;
23361.1Skamil	struct ptrace_io_desc io = {
23371.1Skamil		.piod_op = PIOD_WRITE_D,
23381.1Skamil		.piod_offs = &lookup_me,
23391.1Skamil		.piod_addr = &lookup_me,
23401.1Skamil		.piod_len = sizeof(lookup_me)
23411.1Skamil	};
23421.1Skamil#if defined(TWAIT_HAVE_STATUS)
23431.1Skamil	int status;
23441.1Skamil#endif
23451.1Skamil
23461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23481.1Skamil	if (child == 0) {
23491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23511.1Skamil
23521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23541.1Skamil
23551.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23561.1Skamil
23571.13Schristos		DPRINTF("Before exiting of the child process\n");
23581.1Skamil		_exit(exitval);
23591.1Skamil	}
23601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23611.1Skamil
23621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23641.1Skamil
23651.1Skamil	validate_status_stopped(status, sigval);
23661.1Skamil
23671.1Skamil	lookup_me = magic;
23681.1Skamil
23691.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23701.1Skamil	    child, getpid());
23711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23721.1Skamil
23731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23741.1Skamil	    "without signal to be sent\n");
23751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23761.1Skamil
23771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23791.1Skamil
23801.1Skamil	validate_status_exited(status, exitval);
23811.1Skamil
23821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23841.1Skamil}
23851.1Skamil
23861.1SkamilATF_TC(io_write_d4);
23871.1SkamilATF_TC_HEAD(io_write_d4, tc)
23881.1Skamil{
23891.1Skamil	atf_tc_set_md_var(tc, "descr",
23901.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
23911.1Skamil}
23921.1Skamil
23931.1SkamilATF_TC_BODY(io_write_d4, tc)
23941.1Skamil{
23951.1Skamil	const int exitval = 5;
23961.1Skamil	const int sigval = SIGSTOP;
23971.1Skamil	pid_t child, wpid;
23981.1Skamil	uint64_t lookup_me = 0;
23991.1Skamil	const uint64_t magic = 0xab12764376490123;
24001.1Skamil	struct ptrace_io_desc io = {
24011.1Skamil		.piod_op = PIOD_WRITE_D,
24021.1Skamil		.piod_offs = &lookup_me,
24031.1Skamil		.piod_addr = &lookup_me,
24041.1Skamil		.piod_len = sizeof(lookup_me)
24051.1Skamil	};
24061.1Skamil#if defined(TWAIT_HAVE_STATUS)
24071.1Skamil	int status;
24081.1Skamil#endif
24091.1Skamil
24101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24121.1Skamil	if (child == 0) {
24131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24151.1Skamil
24161.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24171.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24181.1Skamil
24191.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
24201.1Skamil
24211.13Schristos		DPRINTF("Before exiting of the child process\n");
24221.1Skamil		_exit(exitval);
24231.1Skamil	}
24241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24251.1Skamil
24261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24281.1Skamil
24291.1Skamil	validate_status_stopped(status, sigval);
24301.1Skamil
24311.1Skamil	lookup_me = magic;
24321.1Skamil
24331.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24341.1Skamil	    child, getpid());
24351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24361.1Skamil
24371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24381.1Skamil	    "without signal to be sent\n");
24391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24401.1Skamil
24411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24431.1Skamil
24441.1Skamil	validate_status_exited(status, exitval);
24451.1Skamil
24461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24481.1Skamil}
24491.1Skamil
24501.1SkamilATF_TC(io_read_auxv1);
24511.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
24521.1Skamil{
24531.1Skamil	atf_tc_set_md_var(tc, "descr",
24541.1Skamil	    "Verify PT_READ_AUXV called for tracee");
24551.1Skamil}
24561.1Skamil
24571.1SkamilATF_TC_BODY(io_read_auxv1, tc)
24581.1Skamil{
24591.1Skamil	const int exitval = 5;
24601.1Skamil	const int sigval = SIGSTOP;
24611.1Skamil	pid_t child, wpid;
24621.1Skamil#if defined(TWAIT_HAVE_STATUS)
24631.1Skamil	int status;
24641.1Skamil#endif
24651.1Skamil	AuxInfo ai[100], *aip;
24661.1Skamil	struct ptrace_io_desc io = {
24671.1Skamil		.piod_op = PIOD_READ_AUXV,
24681.1Skamil		.piod_offs = 0,
24691.1Skamil		.piod_addr = ai,
24701.1Skamil		.piod_len = sizeof(ai)
24711.1Skamil	};
24721.1Skamil
24731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24751.1Skamil	if (child == 0) {
24761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24781.1Skamil
24791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24811.1Skamil
24821.13Schristos		DPRINTF("Before exiting of the child process\n");
24831.1Skamil		_exit(exitval);
24841.1Skamil	}
24851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24861.1Skamil
24871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24891.1Skamil
24901.1Skamil	validate_status_stopped(status, sigval);
24911.1Skamil
24921.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
24931.1Skamil	    child, getpid());
24941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24951.1Skamil
24961.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
24971.1Skamil	ATF_REQUIRE(io.piod_len > 0);
24981.1Skamil
24991.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
25001.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
25011.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
25021.1Skamil
25031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25041.1Skamil	    "without signal to be sent\n");
25051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25061.1Skamil
25071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25091.1Skamil
25101.1Skamil	validate_status_exited(status, exitval);
25111.1Skamil
25121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25141.1Skamil}
25151.1Skamil
25161.1SkamilATF_TC(read_d1);
25171.1SkamilATF_TC_HEAD(read_d1, tc)
25181.1Skamil{
25191.1Skamil	atf_tc_set_md_var(tc, "descr",
25201.1Skamil	    "Verify PT_READ_D called once");
25211.1Skamil}
25221.1Skamil
25231.1SkamilATF_TC_BODY(read_d1, tc)
25241.1Skamil{
25251.1Skamil	const int exitval = 5;
25261.1Skamil	const int sigval = SIGSTOP;
25271.1Skamil	pid_t child, wpid;
25281.1Skamil	int lookup_me = 0;
25291.1Skamil	const int magic = (int)random();
25301.1Skamil#if defined(TWAIT_HAVE_STATUS)
25311.1Skamil	int status;
25321.1Skamil#endif
25331.1Skamil
25341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25361.1Skamil	if (child == 0) {
25371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25391.1Skamil
25401.1Skamil		lookup_me = magic;
25411.1Skamil
25421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25441.1Skamil
25451.13Schristos		DPRINTF("Before exiting of the child process\n");
25461.1Skamil		_exit(exitval);
25471.1Skamil	}
25481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25491.1Skamil
25501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25521.1Skamil
25531.1Skamil	validate_status_stopped(status, sigval);
25541.1Skamil
25551.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
25561.1Skamil	    child, getpid());
25571.1Skamil	errno = 0;
25581.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
25591.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25601.1Skamil
25611.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
25621.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
25631.1Skamil
25641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25651.1Skamil	    "without signal to be sent\n");
25661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25671.1Skamil
25681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25701.1Skamil
25711.1Skamil	validate_status_exited(status, exitval);
25721.1Skamil
25731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25751.1Skamil}
25761.1Skamil
25771.1SkamilATF_TC(read_d2);
25781.1SkamilATF_TC_HEAD(read_d2, tc)
25791.1Skamil{
25801.1Skamil	atf_tc_set_md_var(tc, "descr",
25811.1Skamil	    "Verify PT_READ_D called twice");
25821.1Skamil}
25831.1Skamil
25841.1SkamilATF_TC_BODY(read_d2, tc)
25851.1Skamil{
25861.1Skamil	const int exitval = 5;
25871.1Skamil	const int sigval = SIGSTOP;
25881.1Skamil	pid_t child, wpid;
25891.1Skamil	int lookup_me1 = 0;
25901.1Skamil	int lookup_me2 = 0;
25911.1Skamil	const int magic1 = (int)random();
25921.1Skamil	const int magic2 = (int)random();
25931.1Skamil#if defined(TWAIT_HAVE_STATUS)
25941.1Skamil	int status;
25951.1Skamil#endif
25961.1Skamil
25971.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25981.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25991.1Skamil	if (child == 0) {
26001.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26011.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26021.1Skamil
26031.1Skamil		lookup_me1 = magic1;
26041.1Skamil		lookup_me2 = magic2;
26051.1Skamil
26061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26081.1Skamil
26091.13Schristos		DPRINTF("Before exiting of the child process\n");
26101.1Skamil		_exit(exitval);
26111.1Skamil	}
26121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26131.1Skamil
26141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26161.1Skamil
26171.1Skamil	validate_status_stopped(status, sigval);
26181.1Skamil
26191.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26201.1Skamil	    child, getpid());
26211.1Skamil	errno = 0;
26221.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26231.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26241.1Skamil
26251.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26261.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26271.1Skamil
26281.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26291.1Skamil	    child, getpid());
26301.1Skamil	errno = 0;
26311.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26321.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26331.1Skamil
26341.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26351.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26361.1Skamil
26371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26381.1Skamil	    "without signal to be sent\n");
26391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26401.1Skamil
26411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26431.1Skamil
26441.1Skamil	validate_status_exited(status, exitval);
26451.1Skamil
26461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26481.1Skamil}
26491.1Skamil
26501.1SkamilATF_TC(read_d3);
26511.1SkamilATF_TC_HEAD(read_d3, tc)
26521.1Skamil{
26531.1Skamil	atf_tc_set_md_var(tc, "descr",
26541.1Skamil	    "Verify PT_READ_D called three times");
26551.1Skamil}
26561.1Skamil
26571.1SkamilATF_TC_BODY(read_d3, tc)
26581.1Skamil{
26591.1Skamil	const int exitval = 5;
26601.1Skamil	const int sigval = SIGSTOP;
26611.1Skamil	pid_t child, wpid;
26621.1Skamil	int lookup_me1 = 0;
26631.1Skamil	int lookup_me2 = 0;
26641.1Skamil	int lookup_me3 = 0;
26651.1Skamil	const int magic1 = (int)random();
26661.1Skamil	const int magic2 = (int)random();
26671.1Skamil	const int magic3 = (int)random();
26681.1Skamil#if defined(TWAIT_HAVE_STATUS)
26691.1Skamil	int status;
26701.1Skamil#endif
26711.1Skamil
26721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26741.1Skamil	if (child == 0) {
26751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26771.1Skamil
26781.1Skamil		lookup_me1 = magic1;
26791.1Skamil		lookup_me2 = magic2;
26801.1Skamil		lookup_me3 = magic3;
26811.1Skamil
26821.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26831.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26841.1Skamil
26851.13Schristos		DPRINTF("Before exiting of the child process\n");
26861.1Skamil		_exit(exitval);
26871.1Skamil	}
26881.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26891.1Skamil
26901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26921.1Skamil
26931.1Skamil	validate_status_stopped(status, sigval);
26941.1Skamil
26951.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26961.1Skamil	    child, getpid());
26971.1Skamil	errno = 0;
26981.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26991.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27001.1Skamil
27011.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27021.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27031.1Skamil
27041.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27051.1Skamil	    child, getpid());
27061.1Skamil	errno = 0;
27071.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27081.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27091.1Skamil
27101.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27111.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27121.1Skamil
27131.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27141.1Skamil	    child, getpid());
27151.1Skamil	errno = 0;
27161.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27171.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27181.1Skamil
27191.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27201.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27211.1Skamil
27221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27231.1Skamil	    "without signal to be sent\n");
27241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27251.1Skamil
27261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27281.1Skamil
27291.1Skamil	validate_status_exited(status, exitval);
27301.1Skamil
27311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27331.1Skamil}
27341.1Skamil
27351.1SkamilATF_TC(read_d4);
27361.1SkamilATF_TC_HEAD(read_d4, tc)
27371.1Skamil{
27381.1Skamil	atf_tc_set_md_var(tc, "descr",
27391.1Skamil	    "Verify PT_READ_D called four times");
27401.1Skamil}
27411.1Skamil
27421.1SkamilATF_TC_BODY(read_d4, tc)
27431.1Skamil{
27441.1Skamil	const int exitval = 5;
27451.1Skamil	const int sigval = SIGSTOP;
27461.1Skamil	pid_t child, wpid;
27471.1Skamil	int lookup_me1 = 0;
27481.1Skamil	int lookup_me2 = 0;
27491.1Skamil	int lookup_me3 = 0;
27501.1Skamil	int lookup_me4 = 0;
27511.1Skamil	const int magic1 = (int)random();
27521.1Skamil	const int magic2 = (int)random();
27531.1Skamil	const int magic3 = (int)random();
27541.1Skamil	const int magic4 = (int)random();
27551.1Skamil#if defined(TWAIT_HAVE_STATUS)
27561.1Skamil	int status;
27571.1Skamil#endif
27581.1Skamil
27591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27611.1Skamil	if (child == 0) {
27621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27641.1Skamil
27651.1Skamil		lookup_me1 = magic1;
27661.1Skamil		lookup_me2 = magic2;
27671.1Skamil		lookup_me3 = magic3;
27681.1Skamil		lookup_me4 = magic4;
27691.1Skamil
27701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27721.1Skamil
27731.13Schristos		DPRINTF("Before exiting of the child process\n");
27741.1Skamil		_exit(exitval);
27751.1Skamil	}
27761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27771.1Skamil
27781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27801.1Skamil
27811.1Skamil	validate_status_stopped(status, sigval);
27821.1Skamil
27831.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
27841.1Skamil	    child, getpid());
27851.1Skamil	errno = 0;
27861.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
27871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27881.1Skamil
27891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27901.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27911.1Skamil
27921.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27931.1Skamil	    child, getpid());
27941.1Skamil	errno = 0;
27951.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27961.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27971.1Skamil
27981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27991.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
28001.1Skamil
28011.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
28021.1Skamil	    child, getpid());
28031.1Skamil	errno = 0;
28041.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
28051.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
28061.1Skamil
28071.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
28081.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
28091.1Skamil
28101.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
28111.1Skamil	    child, getpid());
28121.1Skamil	errno = 0;
28131.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
28141.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
28151.1Skamil
28161.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
28171.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
28181.1Skamil
28191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28201.1Skamil	    "without signal to be sent\n");
28211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28221.1Skamil
28231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28251.1Skamil
28261.1Skamil	validate_status_exited(status, exitval);
28271.1Skamil
28281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28301.1Skamil}
28311.1Skamil
28321.1SkamilATF_TC(write_d1);
28331.1SkamilATF_TC_HEAD(write_d1, tc)
28341.1Skamil{
28351.1Skamil	atf_tc_set_md_var(tc, "descr",
28361.1Skamil	    "Verify PT_WRITE_D called once");
28371.1Skamil}
28381.1Skamil
28391.1SkamilATF_TC_BODY(write_d1, tc)
28401.1Skamil{
28411.1Skamil	const int exitval = 5;
28421.1Skamil	const int sigval = SIGSTOP;
28431.1Skamil	pid_t child, wpid;
28441.1Skamil	int lookup_me = 0;
28451.1Skamil	const int magic = (int)random();
28461.1Skamil#if defined(TWAIT_HAVE_STATUS)
28471.1Skamil	int status;
28481.1Skamil#endif
28491.1Skamil
28501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28521.1Skamil	if (child == 0) {
28531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28551.1Skamil
28561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28581.1Skamil
28591.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
28601.1Skamil
28611.13Schristos		DPRINTF("Before exiting of the child process\n");
28621.1Skamil		_exit(exitval);
28631.1Skamil	}
28641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28651.1Skamil
28661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28681.1Skamil
28691.1Skamil	validate_status_stopped(status, sigval);
28701.1Skamil
28711.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
28721.1Skamil	    child, getpid());
28731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
28741.1Skamil
28751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28761.1Skamil	    "without signal to be sent\n");
28771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28781.1Skamil
28791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28811.1Skamil
28821.1Skamil	validate_status_exited(status, exitval);
28831.1Skamil
28841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28861.1Skamil}
28871.1Skamil
28881.1SkamilATF_TC(write_d2);
28891.1SkamilATF_TC_HEAD(write_d2, tc)
28901.1Skamil{
28911.1Skamil	atf_tc_set_md_var(tc, "descr",
28921.1Skamil	    "Verify PT_WRITE_D called twice");
28931.1Skamil}
28941.1Skamil
28951.1SkamilATF_TC_BODY(write_d2, tc)
28961.1Skamil{
28971.1Skamil	const int exitval = 5;
28981.1Skamil	const int sigval = SIGSTOP;
28991.1Skamil	pid_t child, wpid;
29001.1Skamil	int lookup_me1 = 0;
29011.1Skamil	int lookup_me2 = 0;
29021.1Skamil	const int magic1 = (int)random();
29031.1Skamil	const int magic2 = (int)random();
29041.1Skamil#if defined(TWAIT_HAVE_STATUS)
29051.1Skamil	int status;
29061.1Skamil#endif
29071.1Skamil
29081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29101.1Skamil	if (child == 0) {
29111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29131.1Skamil
29141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29161.1Skamil
29171.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29181.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29191.1Skamil
29201.13Schristos		DPRINTF("Before exiting of the child process\n");
29211.1Skamil		_exit(exitval);
29221.1Skamil	}
29231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29241.1Skamil
29251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29271.1Skamil
29281.1Skamil	validate_status_stopped(status, sigval);
29291.1Skamil
29301.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29311.1Skamil	    child, getpid());
29321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29331.1Skamil
29341.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29351.1Skamil	    child, getpid());
29361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29371.1Skamil
29381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29391.1Skamil	    "without signal to be sent\n");
29401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29411.1Skamil
29421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29441.1Skamil
29451.1Skamil	validate_status_exited(status, exitval);
29461.1Skamil
29471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29481.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29491.1Skamil}
29501.1Skamil
29511.1SkamilATF_TC(write_d3);
29521.1SkamilATF_TC_HEAD(write_d3, tc)
29531.1Skamil{
29541.1Skamil	atf_tc_set_md_var(tc, "descr",
29551.1Skamil	    "Verify PT_WRITE_D called three times");
29561.1Skamil}
29571.1Skamil
29581.1SkamilATF_TC_BODY(write_d3, tc)
29591.1Skamil{
29601.1Skamil	const int exitval = 5;
29611.1Skamil	const int sigval = SIGSTOP;
29621.1Skamil	pid_t child, wpid;
29631.1Skamil	int lookup_me1 = 0;
29641.1Skamil	int lookup_me2 = 0;
29651.1Skamil	int lookup_me3 = 0;
29661.1Skamil	const int magic1 = (int)random();
29671.1Skamil	const int magic2 = (int)random();
29681.1Skamil	const int magic3 = (int)random();
29691.1Skamil#if defined(TWAIT_HAVE_STATUS)
29701.1Skamil	int status;
29711.1Skamil#endif
29721.1Skamil
29731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29751.1Skamil	if (child == 0) {
29761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29781.1Skamil
29791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29811.1Skamil
29821.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29831.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29841.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
29851.1Skamil
29861.13Schristos		DPRINTF("Before exiting of the child process\n");
29871.1Skamil		_exit(exitval);
29881.1Skamil	}
29891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29901.1Skamil
29911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29931.1Skamil
29941.1Skamil	validate_status_stopped(status, sigval);
29951.1Skamil
29961.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29971.1Skamil	    child, getpid());
29981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29991.1Skamil
30001.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30011.1Skamil	    child, getpid());
30021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30031.1Skamil
30041.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30051.1Skamil	    child, getpid());
30061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30071.1Skamil
30081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30091.1Skamil	    "without signal to be sent\n");
30101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30111.1Skamil
30121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30141.1Skamil
30151.1Skamil	validate_status_exited(status, exitval);
30161.1Skamil
30171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30191.1Skamil}
30201.1Skamil
30211.1SkamilATF_TC(write_d4);
30221.1SkamilATF_TC_HEAD(write_d4, tc)
30231.1Skamil{
30241.1Skamil	atf_tc_set_md_var(tc, "descr",
30251.1Skamil	    "Verify PT_WRITE_D called four times");
30261.1Skamil}
30271.1Skamil
30281.1SkamilATF_TC_BODY(write_d4, tc)
30291.1Skamil{
30301.1Skamil	const int exitval = 5;
30311.1Skamil	const int sigval = SIGSTOP;
30321.1Skamil	pid_t child, wpid;
30331.1Skamil	int lookup_me1 = 0;
30341.1Skamil	int lookup_me2 = 0;
30351.1Skamil	int lookup_me3 = 0;
30361.1Skamil	int lookup_me4 = 0;
30371.1Skamil	const int magic1 = (int)random();
30381.1Skamil	const int magic2 = (int)random();
30391.1Skamil	const int magic3 = (int)random();
30401.1Skamil	const int magic4 = (int)random();
30411.1Skamil#if defined(TWAIT_HAVE_STATUS)
30421.1Skamil	int status;
30431.1Skamil#endif
30441.1Skamil
30451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30471.1Skamil	if (child == 0) {
30481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30501.1Skamil
30511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30531.1Skamil
30541.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
30551.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
30561.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
30571.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
30581.1Skamil
30591.13Schristos		DPRINTF("Before exiting of the child process\n");
30601.1Skamil		_exit(exitval);
30611.1Skamil	}
30621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30631.1Skamil
30641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30661.1Skamil
30671.1Skamil	validate_status_stopped(status, sigval);
30681.1Skamil
30691.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
30701.1Skamil	    child, getpid());
30711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
30721.1Skamil
30731.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30741.1Skamil	    child, getpid());
30751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30761.1Skamil
30771.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30781.1Skamil	    child, getpid());
30791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30801.1Skamil
30811.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
30821.1Skamil	    child, getpid());
30831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
30841.1Skamil
30851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30861.1Skamil	    "without signal to be sent\n");
30871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30881.1Skamil
30891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30911.1Skamil
30921.1Skamil	validate_status_exited(status, exitval);
30931.1Skamil
30941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30961.1Skamil}
30971.1Skamil
30981.1SkamilATF_TC(io_read_d_write_d_handshake1);
30991.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
31001.1Skamil{
31011.1Skamil	atf_tc_set_md_var(tc, "descr",
31021.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
31031.1Skamil}
31041.1Skamil
31051.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
31061.1Skamil{
31071.1Skamil	const int exitval = 5;
31081.1Skamil	const int sigval = SIGSTOP;
31091.1Skamil	pid_t child, wpid;
31101.1Skamil	uint8_t lookup_me_fromtracee = 0;
31111.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31121.1Skamil	uint8_t lookup_me_totracee = 0;
31131.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31141.1Skamil	struct ptrace_io_desc io_fromtracee = {
31151.1Skamil		.piod_op = PIOD_READ_D,
31161.1Skamil		.piod_offs = &lookup_me_fromtracee,
31171.1Skamil		.piod_addr = &lookup_me_fromtracee,
31181.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31191.1Skamil	};
31201.1Skamil	struct ptrace_io_desc io_totracee = {
31211.1Skamil		.piod_op = PIOD_WRITE_D,
31221.1Skamil		.piod_offs = &lookup_me_totracee,
31231.1Skamil		.piod_addr = &lookup_me_totracee,
31241.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31251.1Skamil	};
31261.1Skamil#if defined(TWAIT_HAVE_STATUS)
31271.1Skamil	int status;
31281.1Skamil#endif
31291.1Skamil
31301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31321.1Skamil	if (child == 0) {
31331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31351.1Skamil
31361.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31371.1Skamil
31381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31401.1Skamil
31411.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31421.1Skamil
31431.13Schristos		DPRINTF("Before exiting of the child process\n");
31441.1Skamil		_exit(exitval);
31451.1Skamil	}
31461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31471.1Skamil
31481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31501.1Skamil
31511.1Skamil	validate_status_stopped(status, sigval);
31521.1Skamil
31531.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31541.1Skamil	    child, getpid());
31551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
31561.1Skamil
31571.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31581.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
31591.1Skamil	    magic_fromtracee);
31601.1Skamil
31611.1Skamil	lookup_me_totracee = magic_totracee;
31621.1Skamil
31631.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
31641.1Skamil	    child, getpid());
31651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
31661.1Skamil
31671.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
31681.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
31691.1Skamil	    magic_totracee);
31701.1Skamil
31711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31721.1Skamil	    "without signal to be sent\n");
31731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31741.1Skamil
31751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31771.1Skamil
31781.1Skamil	validate_status_exited(status, exitval);
31791.1Skamil
31801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31811.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31821.1Skamil}
31831.1Skamil
31841.1SkamilATF_TC(io_read_d_write_d_handshake2);
31851.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
31861.1Skamil{
31871.1Skamil	atf_tc_set_md_var(tc, "descr",
31881.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
31891.1Skamil}
31901.1Skamil
31911.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
31921.1Skamil{
31931.1Skamil	const int exitval = 5;
31941.1Skamil	const int sigval = SIGSTOP;
31951.1Skamil	pid_t child, wpid;
31961.1Skamil	uint8_t lookup_me_fromtracee = 0;
31971.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31981.1Skamil	uint8_t lookup_me_totracee = 0;
31991.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
32001.1Skamil	struct ptrace_io_desc io_fromtracee = {
32011.1Skamil		.piod_op = PIOD_READ_D,
32021.1Skamil		.piod_offs = &lookup_me_fromtracee,
32031.1Skamil		.piod_addr = &lookup_me_fromtracee,
32041.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
32051.1Skamil	};
32061.1Skamil	struct ptrace_io_desc io_totracee = {
32071.1Skamil		.piod_op = PIOD_WRITE_D,
32081.1Skamil		.piod_offs = &lookup_me_totracee,
32091.1Skamil		.piod_addr = &lookup_me_totracee,
32101.1Skamil		.piod_len = sizeof(lookup_me_totracee)
32111.1Skamil	};
32121.1Skamil#if defined(TWAIT_HAVE_STATUS)
32131.1Skamil	int status;
32141.1Skamil#endif
32151.1Skamil
32161.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32171.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32181.1Skamil	if (child == 0) {
32191.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32201.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32211.1Skamil
32221.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32231.1Skamil
32241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32261.1Skamil
32271.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32281.1Skamil
32291.13Schristos		DPRINTF("Before exiting of the child process\n");
32301.1Skamil		_exit(exitval);
32311.1Skamil	}
32321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32331.1Skamil
32341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32361.1Skamil
32371.1Skamil	validate_status_stopped(status, sigval);
32381.1Skamil
32391.1Skamil	lookup_me_totracee = magic_totracee;
32401.1Skamil
32411.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
32421.1Skamil	    child, getpid());
32431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
32441.1Skamil
32451.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
32461.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
32471.1Skamil	    magic_totracee);
32481.1Skamil
32491.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32501.1Skamil	    child, getpid());
32511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
32521.1Skamil
32531.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32541.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
32551.1Skamil	    magic_fromtracee);
32561.1Skamil
32571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32581.1Skamil	    "without signal to be sent\n");
32591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32601.1Skamil
32611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32631.1Skamil
32641.1Skamil	validate_status_exited(status, exitval);
32651.1Skamil
32661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32681.1Skamil}
32691.1Skamil
32701.1SkamilATF_TC(read_d_write_d_handshake1);
32711.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
32721.1Skamil{
32731.1Skamil	atf_tc_set_md_var(tc, "descr",
32741.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
32751.1Skamil}
32761.1Skamil
32771.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
32781.1Skamil{
32791.1Skamil	const int exitval = 5;
32801.1Skamil	const int sigval = SIGSTOP;
32811.1Skamil	pid_t child, wpid;
32821.1Skamil	int lookup_me_fromtracee = 0;
32831.1Skamil	const int magic_fromtracee = (int)random();
32841.1Skamil	int lookup_me_totracee = 0;
32851.1Skamil	const int magic_totracee = (int)random();
32861.1Skamil#if defined(TWAIT_HAVE_STATUS)
32871.1Skamil	int status;
32881.1Skamil#endif
32891.1Skamil
32901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32921.1Skamil	if (child == 0) {
32931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32951.1Skamil
32961.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32971.1Skamil
32981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33001.1Skamil
33011.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33021.1Skamil
33031.13Schristos		DPRINTF("Before exiting of the child process\n");
33041.1Skamil		_exit(exitval);
33051.1Skamil	}
33061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33071.1Skamil
33081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33101.1Skamil
33111.1Skamil	validate_status_stopped(status, sigval);
33121.1Skamil
33131.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33141.1Skamil	    child, getpid());
33151.1Skamil	errno = 0;
33161.1Skamil	lookup_me_fromtracee =
33171.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33181.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33191.1Skamil
33201.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33211.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33221.1Skamil	    magic_fromtracee);
33231.1Skamil
33241.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33251.1Skamil	    child, getpid());
33261.1Skamil	ATF_REQUIRE
33271.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33281.1Skamil	    != -1);
33291.1Skamil
33301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33311.1Skamil	    "without signal to be sent\n");
33321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33331.1Skamil
33341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33361.1Skamil
33371.1Skamil	validate_status_exited(status, exitval);
33381.1Skamil
33391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33411.1Skamil}
33421.1Skamil
33431.1SkamilATF_TC(read_d_write_d_handshake2);
33441.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
33451.1Skamil{
33461.1Skamil	atf_tc_set_md_var(tc, "descr",
33471.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
33481.1Skamil}
33491.1Skamil
33501.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
33511.1Skamil{
33521.1Skamil	const int exitval = 5;
33531.1Skamil	const int sigval = SIGSTOP;
33541.1Skamil	pid_t child, wpid;
33551.1Skamil	int lookup_me_fromtracee = 0;
33561.1Skamil	const int magic_fromtracee = (int)random();
33571.1Skamil	int lookup_me_totracee = 0;
33581.1Skamil	const int magic_totracee = (int)random();
33591.1Skamil#if defined(TWAIT_HAVE_STATUS)
33601.1Skamil	int status;
33611.1Skamil#endif
33621.1Skamil
33631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33651.1Skamil	if (child == 0) {
33661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33681.1Skamil
33691.1Skamil		lookup_me_fromtracee = magic_fromtracee;
33701.1Skamil
33711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33731.1Skamil
33741.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33751.1Skamil
33761.13Schristos		DPRINTF("Before exiting of the child process\n");
33771.1Skamil		_exit(exitval);
33781.1Skamil	}
33791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33801.1Skamil
33811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33831.1Skamil
33841.1Skamil	validate_status_stopped(status, sigval);
33851.1Skamil
33861.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33871.1Skamil	    child, getpid());
33881.1Skamil	ATF_REQUIRE
33891.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33901.1Skamil	    != -1);
33911.1Skamil
33921.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33931.1Skamil	    child, getpid());
33941.1Skamil	errno = 0;
33951.1Skamil	lookup_me_fromtracee =
33961.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33971.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33981.1Skamil
33991.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
34001.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
34011.1Skamil	    magic_fromtracee);
34021.1Skamil
34031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34041.1Skamil	    "without signal to be sent\n");
34051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34061.1Skamil
34071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34091.1Skamil
34101.1Skamil	validate_status_exited(status, exitval);
34111.1Skamil
34121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34141.1Skamil}
34151.1Skamil
34161.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
34171.1Skamilstatic int __used
34181.1Skamildummy_fn1(int a, int b, int c, int d)
34191.1Skamil{
34201.1Skamil
34211.1Skamil	a *= 1;
34221.1Skamil	b += 2;
34231.1Skamil	c -= 3;
34241.1Skamil	d /= 4;
34251.1Skamil
34261.1Skamil	return a + b * c - d;
34271.1Skamil}
34281.1Skamil
34291.1Skamilstatic int __used
34301.1Skamildummy_fn2(int a, int b, int c, int d)
34311.1Skamil{
34321.1Skamil
34331.1Skamil	a *= 4;
34341.1Skamil	b += 3;
34351.1Skamil	c -= 2;
34361.1Skamil	d /= 1;
34371.1Skamil
34381.1Skamil	return a + b * c - d;
34391.1Skamil}
34401.1Skamil
34411.1Skamilstatic int __used
34421.1Skamildummy_fn3(int a, int b, int c, int d)
34431.1Skamil{
34441.1Skamil
34451.1Skamil	a *= 10;
34461.1Skamil	b += 20;
34471.1Skamil	c -= 30;
34481.1Skamil	d /= 40;
34491.1Skamil
34501.1Skamil	return a + b * c - d;
34511.1Skamil}
34521.1Skamil
34531.1Skamilstatic int __used
34541.1Skamildummy_fn4(int a, int b, int c, int d)
34551.1Skamil{
34561.1Skamil
34571.1Skamil	a *= 40;
34581.1Skamil	b += 30;
34591.1Skamil	c -= 20;
34601.1Skamil	d /= 10;
34611.1Skamil
34621.1Skamil	return a + b * c - d;
34631.1Skamil}
34641.1Skamil
34651.1SkamilATF_TC(io_read_i1);
34661.1SkamilATF_TC_HEAD(io_read_i1, tc)
34671.1Skamil{
34681.1Skamil	atf_tc_set_md_var(tc, "descr",
34691.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
34701.1Skamil}
34711.1Skamil
34721.1SkamilATF_TC_BODY(io_read_i1, tc)
34731.1Skamil{
34741.1Skamil	const int exitval = 5;
34751.1Skamil	const int sigval = SIGSTOP;
34761.1Skamil	pid_t child, wpid;
34771.1Skamil	uint8_t lookup_me = 0;
34781.1Skamil	uint8_t magic;
34791.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34801.1Skamil	struct ptrace_io_desc io = {
34811.1Skamil		.piod_op = PIOD_READ_I,
34821.1Skamil		.piod_offs = dummy_fn1,
34831.1Skamil		.piod_addr = &lookup_me,
34841.1Skamil		.piod_len = sizeof(lookup_me)
34851.1Skamil	};
34861.1Skamil#if defined(TWAIT_HAVE_STATUS)
34871.1Skamil	int status;
34881.1Skamil#endif
34891.1Skamil
34901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34921.1Skamil	if (child == 0) {
34931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34951.1Skamil
34961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34981.1Skamil
34991.13Schristos		DPRINTF("Before exiting of the child process\n");
35001.1Skamil		_exit(exitval);
35011.1Skamil	}
35021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35031.1Skamil
35041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35061.1Skamil
35071.1Skamil	validate_status_stopped(status, sigval);
35081.1Skamil
35091.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35101.1Skamil	    child, getpid());
35111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35121.1Skamil
35131.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35141.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
35151.1Skamil
35161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35171.1Skamil	    "without signal to be sent\n");
35181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35191.1Skamil
35201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35221.1Skamil
35231.1Skamil	validate_status_exited(status, exitval);
35241.1Skamil
35251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35271.1Skamil}
35281.1Skamil
35291.1SkamilATF_TC(io_read_i2);
35301.1SkamilATF_TC_HEAD(io_read_i2, tc)
35311.1Skamil{
35321.1Skamil	atf_tc_set_md_var(tc, "descr",
35331.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
35341.1Skamil}
35351.1Skamil
35361.1SkamilATF_TC_BODY(io_read_i2, tc)
35371.1Skamil{
35381.1Skamil	const int exitval = 5;
35391.1Skamil	const int sigval = SIGSTOP;
35401.1Skamil	pid_t child, wpid;
35411.1Skamil	uint16_t lookup_me = 0;
35421.1Skamil	uint16_t magic;
35431.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35441.1Skamil	struct ptrace_io_desc io = {
35451.1Skamil		.piod_op = PIOD_READ_I,
35461.1Skamil		.piod_offs = dummy_fn1,
35471.1Skamil		.piod_addr = &lookup_me,
35481.1Skamil		.piod_len = sizeof(lookup_me)
35491.1Skamil	};
35501.1Skamil#if defined(TWAIT_HAVE_STATUS)
35511.1Skamil	int status;
35521.1Skamil#endif
35531.1Skamil
35541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35561.1Skamil	if (child == 0) {
35571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35591.1Skamil
35601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35621.1Skamil
35631.13Schristos		DPRINTF("Before exiting of the child process\n");
35641.1Skamil		_exit(exitval);
35651.1Skamil	}
35661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35671.1Skamil
35681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35701.1Skamil
35711.1Skamil	validate_status_stopped(status, sigval);
35721.1Skamil
35731.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35741.1Skamil	    child, getpid());
35751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35761.1Skamil
35771.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35781.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
35791.1Skamil
35801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35811.1Skamil	    "without signal to be sent\n");
35821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35831.1Skamil
35841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35861.1Skamil
35871.1Skamil	validate_status_exited(status, exitval);
35881.1Skamil
35891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35911.1Skamil}
35921.1Skamil
35931.1SkamilATF_TC(io_read_i3);
35941.1SkamilATF_TC_HEAD(io_read_i3, tc)
35951.1Skamil{
35961.1Skamil	atf_tc_set_md_var(tc, "descr",
35971.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
35981.1Skamil}
35991.1Skamil
36001.1SkamilATF_TC_BODY(io_read_i3, tc)
36011.1Skamil{
36021.1Skamil	const int exitval = 5;
36031.1Skamil	const int sigval = SIGSTOP;
36041.1Skamil	pid_t child, wpid;
36051.1Skamil	uint32_t lookup_me = 0;
36061.1Skamil	uint32_t magic;
36071.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36081.1Skamil	struct ptrace_io_desc io = {
36091.1Skamil		.piod_op = PIOD_READ_I,
36101.1Skamil		.piod_offs = dummy_fn1,
36111.1Skamil		.piod_addr = &lookup_me,
36121.1Skamil		.piod_len = sizeof(lookup_me)
36131.1Skamil	};
36141.1Skamil#if defined(TWAIT_HAVE_STATUS)
36151.1Skamil	int status;
36161.1Skamil#endif
36171.1Skamil
36181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36201.1Skamil	if (child == 0) {
36211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36231.1Skamil
36241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36261.1Skamil
36271.13Schristos		DPRINTF("Before exiting of the child process\n");
36281.1Skamil		_exit(exitval);
36291.1Skamil	}
36301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36311.1Skamil
36321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36341.1Skamil
36351.1Skamil	validate_status_stopped(status, sigval);
36361.1Skamil
36371.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36381.1Skamil	    child, getpid());
36391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36401.1Skamil
36411.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36421.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
36431.1Skamil
36441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36451.1Skamil	    "without signal to be sent\n");
36461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36471.1Skamil
36481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36501.1Skamil
36511.1Skamil	validate_status_exited(status, exitval);
36521.1Skamil
36531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36551.1Skamil}
36561.1Skamil
36571.1SkamilATF_TC(io_read_i4);
36581.1SkamilATF_TC_HEAD(io_read_i4, tc)
36591.1Skamil{
36601.1Skamil	atf_tc_set_md_var(tc, "descr",
36611.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
36621.1Skamil}
36631.1Skamil
36641.1SkamilATF_TC_BODY(io_read_i4, tc)
36651.1Skamil{
36661.1Skamil	const int exitval = 5;
36671.1Skamil	const int sigval = SIGSTOP;
36681.1Skamil	pid_t child, wpid;
36691.1Skamil	uint64_t lookup_me = 0;
36701.1Skamil	uint64_t magic;
36711.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36721.1Skamil	struct ptrace_io_desc io = {
36731.1Skamil		.piod_op = PIOD_READ_I,
36741.1Skamil		.piod_offs = dummy_fn1,
36751.1Skamil		.piod_addr = &lookup_me,
36761.1Skamil		.piod_len = sizeof(lookup_me)
36771.1Skamil	};
36781.1Skamil#if defined(TWAIT_HAVE_STATUS)
36791.1Skamil	int status;
36801.1Skamil#endif
36811.1Skamil
36821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36841.1Skamil	if (child == 0) {
36851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36871.1Skamil
36881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36901.1Skamil
36911.13Schristos		DPRINTF("Before exiting of the child process\n");
36921.1Skamil		_exit(exitval);
36931.1Skamil	}
36941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36951.1Skamil
36961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36981.1Skamil
36991.1Skamil	validate_status_stopped(status, sigval);
37001.1Skamil
37011.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37021.1Skamil	    child, getpid());
37031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
37041.1Skamil
37051.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37061.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
37071.1Skamil
37081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37091.1Skamil	    "without signal to be sent\n");
37101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37111.1Skamil
37121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37141.1Skamil
37151.1Skamil	validate_status_exited(status, exitval);
37161.1Skamil
37171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37191.1Skamil}
37201.1Skamil
37211.1SkamilATF_TC(read_i1);
37221.1SkamilATF_TC_HEAD(read_i1, tc)
37231.1Skamil{
37241.1Skamil	atf_tc_set_md_var(tc, "descr",
37251.1Skamil	    "Verify PT_READ_I called once");
37261.1Skamil}
37271.1Skamil
37281.1SkamilATF_TC_BODY(read_i1, tc)
37291.1Skamil{
37301.1Skamil	const int exitval = 5;
37311.1Skamil	const int sigval = SIGSTOP;
37321.1Skamil	pid_t child, wpid;
37331.1Skamil	int lookup_me = 0;
37341.1Skamil	int magic;
37351.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
37361.1Skamil#if defined(TWAIT_HAVE_STATUS)
37371.1Skamil	int status;
37381.1Skamil#endif
37391.1Skamil
37401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37421.1Skamil	if (child == 0) {
37431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37451.1Skamil
37461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37481.1Skamil
37491.13Schristos		DPRINTF("Before exiting of the child process\n");
37501.1Skamil		_exit(exitval);
37511.1Skamil	}
37521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37531.1Skamil
37541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37561.1Skamil
37571.1Skamil	validate_status_stopped(status, sigval);
37581.1Skamil
37591.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37601.1Skamil	    child, getpid());
37611.1Skamil	errno = 0;
37621.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
37631.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37641.1Skamil
37651.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37661.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
37671.1Skamil
37681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37691.1Skamil	    "without signal to be sent\n");
37701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37711.1Skamil
37721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37741.1Skamil
37751.1Skamil	validate_status_exited(status, exitval);
37761.1Skamil
37771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37791.1Skamil}
37801.1Skamil
37811.1SkamilATF_TC(read_i2);
37821.1SkamilATF_TC_HEAD(read_i2, tc)
37831.1Skamil{
37841.1Skamil	atf_tc_set_md_var(tc, "descr",
37851.1Skamil	    "Verify PT_READ_I called twice");
37861.1Skamil}
37871.1Skamil
37881.1SkamilATF_TC_BODY(read_i2, tc)
37891.1Skamil{
37901.1Skamil	const int exitval = 5;
37911.1Skamil	const int sigval = SIGSTOP;
37921.1Skamil	pid_t child, wpid;
37931.1Skamil	int lookup_me1 = 0;
37941.1Skamil	int lookup_me2 = 0;
37951.1Skamil	int magic1;
37961.1Skamil	int magic2;
37971.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37981.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37991.1Skamil#if defined(TWAIT_HAVE_STATUS)
38001.1Skamil	int status;
38011.1Skamil#endif
38021.1Skamil
38031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38051.1Skamil	if (child == 0) {
38061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38081.1Skamil
38091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38111.1Skamil
38121.13Schristos		DPRINTF("Before exiting of the child process\n");
38131.1Skamil		_exit(exitval);
38141.1Skamil	}
38151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38161.1Skamil
38171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38191.1Skamil
38201.1Skamil	validate_status_stopped(status, sigval);
38211.1Skamil
38221.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38231.1Skamil	    child, getpid());
38241.1Skamil	errno = 0;
38251.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38261.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38271.1Skamil
38281.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38291.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38301.1Skamil
38311.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38321.1Skamil	    child, getpid());
38331.1Skamil	errno = 0;
38341.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38351.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38361.1Skamil
38371.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38381.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38391.1Skamil
38401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38411.1Skamil	    "without signal to be sent\n");
38421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38431.1Skamil
38441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38461.1Skamil
38471.1Skamil	validate_status_exited(status, exitval);
38481.1Skamil
38491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38511.1Skamil}
38521.1Skamil
38531.1SkamilATF_TC(read_i3);
38541.1SkamilATF_TC_HEAD(read_i3, tc)
38551.1Skamil{
38561.1Skamil	atf_tc_set_md_var(tc, "descr",
38571.1Skamil	    "Verify PT_READ_I called three times");
38581.1Skamil}
38591.1Skamil
38601.1SkamilATF_TC_BODY(read_i3, tc)
38611.1Skamil{
38621.1Skamil	const int exitval = 5;
38631.1Skamil	const int sigval = SIGSTOP;
38641.1Skamil	pid_t child, wpid;
38651.1Skamil	int lookup_me1 = 0;
38661.1Skamil	int lookup_me2 = 0;
38671.1Skamil	int lookup_me3 = 0;
38681.1Skamil	int magic1;
38691.1Skamil	int magic2;
38701.1Skamil	int magic3;
38711.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
38721.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
38731.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
38741.1Skamil#if defined(TWAIT_HAVE_STATUS)
38751.1Skamil	int status;
38761.1Skamil#endif
38771.1Skamil
38781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38801.1Skamil	if (child == 0) {
38811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38831.1Skamil
38841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38861.1Skamil
38871.13Schristos		DPRINTF("Before exiting of the child process\n");
38881.1Skamil		_exit(exitval);
38891.1Skamil	}
38901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38911.1Skamil
38921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38941.1Skamil
38951.1Skamil	validate_status_stopped(status, sigval);
38961.1Skamil
38971.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38981.1Skamil	    child, getpid());
38991.1Skamil	errno = 0;
39001.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39011.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39021.1Skamil
39031.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39041.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39051.1Skamil
39061.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39071.1Skamil	    child, getpid());
39081.1Skamil	errno = 0;
39091.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39101.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39111.1Skamil
39121.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39131.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39141.1Skamil
39151.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39161.1Skamil	    child, getpid());
39171.1Skamil	errno = 0;
39181.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39191.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39201.1Skamil
39211.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39221.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39231.1Skamil
39241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39251.1Skamil	    "without signal to be sent\n");
39261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39271.1Skamil
39281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39301.1Skamil
39311.1Skamil	validate_status_exited(status, exitval);
39321.1Skamil
39331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39351.1Skamil}
39361.1Skamil
39371.1SkamilATF_TC(read_i4);
39381.1SkamilATF_TC_HEAD(read_i4, tc)
39391.1Skamil{
39401.1Skamil	atf_tc_set_md_var(tc, "descr",
39411.1Skamil	    "Verify PT_READ_I called four times");
39421.1Skamil}
39431.1Skamil
39441.1SkamilATF_TC_BODY(read_i4, tc)
39451.1Skamil{
39461.1Skamil	const int exitval = 5;
39471.1Skamil	const int sigval = SIGSTOP;
39481.1Skamil	pid_t child, wpid;
39491.1Skamil	int lookup_me1 = 0;
39501.1Skamil	int lookup_me2 = 0;
39511.1Skamil	int lookup_me3 = 0;
39521.1Skamil	int lookup_me4 = 0;
39531.1Skamil	int magic1;
39541.1Skamil	int magic2;
39551.1Skamil	int magic3;
39561.1Skamil	int magic4;
39571.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
39581.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
39591.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
39601.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
39611.1Skamil#if defined(TWAIT_HAVE_STATUS)
39621.1Skamil	int status;
39631.1Skamil#endif
39641.1Skamil
39651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39671.1Skamil	if (child == 0) {
39681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39701.1Skamil
39711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39731.1Skamil
39741.13Schristos		DPRINTF("Before exiting of the child process\n");
39751.1Skamil		_exit(exitval);
39761.1Skamil	}
39771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39781.1Skamil
39791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39811.1Skamil
39821.1Skamil	validate_status_stopped(status, sigval);
39831.1Skamil
39841.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
39851.1Skamil	    child, getpid());
39861.1Skamil	errno = 0;
39871.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39881.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39891.1Skamil
39901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39911.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39921.1Skamil
39931.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39941.1Skamil	    child, getpid());
39951.1Skamil	errno = 0;
39961.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39971.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39981.1Skamil
39991.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
40001.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
40011.1Skamil
40021.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
40031.1Skamil	    child, getpid());
40041.1Skamil	errno = 0;
40051.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
40061.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
40071.1Skamil
40081.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
40091.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
40101.1Skamil
40111.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
40121.1Skamil	    child, getpid());
40131.1Skamil	errno = 0;
40141.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
40151.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
40161.1Skamil
40171.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
40181.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
40191.1Skamil
40201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40211.1Skamil	    "without signal to be sent\n");
40221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40231.1Skamil
40241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40261.1Skamil
40271.1Skamil	validate_status_exited(status, exitval);
40281.1Skamil
40291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40311.1Skamil}
40321.1Skamil
40331.1Skamil#if defined(HAVE_GPREGS)
40341.1SkamilATF_TC(regs1);
40351.1SkamilATF_TC_HEAD(regs1, tc)
40361.1Skamil{
40371.1Skamil	atf_tc_set_md_var(tc, "descr",
40381.1Skamil	    "Verify plain PT_GETREGS call without further steps");
40391.1Skamil}
40401.1Skamil
40411.1SkamilATF_TC_BODY(regs1, tc)
40421.1Skamil{
40431.1Skamil	const int exitval = 5;
40441.1Skamil	const int sigval = SIGSTOP;
40451.1Skamil	pid_t child, wpid;
40461.1Skamil#if defined(TWAIT_HAVE_STATUS)
40471.1Skamil	int status;
40481.1Skamil#endif
40491.1Skamil	struct reg r;
40501.1Skamil
40511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40531.1Skamil	if (child == 0) {
40541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40561.1Skamil
40571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40591.1Skamil
40601.13Schristos		DPRINTF("Before exiting of the child process\n");
40611.1Skamil		_exit(exitval);
40621.1Skamil	}
40631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40641.1Skamil
40651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40671.1Skamil
40681.1Skamil	validate_status_stopped(status, sigval);
40691.1Skamil
40701.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40721.1Skamil
40731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40741.1Skamil	    "without signal to be sent\n");
40751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40761.1Skamil
40771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40791.1Skamil
40801.1Skamil	validate_status_exited(status, exitval);
40811.1Skamil
40821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40841.1Skamil}
40851.1Skamil#endif
40861.1Skamil
40871.1Skamil#if defined(HAVE_GPREGS)
40881.1SkamilATF_TC(regs2);
40891.1SkamilATF_TC_HEAD(regs2, tc)
40901.1Skamil{
40911.1Skamil	atf_tc_set_md_var(tc, "descr",
40921.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
40931.1Skamil}
40941.1Skamil
40951.1SkamilATF_TC_BODY(regs2, tc)
40961.1Skamil{
40971.1Skamil	const int exitval = 5;
40981.1Skamil	const int sigval = SIGSTOP;
40991.1Skamil	pid_t child, wpid;
41001.1Skamil#if defined(TWAIT_HAVE_STATUS)
41011.1Skamil	int status;
41021.1Skamil#endif
41031.1Skamil	struct reg r;
41041.1Skamil
41051.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41061.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41071.1Skamil	if (child == 0) {
41081.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41091.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41101.1Skamil
41111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41131.1Skamil
41141.13Schristos		DPRINTF("Before exiting of the child process\n");
41151.1Skamil		_exit(exitval);
41161.1Skamil	}
41171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41181.1Skamil
41191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41211.1Skamil
41221.1Skamil	validate_status_stopped(status, sigval);
41231.1Skamil
41241.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41261.1Skamil
41271.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
41281.1Skamil
41291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41301.1Skamil	    "without signal to be sent\n");
41311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41321.1Skamil
41331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41351.1Skamil
41361.1Skamil	validate_status_exited(status, exitval);
41371.1Skamil
41381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41401.1Skamil}
41411.1Skamil#endif
41421.1Skamil
41431.1Skamil#if defined(HAVE_GPREGS)
41441.1SkamilATF_TC(regs3);
41451.1SkamilATF_TC_HEAD(regs3, tc)
41461.1Skamil{
41471.1Skamil	atf_tc_set_md_var(tc, "descr",
41481.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
41491.1Skamil}
41501.1Skamil
41511.1SkamilATF_TC_BODY(regs3, tc)
41521.1Skamil{
41531.1Skamil	const int exitval = 5;
41541.1Skamil	const int sigval = SIGSTOP;
41551.1Skamil	pid_t child, wpid;
41561.1Skamil#if defined(TWAIT_HAVE_STATUS)
41571.1Skamil	int status;
41581.1Skamil#endif
41591.1Skamil	struct reg r;
41601.1Skamil
41611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41631.1Skamil	if (child == 0) {
41641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41661.1Skamil
41671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41691.1Skamil
41701.13Schristos		DPRINTF("Before exiting of the child process\n");
41711.1Skamil		_exit(exitval);
41721.1Skamil	}
41731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41741.1Skamil
41751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41771.1Skamil
41781.1Skamil	validate_status_stopped(status, sigval);
41791.1Skamil
41801.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41821.1Skamil
41831.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
41841.1Skamil
41851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41861.1Skamil	    "without signal to be sent\n");
41871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41881.1Skamil
41891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41911.1Skamil
41921.1Skamil	validate_status_exited(status, exitval);
41931.1Skamil
41941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41961.1Skamil}
41971.1Skamil#endif
41981.1Skamil
41991.1Skamil#if defined(HAVE_GPREGS)
42001.1SkamilATF_TC(regs4);
42011.1SkamilATF_TC_HEAD(regs4, tc)
42021.1Skamil{
42031.1Skamil	atf_tc_set_md_var(tc, "descr",
42041.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
42051.1Skamil}
42061.1Skamil
42071.1SkamilATF_TC_BODY(regs4, tc)
42081.1Skamil{
42091.1Skamil	const int exitval = 5;
42101.1Skamil	const int sigval = SIGSTOP;
42111.1Skamil	pid_t child, wpid;
42121.1Skamil#if defined(TWAIT_HAVE_STATUS)
42131.1Skamil	int status;
42141.1Skamil#endif
42151.1Skamil	struct reg r;
42161.1Skamil
42171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42191.1Skamil	if (child == 0) {
42201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42221.1Skamil
42231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42251.1Skamil
42261.13Schristos		DPRINTF("Before exiting of the child process\n");
42271.1Skamil		_exit(exitval);
42281.1Skamil	}
42291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42301.1Skamil
42311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42331.1Skamil
42341.1Skamil	validate_status_stopped(status, sigval);
42351.1Skamil
42361.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42381.1Skamil
42391.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
42401.1Skamil
42411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42421.1Skamil	    "without signal to be sent\n");
42431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42441.1Skamil
42451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42471.1Skamil
42481.1Skamil	validate_status_exited(status, exitval);
42491.1Skamil
42501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42521.1Skamil}
42531.1Skamil#endif
42541.1Skamil
42551.1Skamil#if defined(HAVE_GPREGS)
42561.1SkamilATF_TC(regs5);
42571.1SkamilATF_TC_HEAD(regs5, tc)
42581.1Skamil{
42591.1Skamil	atf_tc_set_md_var(tc, "descr",
42601.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
42611.1Skamil}
42621.1Skamil
42631.1SkamilATF_TC_BODY(regs5, tc)
42641.1Skamil{
42651.1Skamil	const int exitval = 5;
42661.1Skamil	const int sigval = SIGSTOP;
42671.1Skamil	pid_t child, wpid;
42681.1Skamil#if defined(TWAIT_HAVE_STATUS)
42691.1Skamil	int status;
42701.1Skamil#endif
42711.1Skamil	struct reg r;
42721.1Skamil
42731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42751.1Skamil	if (child == 0) {
42761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42781.1Skamil
42791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42811.1Skamil
42821.13Schristos		DPRINTF("Before exiting of the child process\n");
42831.1Skamil		_exit(exitval);
42841.1Skamil	}
42851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42861.1Skamil
42871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42891.1Skamil
42901.1Skamil	validate_status_stopped(status, sigval);
42911.1Skamil
42921.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42941.1Skamil
42951.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
42961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42971.1Skamil
42981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42991.1Skamil	    "without signal to be sent\n");
43001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43011.1Skamil
43021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43041.1Skamil
43051.1Skamil	validate_status_exited(status, exitval);
43061.1Skamil
43071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43091.1Skamil}
43101.1Skamil#endif
43111.1Skamil
43121.1Skamil#if defined(HAVE_FPREGS)
43131.1SkamilATF_TC(fpregs1);
43141.1SkamilATF_TC_HEAD(fpregs1, tc)
43151.1Skamil{
43161.1Skamil	atf_tc_set_md_var(tc, "descr",
43171.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
43181.1Skamil}
43191.1Skamil
43201.1SkamilATF_TC_BODY(fpregs1, tc)
43211.1Skamil{
43221.1Skamil	const int exitval = 5;
43231.1Skamil	const int sigval = SIGSTOP;
43241.1Skamil	pid_t child, wpid;
43251.1Skamil#if defined(TWAIT_HAVE_STATUS)
43261.1Skamil	int status;
43271.1Skamil#endif
43281.1Skamil	struct fpreg r;
43291.1Skamil
43301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43321.1Skamil	if (child == 0) {
43331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43351.1Skamil
43361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43381.1Skamil
43391.13Schristos		DPRINTF("Before exiting of the child process\n");
43401.1Skamil		_exit(exitval);
43411.1Skamil	}
43421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43431.1Skamil
43441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43461.1Skamil
43471.1Skamil	validate_status_stopped(status, sigval);
43481.1Skamil
43491.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43511.1Skamil
43521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43531.1Skamil	    "without signal to be sent\n");
43541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43551.1Skamil
43561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43581.1Skamil
43591.1Skamil	validate_status_exited(status, exitval);
43601.1Skamil
43611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43631.1Skamil}
43641.1Skamil#endif
43651.1Skamil
43661.1Skamil#if defined(HAVE_FPREGS)
43671.1SkamilATF_TC(fpregs2);
43681.1SkamilATF_TC_HEAD(fpregs2, tc)
43691.1Skamil{
43701.1Skamil	atf_tc_set_md_var(tc, "descr",
43711.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
43721.1Skamil	    "regs");
43731.1Skamil}
43741.1Skamil
43751.1SkamilATF_TC_BODY(fpregs2, tc)
43761.1Skamil{
43771.1Skamil	const int exitval = 5;
43781.1Skamil	const int sigval = SIGSTOP;
43791.1Skamil	pid_t child, wpid;
43801.1Skamil#if defined(TWAIT_HAVE_STATUS)
43811.1Skamil	int status;
43821.1Skamil#endif
43831.1Skamil	struct fpreg r;
43841.1Skamil
43851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43871.1Skamil	if (child == 0) {
43881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43901.1Skamil
43911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43931.1Skamil
43941.13Schristos		DPRINTF("Before exiting of the child process\n");
43951.1Skamil		_exit(exitval);
43961.1Skamil	}
43971.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43981.1Skamil
43991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44011.1Skamil
44021.1Skamil	validate_status_stopped(status, sigval);
44031.1Skamil
44041.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
44051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
44061.1Skamil
44071.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
44081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
44091.1Skamil
44101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44111.1Skamil	    "without signal to be sent\n");
44121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44131.1Skamil
44141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44161.1Skamil
44171.1Skamil	validate_status_exited(status, exitval);
44181.1Skamil
44191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44211.1Skamil}
44221.1Skamil#endif
44231.1Skamil
44241.1Skamil#if defined(PT_STEP)
44251.1Skamilstatic void
44261.2Skamilptrace_step(int N, int setstep)
44271.1Skamil{
44281.1Skamil	const int exitval = 5;
44291.1Skamil	const int sigval = SIGSTOP;
44301.1Skamil	pid_t child, wpid;
44311.1Skamil#if defined(TWAIT_HAVE_STATUS)
44321.1Skamil	int status;
44331.1Skamil#endif
44341.1Skamil	int happy;
44351.1Skamil
44361.1Skamil#if defined(__arm__)
44371.1Skamil	/* PT_STEP not supported on arm 32-bit */
44381.1Skamil	atf_tc_expect_fail("PR kern/52119");
44391.1Skamil#endif
44401.1Skamil
44411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44431.1Skamil	if (child == 0) {
44441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44461.1Skamil
44471.1Skamil		happy = check_happy(999);
44481.1Skamil
44491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44511.1Skamil
44521.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
44531.1Skamil
44541.13Schristos		DPRINTF("Before exiting of the child process\n");
44551.1Skamil		_exit(exitval);
44561.1Skamil	}
44571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44581.1Skamil
44591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44611.1Skamil
44621.1Skamil	validate_status_stopped(status, sigval);
44631.1Skamil
44641.1Skamil	while (N --> 0) {
44651.2Skamil		if (setstep) {
44661.13Schristos			DPRINTF("Before resuming the child process where it "
44671.2Skamil			    "left off and without signal to be sent (use "
44681.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
44691.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
44701.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
44711.2Skamil			    != -1);
44721.2Skamil		} else {
44731.13Schristos			DPRINTF("Before resuming the child process where it "
44741.2Skamil			    "left off and without signal to be sent (use "
44751.2Skamil			    "PT_STEP)\n");
44761.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
44771.2Skamil			    != -1);
44781.2Skamil		}
44791.1Skamil
44801.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44811.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
44821.1Skamil		    child);
44831.1Skamil
44841.1Skamil		validate_status_stopped(status, SIGTRAP);
44851.2Skamil
44861.2Skamil		if (setstep) {
44871.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
44881.2Skamil		}
44891.1Skamil	}
44901.1Skamil
44911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44921.1Skamil	    "without signal to be sent\n");
44931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44941.1Skamil
44951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44971.1Skamil
44981.1Skamil	validate_status_exited(status, exitval);
44991.1Skamil
45001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
45021.1Skamil}
45031.1Skamil#endif
45041.1Skamil
45051.1Skamil#if defined(PT_STEP)
45061.1SkamilATF_TC(step1);
45071.1SkamilATF_TC_HEAD(step1, tc)
45081.1Skamil{
45091.1Skamil	atf_tc_set_md_var(tc, "descr",
45101.1Skamil	    "Verify single PT_STEP call");
45111.1Skamil}
45121.1Skamil
45131.1SkamilATF_TC_BODY(step1, tc)
45141.1Skamil{
45151.2Skamil	ptrace_step(1, 0);
45161.1Skamil}
45171.1Skamil#endif
45181.1Skamil
45191.1Skamil#if defined(PT_STEP)
45201.1SkamilATF_TC(step2);
45211.1SkamilATF_TC_HEAD(step2, tc)
45221.1Skamil{
45231.1Skamil	atf_tc_set_md_var(tc, "descr",
45241.1Skamil	    "Verify PT_STEP called twice");
45251.1Skamil}
45261.1Skamil
45271.1SkamilATF_TC_BODY(step2, tc)
45281.1Skamil{
45291.2Skamil	ptrace_step(2, 0);
45301.1Skamil}
45311.1Skamil#endif
45321.1Skamil
45331.1Skamil#if defined(PT_STEP)
45341.1SkamilATF_TC(step3);
45351.1SkamilATF_TC_HEAD(step3, tc)
45361.1Skamil{
45371.1Skamil	atf_tc_set_md_var(tc, "descr",
45381.1Skamil	    "Verify PT_STEP called three times");
45391.1Skamil}
45401.1Skamil
45411.1SkamilATF_TC_BODY(step3, tc)
45421.1Skamil{
45431.2Skamil	ptrace_step(3, 0);
45441.1Skamil}
45451.1Skamil#endif
45461.1Skamil
45471.1Skamil#if defined(PT_STEP)
45481.1SkamilATF_TC(step4);
45491.1SkamilATF_TC_HEAD(step4, tc)
45501.1Skamil{
45511.1Skamil	atf_tc_set_md_var(tc, "descr",
45521.1Skamil	    "Verify PT_STEP called four times");
45531.1Skamil}
45541.1Skamil
45551.1SkamilATF_TC_BODY(step4, tc)
45561.1Skamil{
45571.2Skamil	ptrace_step(4, 0);
45581.2Skamil}
45591.2Skamil#endif
45601.2Skamil
45611.2Skamil#if defined(PT_STEP)
45621.2SkamilATF_TC(setstep1);
45631.2SkamilATF_TC_HEAD(setstep1, tc)
45641.2Skamil{
45651.2Skamil	atf_tc_set_md_var(tc, "descr",
45661.2Skamil	    "Verify single PT_SETSTEP call");
45671.2Skamil}
45681.2Skamil
45691.2SkamilATF_TC_BODY(setstep1, tc)
45701.2Skamil{
45711.2Skamil	ptrace_step(1, 1);
45721.2Skamil}
45731.2Skamil#endif
45741.2Skamil
45751.2Skamil#if defined(PT_STEP)
45761.2SkamilATF_TC(setstep2);
45771.2SkamilATF_TC_HEAD(setstep2, tc)
45781.2Skamil{
45791.2Skamil	atf_tc_set_md_var(tc, "descr",
45801.2Skamil	    "Verify PT_SETSTEP called twice");
45811.2Skamil}
45821.2Skamil
45831.2SkamilATF_TC_BODY(setstep2, tc)
45841.2Skamil{
45851.2Skamil	ptrace_step(2, 1);
45861.2Skamil}
45871.2Skamil#endif
45881.2Skamil
45891.2Skamil#if defined(PT_STEP)
45901.2SkamilATF_TC(setstep3);
45911.2SkamilATF_TC_HEAD(setstep3, tc)
45921.2Skamil{
45931.2Skamil	atf_tc_set_md_var(tc, "descr",
45941.2Skamil	    "Verify PT_SETSTEP called three times");
45951.2Skamil}
45961.2Skamil
45971.2SkamilATF_TC_BODY(setstep3, tc)
45981.2Skamil{
45991.2Skamil	ptrace_step(3, 1);
46001.2Skamil}
46011.2Skamil#endif
46021.2Skamil
46031.2Skamil#if defined(PT_STEP)
46041.2SkamilATF_TC(setstep4);
46051.2SkamilATF_TC_HEAD(setstep4, tc)
46061.2Skamil{
46071.2Skamil	atf_tc_set_md_var(tc, "descr",
46081.2Skamil	    "Verify PT_SETSTEP called four times");
46091.2Skamil}
46101.2Skamil
46111.2SkamilATF_TC_BODY(setstep4, tc)
46121.2Skamil{
46131.2Skamil	ptrace_step(4, 1);
46141.1Skamil}
46151.1Skamil#endif
46161.1Skamil
46171.1SkamilATF_TC(kill1);
46181.1SkamilATF_TC_HEAD(kill1, tc)
46191.1Skamil{
46201.1Skamil	atf_tc_set_md_var(tc, "descr",
46211.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
46221.1Skamil}
46231.1Skamil
46241.1SkamilATF_TC_BODY(kill1, tc)
46251.1Skamil{
46261.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
46271.1Skamil	pid_t child, wpid;
46281.1Skamil#if defined(TWAIT_HAVE_STATUS)
46291.1Skamil	int status;
46301.1Skamil#endif
46311.1Skamil
46321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46341.1Skamil	if (child == 0) {
46351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46371.1Skamil
46381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46401.1Skamil
46411.1Skamil		/* NOTREACHED */
46421.1Skamil		FORKEE_ASSERTX(0 &&
46431.1Skamil		    "Child should be terminated by a signal from its parent");
46441.1Skamil	}
46451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46461.1Skamil
46471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46491.1Skamil
46501.1Skamil	validate_status_stopped(status, sigval);
46511.1Skamil
46521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46531.1Skamil	    "without signal to be sent\n");
46541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
46551.1Skamil
46561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46581.1Skamil
46591.1Skamil	validate_status_signaled(status, sigsent, 0);
46601.1Skamil
46611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46631.1Skamil}
46641.1Skamil
46651.1SkamilATF_TC(kill2);
46661.1SkamilATF_TC_HEAD(kill2, tc)
46671.1Skamil{
46681.1Skamil	atf_tc_set_md_var(tc, "descr",
46691.1Skamil	    "Verify that PT_KILL terminates child");
46701.1Skamil}
46711.1Skamil
46721.1SkamilATF_TC_BODY(kill2, tc)
46731.1Skamil{
46741.1Skamil	const int sigval = SIGSTOP;
46751.1Skamil	pid_t child, wpid;
46761.1Skamil#if defined(TWAIT_HAVE_STATUS)
46771.1Skamil	int status;
46781.1Skamil#endif
46791.1Skamil
46801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46821.1Skamil	if (child == 0) {
46831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46851.1Skamil
46861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46881.1Skamil
46891.1Skamil		/* NOTREACHED */
46901.1Skamil		FORKEE_ASSERTX(0 &&
46911.1Skamil		    "Child should be terminated by a signal from its parent");
46921.1Skamil	}
46931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46941.1Skamil
46951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46971.1Skamil
46981.1Skamil	validate_status_stopped(status, sigval);
46991.1Skamil
47001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47011.1Skamil	    "without signal to be sent\n");
47021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
47031.1Skamil
47041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47061.1Skamil
47071.1Skamil	validate_status_signaled(status, SIGKILL, 0);
47081.1Skamil
47091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47111.1Skamil}
47121.1Skamil
47131.1SkamilATF_TC(lwpinfo1);
47141.1SkamilATF_TC_HEAD(lwpinfo1, tc)
47151.1Skamil{
47161.1Skamil	atf_tc_set_md_var(tc, "descr",
47171.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
47181.1Skamil}
47191.1Skamil
47201.1SkamilATF_TC_BODY(lwpinfo1, tc)
47211.1Skamil{
47221.1Skamil	const int exitval = 5;
47231.1Skamil	const int sigval = SIGSTOP;
47241.1Skamil	pid_t child, wpid;
47251.1Skamil#if defined(TWAIT_HAVE_STATUS)
47261.1Skamil	int status;
47271.1Skamil#endif
47281.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47291.1Skamil
47301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47321.1Skamil	if (child == 0) {
47331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47351.1Skamil
47361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47381.1Skamil
47391.13Schristos		DPRINTF("Before exiting of the child process\n");
47401.1Skamil		_exit(exitval);
47411.1Skamil	}
47421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47431.1Skamil
47441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47461.1Skamil
47471.1Skamil	validate_status_stopped(status, sigval);
47481.1Skamil
47491.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47511.1Skamil
47521.13Schristos	DPRINTF("Assert that there exists a thread\n");
47531.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
47541.1Skamil
47551.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
47561.1Skamil	    info.pl_lwpid);
47571.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
47581.1Skamil	    "Received event %d != expected event %d",
47591.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
47601.1Skamil
47611.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47631.1Skamil
47641.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
47651.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
47661.1Skamil
47671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47681.1Skamil	    "without signal to be sent\n");
47691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47701.1Skamil
47711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47731.1Skamil
47741.1Skamil	validate_status_exited(status, exitval);
47751.1Skamil
47761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47781.1Skamil}
47791.1Skamil
47801.1Skamil#if defined(TWAIT_HAVE_PID)
47811.1SkamilATF_TC(lwpinfo2);
47821.1SkamilATF_TC_HEAD(lwpinfo2, tc)
47831.1Skamil{
47841.1Skamil	atf_tc_set_md_var(tc, "descr",
47851.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
47861.1Skamil	    "tracer)");
47871.1Skamil}
47881.1Skamil
47891.1SkamilATF_TC_BODY(lwpinfo2, tc)
47901.1Skamil{
47911.1Skamil	struct msg_fds parent_tracee, parent_tracer;
47921.1Skamil	const int exitval_tracee = 5;
47931.1Skamil	const int exitval_tracer = 10;
47941.1Skamil	pid_t tracee, tracer, wpid;
47951.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
47961.1Skamil#if defined(TWAIT_HAVE_STATUS)
47971.1Skamil	int status;
47981.1Skamil#endif
47991.1Skamil	struct ptrace_lwpinfo info = {0, 0};
48001.1Skamil
48011.13Schristos	DPRINTF("Spawn tracee\n");
48021.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
48031.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
48041.1Skamil	tracee = atf_utils_fork();
48051.1Skamil	if (tracee == 0) {
48061.1Skamil
48071.1Skamil		/* Wait for message from the parent */
48081.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
48091.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
48101.1Skamil
48111.1Skamil		_exit(exitval_tracee);
48121.1Skamil	}
48131.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
48141.1Skamil
48151.13Schristos	DPRINTF("Spawn debugger\n");
48161.1Skamil	tracer = atf_utils_fork();
48171.1Skamil	if (tracer == 0) {
48181.1Skamil		/* No IPC to communicate with the child */
48191.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
48201.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
48211.1Skamil
48221.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
48231.1Skamil		FORKEE_REQUIRE_SUCCESS(
48241.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48251.1Skamil
48261.1Skamil		forkee_status_stopped(status, SIGSTOP);
48271.1Skamil
48281.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48291.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48301.1Skamil		    != -1);
48311.1Skamil
48321.13Schristos		DPRINTF("Assert that there exists a thread\n");
48331.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
48341.1Skamil
48351.13Schristos		DPRINTF("Assert that lwp thread %d received event "
48361.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
48371.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
48381.1Skamil
48391.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48401.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48411.1Skamil		    != -1);
48421.1Skamil
48431.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
48441.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
48451.1Skamil
48461.1Skamil		/* Resume tracee with PT_CONTINUE */
48471.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
48481.1Skamil
48491.1Skamil		/* Inform parent that tracer has attached to tracee */
48501.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
48511.1Skamil		/* Wait for parent */
48521.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
48531.1Skamil
48541.1Skamil		/* Wait for tracee and assert that it exited */
48551.1Skamil		FORKEE_REQUIRE_SUCCESS(
48561.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48571.1Skamil
48581.1Skamil		forkee_status_exited(status, exitval_tracee);
48591.1Skamil
48601.13Schristos		DPRINTF("Before exiting of the tracer process\n");
48611.1Skamil		_exit(exitval_tracer);
48621.1Skamil	}
48631.1Skamil
48641.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
48651.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
48661.1Skamil
48671.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
48681.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
48691.1Skamil
48701.13Schristos	DPRINTF("Detect that tracee is zombie\n");
48711.1Skamil	await_zombie(tracee);
48721.1Skamil
48731.13Schristos	DPRINTF("Assert that there is no status about tracee - "
48741.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
48751.1Skamil	TWAIT_REQUIRE_SUCCESS(
48761.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
48771.1Skamil
48781.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
48791.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
48801.1Skamil
48811.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
48821.1Skamil	    TWAIT_FNAME);
48831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
48841.1Skamil	    tracer);
48851.1Skamil
48861.1Skamil	validate_status_exited(status, exitval_tracer);
48871.1Skamil
48881.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
48891.1Skamil	    TWAIT_FNAME);
48901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
48911.1Skamil	    tracee);
48921.1Skamil
48931.1Skamil	validate_status_exited(status, exitval_tracee);
48941.1Skamil
48951.1Skamil	msg_close(&parent_tracer);
48961.1Skamil	msg_close(&parent_tracee);
48971.1Skamil}
48981.1Skamil#endif
48991.1Skamil
49001.1SkamilATF_TC(siginfo1);
49011.1SkamilATF_TC_HEAD(siginfo1, tc)
49021.1Skamil{
49031.1Skamil	atf_tc_set_md_var(tc, "descr",
49041.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
49051.1Skamil}
49061.1Skamil
49071.1SkamilATF_TC_BODY(siginfo1, tc)
49081.1Skamil{
49091.1Skamil	const int exitval = 5;
49101.1Skamil	const int sigval = SIGTRAP;
49111.1Skamil	pid_t child, wpid;
49121.1Skamil#if defined(TWAIT_HAVE_STATUS)
49131.1Skamil	int status;
49141.1Skamil#endif
49151.1Skamil	struct ptrace_siginfo info;
49161.1Skamil	memset(&info, 0, sizeof(info));
49171.1Skamil
49181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49201.1Skamil	if (child == 0) {
49211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49231.1Skamil
49241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49261.1Skamil
49271.13Schristos		DPRINTF("Before exiting of the child process\n");
49281.1Skamil		_exit(exitval);
49291.1Skamil	}
49301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49311.1Skamil
49321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49341.1Skamil
49351.1Skamil	validate_status_stopped(status, sigval);
49361.1Skamil
49371.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49391.1Skamil
49401.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49411.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49421.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49431.1Skamil	    info.psi_siginfo.si_errno);
49441.1Skamil
49451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49461.1Skamil	    "without signal to be sent\n");
49471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49481.1Skamil
49491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49511.1Skamil
49521.1Skamil	validate_status_exited(status, exitval);
49531.1Skamil
49541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49561.1Skamil}
49571.1Skamil
49581.1SkamilATF_TC(siginfo2);
49591.1SkamilATF_TC_HEAD(siginfo2, tc)
49601.1Skamil{
49611.1Skamil	atf_tc_set_md_var(tc, "descr",
49621.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
49631.1Skamil	    "modification of SIGINT from tracee");
49641.1Skamil}
49651.1Skamil
49661.1Skamilstatic int siginfo2_caught = 0;
49671.1Skamil
49681.1Skamilstatic void
49691.1Skamilsiginfo2_sighandler(int sig)
49701.1Skamil{
49711.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
49721.1Skamil
49731.1Skamil	++siginfo2_caught;
49741.1Skamil}
49751.1Skamil
49761.1SkamilATF_TC_BODY(siginfo2, tc)
49771.1Skamil{
49781.1Skamil	const int exitval = 5;
49791.1Skamil	const int sigval = SIGINT;
49801.1Skamil	pid_t child, wpid;
49811.1Skamil	struct sigaction sa;
49821.1Skamil#if defined(TWAIT_HAVE_STATUS)
49831.1Skamil	int status;
49841.1Skamil#endif
49851.1Skamil	struct ptrace_siginfo info;
49861.1Skamil	memset(&info, 0, sizeof(info));
49871.1Skamil
49881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49901.1Skamil	if (child == 0) {
49911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49931.1Skamil
49941.1Skamil		sa.sa_handler = siginfo2_sighandler;
49951.1Skamil		sa.sa_flags = SA_SIGINFO;
49961.1Skamil		sigemptyset(&sa.sa_mask);
49971.1Skamil
49981.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
49991.1Skamil
50001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50021.1Skamil
50031.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
50041.1Skamil
50051.13Schristos		DPRINTF("Before exiting of the child process\n");
50061.1Skamil		_exit(exitval);
50071.1Skamil	}
50081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50091.1Skamil
50101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50121.1Skamil
50131.1Skamil	validate_status_stopped(status, sigval);
50141.1Skamil
50151.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50171.1Skamil
50181.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50191.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50201.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50211.1Skamil	    info.psi_siginfo.si_errno);
50221.1Skamil
50231.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50251.1Skamil
50261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50271.1Skamil	    "without signal to be sent\n");
50281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
50291.1Skamil
50301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50321.1Skamil
50331.1Skamil	validate_status_exited(status, exitval);
50341.1Skamil
50351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50371.1Skamil}
50381.1Skamil
50391.1SkamilATF_TC(siginfo3);
50401.1SkamilATF_TC_HEAD(siginfo3, tc)
50411.1Skamil{
50421.1Skamil	atf_tc_set_md_var(tc, "descr",
50431.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
50441.1Skamil	    "setting signal to new value");
50451.1Skamil}
50461.1Skamil
50471.1Skamilstatic int siginfo3_caught = 0;
50481.1Skamil
50491.1Skamilstatic void
50501.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
50511.1Skamil{
50521.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
50531.1Skamil
50541.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
50551.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
50561.1Skamil
50571.1Skamil	++siginfo3_caught;
50581.1Skamil}
50591.1Skamil
50601.1SkamilATF_TC_BODY(siginfo3, tc)
50611.1Skamil{
50621.1Skamil	const int exitval = 5;
50631.1Skamil	const int sigval = SIGINT;
50641.1Skamil	const int sigfaked = SIGTRAP;
50651.1Skamil	const int sicodefaked = TRAP_BRKPT;
50661.1Skamil	pid_t child, wpid;
50671.1Skamil	struct sigaction sa;
50681.1Skamil#if defined(TWAIT_HAVE_STATUS)
50691.1Skamil	int status;
50701.1Skamil#endif
50711.1Skamil	struct ptrace_siginfo info;
50721.1Skamil	memset(&info, 0, sizeof(info));
50731.1Skamil
50741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50761.1Skamil	if (child == 0) {
50771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50791.1Skamil
50801.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
50811.1Skamil		sa.sa_flags = SA_SIGINFO;
50821.1Skamil		sigemptyset(&sa.sa_mask);
50831.1Skamil
50841.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
50851.1Skamil
50861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50881.1Skamil
50891.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
50901.1Skamil
50911.13Schristos		DPRINTF("Before exiting of the child process\n");
50921.1Skamil		_exit(exitval);
50931.1Skamil	}
50941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50951.1Skamil
50961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50981.1Skamil
50991.1Skamil	validate_status_stopped(status, sigval);
51001.1Skamil
51011.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51031.1Skamil
51041.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51051.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51061.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51071.1Skamil	    info.psi_siginfo.si_errno);
51081.1Skamil
51091.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
51101.1Skamil	    sigfaked, sicodefaked);
51111.1Skamil	info.psi_siginfo.si_signo = sigfaked;
51121.1Skamil	info.psi_siginfo.si_code = sicodefaked;
51131.1Skamil
51141.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
51151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
51161.1Skamil
51171.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51191.1Skamil
51201.13Schristos	DPRINTF("Before checking siginfo_t\n");
51211.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
51221.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
51231.1Skamil
51241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51251.1Skamil	    "without signal to be sent\n");
51261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
51271.1Skamil
51281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51301.1Skamil
51311.1Skamil	validate_status_exited(status, exitval);
51321.1Skamil
51331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51351.1Skamil}
51361.1Skamil
51371.1SkamilATF_TC(siginfo4);
51381.1SkamilATF_TC_HEAD(siginfo4, tc)
51391.1Skamil{
51401.1Skamil	atf_tc_set_md_var(tc, "descr",
51411.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
51421.1Skamil}
51431.1Skamil
51441.1SkamilATF_TC_BODY(siginfo4, tc)
51451.1Skamil{
51461.1Skamil	const int sigval = SIGTRAP;
51471.1Skamil	pid_t child, wpid;
51481.1Skamil#if defined(TWAIT_HAVE_STATUS)
51491.1Skamil	int status;
51501.1Skamil#endif
51511.1Skamil
51521.1Skamil	struct ptrace_siginfo info;
51531.1Skamil	memset(&info, 0, sizeof(info));
51541.1Skamil
51551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51571.1Skamil	if (child == 0) {
51581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51601.1Skamil
51611.13Schristos		DPRINTF("Before calling execve(2) from child\n");
51621.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
51631.1Skamil
51641.1Skamil		FORKEE_ASSERT(0 && "Not reached");
51651.1Skamil	}
51661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51671.1Skamil
51681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51701.1Skamil
51711.1Skamil	validate_status_stopped(status, sigval);
51721.1Skamil
51731.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51751.1Skamil
51761.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51771.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51781.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51791.1Skamil	    info.psi_siginfo.si_errno);
51801.1Skamil
51811.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51821.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
51831.1Skamil
51841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51851.1Skamil	    "without signal to be sent\n");
51861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51871.1Skamil
51881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51901.1Skamil
51911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51931.1Skamil}
51941.1Skamil
51951.1Skamil#if defined(TWAIT_HAVE_PID)
51961.1SkamilATF_TC(siginfo5);
51971.1SkamilATF_TC_HEAD(siginfo5, tc)
51981.1Skamil{
51991.1Skamil	atf_tc_set_md_var(tc, "descr",
52001.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
52011.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
52021.1Skamil}
52031.1Skamil
52041.1SkamilATF_TC_BODY(siginfo5, tc)
52051.1Skamil{
52061.1Skamil	const int exitval = 5;
52071.1Skamil	const int exitval2 = 15;
52081.1Skamil	const int sigval = SIGSTOP;
52091.1Skamil	pid_t child, child2, wpid;
52101.1Skamil#if defined(TWAIT_HAVE_STATUS)
52111.1Skamil	int status;
52121.1Skamil#endif
52131.1Skamil	ptrace_state_t state;
52141.1Skamil	const int slen = sizeof(state);
52151.1Skamil	ptrace_event_t event;
52161.1Skamil	const int elen = sizeof(event);
52171.1Skamil	struct ptrace_siginfo info;
52181.1Skamil
52191.1Skamil	memset(&info, 0, sizeof(info));
52201.1Skamil
52211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52231.1Skamil	if (child == 0) {
52241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52261.1Skamil
52271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52291.1Skamil
52301.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
52311.1Skamil
52321.1Skamil		if (child2 == 0)
52331.1Skamil			_exit(exitval2);
52341.1Skamil
52351.1Skamil		FORKEE_REQUIRE_SUCCESS
52361.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
52371.1Skamil
52381.1Skamil		forkee_status_exited(status, exitval2);
52391.1Skamil
52401.13Schristos		DPRINTF("Before exiting of the child process\n");
52411.1Skamil		_exit(exitval);
52421.1Skamil	}
52431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52441.1Skamil
52451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52471.1Skamil
52481.1Skamil	validate_status_stopped(status, sigval);
52491.1Skamil
52501.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52521.1Skamil
52531.13Schristos	DPRINTF("Before checking siginfo_t\n");
52541.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
52551.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
52561.1Skamil
52571.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
52581.1Skamil	event.pe_set_event = PTRACE_FORK;
52591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52601.1Skamil
52611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52621.1Skamil	    "without signal to be sent\n");
52631.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
52641.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
52651.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
52661.1Skamil                "state.pe_other_pid=child)\n", child);
52671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52681.1Skamil
52691.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
52701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52711.1Skamil
52721.1Skamil	validate_status_stopped(status, SIGTRAP);
52731.1Skamil
52741.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52761.1Skamil
52771.13Schristos	DPRINTF("Before checking siginfo_t\n");
52781.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52791.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52801.1Skamil
52811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52821.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52831.1Skamil
52841.1Skamil	child2 = state.pe_other_pid;
52851.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
52861.1Skamil
52871.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
52881.1Skamil	    TWAIT_FNAME, child2, child);
52891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52901.1Skamil	    child2);
52911.1Skamil
52921.1Skamil	validate_status_stopped(status, SIGTRAP);
52931.1Skamil
52941.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52961.1Skamil
52971.13Schristos	DPRINTF("Before checking siginfo_t\n");
52981.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52991.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
53001.1Skamil
53011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
53021.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
53031.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
53041.1Skamil
53051.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
53061.1Skamil	    "without signal to be sent\n");
53071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
53081.1Skamil
53091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53101.1Skamil	    "without signal to be sent\n");
53111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53121.1Skamil
53131.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
53141.1Skamil	    TWAIT_FNAME);
53151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
53161.1Skamil	    child2);
53171.1Skamil
53181.1Skamil	validate_status_exited(status, exitval2);
53191.1Skamil
53201.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
53211.1Skamil	    TWAIT_FNAME);
53221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
53231.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
53241.1Skamil
53251.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53261.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
53271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53281.1Skamil
53291.1Skamil	validate_status_stopped(status, SIGCHLD);
53301.1Skamil
53311.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53331.1Skamil
53341.13Schristos	DPRINTF("Before checking siginfo_t\n");
53351.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
53361.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
53371.1Skamil
53381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53391.1Skamil	    "without signal to be sent\n");
53401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53411.1Skamil
53421.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53431.1Skamil	    TWAIT_FNAME);
53441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53451.1Skamil
53461.1Skamil	validate_status_exited(status, exitval);
53471.1Skamil
53481.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53491.1Skamil	    TWAIT_FNAME);
53501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53511.1Skamil}
53521.1Skamil#endif
53531.1Skamil
53541.1Skamil#if defined(PT_STEP)
53551.1SkamilATF_TC(siginfo6);
53561.1SkamilATF_TC_HEAD(siginfo6, tc)
53571.1Skamil{
53581.1Skamil	atf_tc_set_md_var(tc, "descr",
53591.1Skamil	    "Verify single PT_STEP call with signal information check");
53601.1Skamil}
53611.1Skamil
53621.1SkamilATF_TC_BODY(siginfo6, tc)
53631.1Skamil{
53641.1Skamil	const int exitval = 5;
53651.1Skamil	const int sigval = SIGSTOP;
53661.1Skamil	pid_t child, wpid;
53671.1Skamil#if defined(TWAIT_HAVE_STATUS)
53681.1Skamil	int status;
53691.1Skamil#endif
53701.1Skamil	int happy;
53711.1Skamil	struct ptrace_siginfo info;
53721.1Skamil
53731.1Skamil#if defined(__arm__)
53741.1Skamil	/* PT_STEP not supported on arm 32-bit */
53751.1Skamil	atf_tc_expect_fail("PR kern/52119");
53761.1Skamil#endif
53771.1Skamil
53781.1Skamil	memset(&info, 0, sizeof(info));
53791.1Skamil
53801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53821.1Skamil	if (child == 0) {
53831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53851.1Skamil
53861.1Skamil		happy = check_happy(100);
53871.1Skamil
53881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53901.1Skamil
53911.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
53921.1Skamil
53931.13Schristos		DPRINTF("Before exiting of the child process\n");
53941.1Skamil		_exit(exitval);
53951.1Skamil	}
53961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53971.1Skamil
53981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54001.1Skamil
54011.1Skamil	validate_status_stopped(status, sigval);
54021.1Skamil
54031.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
54041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
54051.1Skamil
54061.13Schristos	DPRINTF("Before checking siginfo_t\n");
54071.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
54081.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
54091.1Skamil
54101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54111.1Skamil	    "without signal to be sent (use PT_STEP)\n");
54121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
54131.1Skamil
54141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54161.1Skamil
54171.1Skamil	validate_status_stopped(status, SIGTRAP);
54181.1Skamil
54191.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
54201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
54211.1Skamil
54221.13Schristos	DPRINTF("Before checking siginfo_t\n");
54231.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
54241.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
54251.1Skamil
54261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54271.1Skamil	    "without signal to be sent\n");
54281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54291.1Skamil
54301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54321.1Skamil
54331.1Skamil	validate_status_exited(status, exitval);
54341.1Skamil
54351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54371.1Skamil}
54381.1Skamil#endif
54391.1Skamil
54401.1Skamilvolatile lwpid_t the_lwp_id = 0;
54411.1Skamil
54421.1Skamilstatic void
54431.1Skamillwp_main_func(void *arg)
54441.1Skamil{
54451.1Skamil	the_lwp_id = _lwp_self();
54461.1Skamil	_lwp_exit();
54471.1Skamil}
54481.1Skamil
54491.1SkamilATF_TC(lwp_create1);
54501.1SkamilATF_TC_HEAD(lwp_create1, tc)
54511.1Skamil{
54521.1Skamil	atf_tc_set_md_var(tc, "descr",
54531.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
54541.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
54551.1Skamil}
54561.1Skamil
54571.1SkamilATF_TC_BODY(lwp_create1, tc)
54581.1Skamil{
54591.1Skamil	const int exitval = 5;
54601.1Skamil	const int sigval = SIGSTOP;
54611.1Skamil	pid_t child, wpid;
54621.1Skamil#if defined(TWAIT_HAVE_STATUS)
54631.1Skamil	int status;
54641.1Skamil#endif
54651.1Skamil	ptrace_state_t state;
54661.1Skamil	const int slen = sizeof(state);
54671.1Skamil	ptrace_event_t event;
54681.1Skamil	const int elen = sizeof(event);
54691.1Skamil	ucontext_t uc;
54701.1Skamil	lwpid_t lid;
54711.1Skamil	static const size_t ssize = 16*1024;
54721.1Skamil	void *stack;
54731.1Skamil
54741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54761.1Skamil	if (child == 0) {
54771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54791.1Skamil
54801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54821.1Skamil
54831.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
54841.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
54851.1Skamil
54861.13Schristos		DPRINTF("Before making context for new lwp in child\n");
54871.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
54881.1Skamil
54891.13Schristos		DPRINTF("Before creating new in child\n");
54901.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
54911.1Skamil
54921.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
54931.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
54941.1Skamil
54951.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
54961.1Skamil		    "are the same\n", lid, the_lwp_id);
54971.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
54981.1Skamil
54991.13Schristos		DPRINTF("Before exiting of the child process\n");
55001.1Skamil		_exit(exitval);
55011.1Skamil	}
55021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55031.1Skamil
55041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55061.1Skamil
55071.1Skamil	validate_status_stopped(status, sigval);
55081.1Skamil
55091.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55101.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
55111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55121.1Skamil
55131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55141.1Skamil	    "without signal to be sent\n");
55151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55161.1Skamil
55171.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55181.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55201.1Skamil
55211.1Skamil	validate_status_stopped(status, SIGTRAP);
55221.1Skamil
55231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55241.1Skamil
55251.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
55261.1Skamil
55271.1Skamil	lid = state.pe_lwp;
55281.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
55291.1Skamil
55301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55311.1Skamil	    "without signal to be sent\n");
55321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55331.1Skamil
55341.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
55351.1Skamil	    TWAIT_FNAME);
55361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55371.1Skamil
55381.1Skamil	validate_status_exited(status, exitval);
55391.1Skamil
55401.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
55411.1Skamil	    TWAIT_FNAME);
55421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55431.1Skamil}
55441.1Skamil
55451.1SkamilATF_TC(lwp_exit1);
55461.1SkamilATF_TC_HEAD(lwp_exit1, tc)
55471.1Skamil{
55481.1Skamil	atf_tc_set_md_var(tc, "descr",
55491.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
55501.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
55511.1Skamil}
55521.1Skamil
55531.1SkamilATF_TC_BODY(lwp_exit1, tc)
55541.1Skamil{
55551.1Skamil	const int exitval = 5;
55561.1Skamil	const int sigval = SIGSTOP;
55571.1Skamil	pid_t child, wpid;
55581.1Skamil#if defined(TWAIT_HAVE_STATUS)
55591.1Skamil	int status;
55601.1Skamil#endif
55611.1Skamil	ptrace_state_t state;
55621.1Skamil	const int slen = sizeof(state);
55631.1Skamil	ptrace_event_t event;
55641.1Skamil	const int elen = sizeof(event);
55651.1Skamil	ucontext_t uc;
55661.1Skamil	lwpid_t lid;
55671.1Skamil	static const size_t ssize = 16*1024;
55681.1Skamil	void *stack;
55691.1Skamil
55701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55721.1Skamil	if (child == 0) {
55731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55751.1Skamil
55761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55781.1Skamil
55791.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
55801.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
55811.1Skamil
55821.13Schristos		DPRINTF("Before making context for new lwp in child\n");
55831.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
55841.1Skamil
55851.13Schristos		DPRINTF("Before creating new in child\n");
55861.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
55871.1Skamil
55881.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
55891.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
55901.1Skamil
55911.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
55921.1Skamil		    "are the same\n", lid, the_lwp_id);
55931.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
55941.1Skamil
55951.13Schristos		DPRINTF("Before exiting of the child process\n");
55961.1Skamil		_exit(exitval);
55971.1Skamil	}
55981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55991.1Skamil
56001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56021.1Skamil
56031.1Skamil	validate_status_stopped(status, sigval);
56041.1Skamil
56051.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
56061.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
56071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
56081.1Skamil
56091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56101.1Skamil	    "without signal to be sent\n");
56111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56121.1Skamil
56131.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
56141.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
56151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56161.1Skamil
56171.1Skamil	validate_status_stopped(status, SIGTRAP);
56181.1Skamil
56191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
56201.1Skamil
56211.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
56221.1Skamil
56231.1Skamil	lid = state.pe_lwp;
56241.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
56251.1Skamil
56261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56271.1Skamil	    "without signal to be sent\n");
56281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56291.1Skamil
56301.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
56311.1Skamil	    TWAIT_FNAME);
56321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56331.1Skamil
56341.1Skamil	validate_status_exited(status, exitval);
56351.1Skamil
56361.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
56371.1Skamil	    TWAIT_FNAME);
56381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56391.1Skamil}
56401.1Skamil
56411.1SkamilATF_TC(signal1);
56421.1SkamilATF_TC_HEAD(signal1, tc)
56431.1Skamil{
56441.1Skamil	atf_tc_set_md_var(tc, "descr",
56451.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
56461.1Skamil	    "from catching other signals");
56471.1Skamil}
56481.1Skamil
56491.1SkamilATF_TC_BODY(signal1, tc)
56501.1Skamil{
56511.1Skamil	const int exitval = 5;
56521.1Skamil	const int sigval = SIGSTOP;
56531.1Skamil	const int sigmasked = SIGTRAP;
56541.1Skamil	const int signotmasked = SIGINT;
56551.1Skamil	pid_t child, wpid;
56561.1Skamil#if defined(TWAIT_HAVE_STATUS)
56571.1Skamil	int status;
56581.1Skamil#endif
56591.1Skamil	sigset_t intmask;
56601.1Skamil
56611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56631.1Skamil	if (child == 0) {
56641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56661.1Skamil
56671.1Skamil		sigemptyset(&intmask);
56681.1Skamil		sigaddset(&intmask, sigmasked);
56691.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56701.1Skamil
56711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56731.1Skamil
56741.13Schristos		DPRINTF("Before raising %s from child\n",
56751.1Skamil		    strsignal(signotmasked));
56761.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
56771.1Skamil
56781.13Schristos		DPRINTF("Before exiting of the child process\n");
56791.1Skamil		_exit(exitval);
56801.1Skamil	}
56811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56821.1Skamil
56831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56851.1Skamil
56861.1Skamil	validate_status_stopped(status, sigval);
56871.1Skamil
56881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56891.1Skamil	    "without signal to be sent\n");
56901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56911.1Skamil
56921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56941.1Skamil
56951.1Skamil	validate_status_stopped(status, signotmasked);
56961.1Skamil
56971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56981.1Skamil	    "without signal to be sent\n");
56991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57001.1Skamil
57011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57031.1Skamil
57041.1Skamil	validate_status_exited(status, exitval);
57051.1Skamil
57061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57081.1Skamil}
57091.1Skamil
57101.1SkamilATF_TC(signal2);
57111.1SkamilATF_TC_HEAD(signal2, tc)
57121.1Skamil{
57131.1Skamil	atf_tc_set_md_var(tc, "descr",
57141.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
57151.1Skamil	    "catching this raised signal");
57161.1Skamil}
57171.1Skamil
57181.1SkamilATF_TC_BODY(signal2, tc)
57191.1Skamil{
57201.1Skamil	const int exitval = 5;
57211.1Skamil	const int sigval = SIGSTOP;
57221.1Skamil	const int sigmasked = SIGTRAP;
57231.1Skamil	pid_t child, wpid;
57241.1Skamil#if defined(TWAIT_HAVE_STATUS)
57251.1Skamil	int status;
57261.1Skamil#endif
57271.1Skamil	sigset_t intmask;
57281.1Skamil
57291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57311.1Skamil	if (child == 0) {
57321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57341.1Skamil
57351.1Skamil		sigemptyset(&intmask);
57361.1Skamil		sigaddset(&intmask, sigmasked);
57371.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57381.1Skamil
57391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57411.1Skamil
57421.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
57431.1Skamil		    strsignal(sigmasked));
57441.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
57451.1Skamil
57461.13Schristos		DPRINTF("Before exiting of the child process\n");
57471.1Skamil		_exit(exitval);
57481.1Skamil	}
57491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57501.1Skamil
57511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57531.1Skamil
57541.1Skamil	validate_status_stopped(status, sigval);
57551.1Skamil
57561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57571.1Skamil	    "without signal to be sent\n");
57581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57591.1Skamil
57601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57621.1Skamil
57631.1Skamil	validate_status_exited(status, exitval);
57641.1Skamil
57651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57671.1Skamil}
57681.1Skamil
57691.1SkamilATF_TC(signal3);
57701.1SkamilATF_TC_HEAD(signal3, tc)
57711.1Skamil{
57721.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57731.1Skamil	atf_tc_set_md_var(tc, "descr",
57741.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57751.1Skamil	    "catching software breakpoints");
57761.1Skamil}
57771.1Skamil
57781.1SkamilATF_TC_BODY(signal3, tc)
57791.1Skamil{
57801.1Skamil	const int exitval = 5;
57811.1Skamil	const int sigval = SIGSTOP;
57821.1Skamil	const int sigmasked = SIGTRAP;
57831.1Skamil	pid_t child, wpid;
57841.1Skamil#if defined(TWAIT_HAVE_STATUS)
57851.1Skamil	int status;
57861.1Skamil#endif
57871.1Skamil	sigset_t intmask;
57881.1Skamil
57891.20Skamil	atf_tc_expect_fail("PR kern/51918");
57901.20Skamil
57911.20Skamil	// This test breaks now on some ports, temporarily disable it
57921.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
57931.20Skamil
57941.10Smartin#if defined(__sparc__)
57951.7Skamil	atf_tc_expect_timeout("PR kern/52167");
57961.7Skamil
57971.7Skamil	// timeout wins, failure still valid
57981.7Skamil	// atf_tc_expect_fail("PR kern/51918");
57991.7Skamil#endif
58001.1Skamil
58011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58031.1Skamil	if (child == 0) {
58041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58061.1Skamil
58071.1Skamil		sigemptyset(&intmask);
58081.1Skamil		sigaddset(&intmask, sigmasked);
58091.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58101.1Skamil
58111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58131.1Skamil
58141.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
58151.4Skamil
58161.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
58171.4Skamil		PTRACE_BREAKPOINT_ASM;
58181.1Skamil#else
58191.4Skamil		/* port me */
58201.1Skamil#endif
58211.1Skamil
58221.13Schristos		DPRINTF("Before exiting of the child process\n");
58231.1Skamil		_exit(exitval);
58241.1Skamil	}
58251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58261.1Skamil
58271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58291.1Skamil
58301.1Skamil	validate_status_stopped(status, sigval);
58311.1Skamil
58321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58331.1Skamil	    "without signal to be sent\n");
58341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58351.1Skamil
58361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58381.1Skamil
58391.1Skamil	validate_status_stopped(status, sigmasked);
58401.1Skamil
58411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58421.1Skamil	    "without signal to be sent\n");
58431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58441.1Skamil
58451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58471.1Skamil
58481.1Skamil	validate_status_exited(status, exitval);
58491.1Skamil
58501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58521.1Skamil}
58531.1Skamil
58541.1Skamil#if defined(PT_STEP)
58551.1SkamilATF_TC(signal4);
58561.1SkamilATF_TC_HEAD(signal4, tc)
58571.1Skamil{
58581.1Skamil	atf_tc_set_md_var(tc, "descr",
58591.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58601.1Skamil	    "catching single step trap");
58611.1Skamil}
58621.1Skamil
58631.1SkamilATF_TC_BODY(signal4, tc)
58641.1Skamil{
58651.1Skamil	const int exitval = 5;
58661.1Skamil	const int sigval = SIGSTOP;
58671.1Skamil	const int sigmasked = SIGTRAP;
58681.1Skamil	pid_t child, wpid;
58691.1Skamil#if defined(TWAIT_HAVE_STATUS)
58701.1Skamil	int status;
58711.1Skamil#endif
58721.1Skamil	sigset_t intmask;
58731.1Skamil	int happy;
58741.1Skamil
58751.1Skamil#if defined(__arm__)
58761.5Skamil	/* PT_STEP not supported on arm 32-bit */
58771.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
58781.1Skamil#endif
58791.1Skamil
58801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58821.1Skamil	if (child == 0) {
58831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58851.1Skamil
58861.1Skamil		happy = check_happy(100);
58871.1Skamil
58881.1Skamil		sigemptyset(&intmask);
58891.1Skamil		sigaddset(&intmask, sigmasked);
58901.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58911.1Skamil
58921.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58931.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58941.1Skamil
58951.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
58961.1Skamil
58971.13Schristos		DPRINTF("Before exiting of the child process\n");
58981.1Skamil		_exit(exitval);
58991.1Skamil	}
59001.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59011.1Skamil
59021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59041.1Skamil
59051.1Skamil	validate_status_stopped(status, sigval);
59061.1Skamil
59071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59081.1Skamil	    "without signal to be sent\n");
59091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
59101.1Skamil
59111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59131.1Skamil
59141.1Skamil	validate_status_stopped(status, sigmasked);
59151.1Skamil
59161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59171.1Skamil	    "without signal to be sent\n");
59181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59191.1Skamil
59201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59221.1Skamil
59231.1Skamil	validate_status_exited(status, exitval);
59241.1Skamil
59251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59271.1Skamil}
59281.1Skamil#endif
59291.1Skamil
59301.1SkamilATF_TC(signal5);
59311.1SkamilATF_TC_HEAD(signal5, tc)
59321.1Skamil{
59331.1Skamil	atf_tc_set_md_var(tc, "descr",
59341.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59351.1Skamil	    "catching exec() breakpoint");
59361.1Skamil}
59371.1Skamil
59381.1SkamilATF_TC_BODY(signal5, tc)
59391.1Skamil{
59401.1Skamil	const int exitval = 5;
59411.1Skamil	const int sigval = SIGSTOP;
59421.1Skamil	const int sigmasked = SIGTRAP;
59431.1Skamil	pid_t child, wpid;
59441.1Skamil#if defined(TWAIT_HAVE_STATUS)
59451.1Skamil	int status;
59461.1Skamil#endif
59471.1Skamil	sigset_t intmask;
59481.1Skamil
59491.14Schristos	atf_tc_expect_fail("wrong signal");
59501.14Schristos
59511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59531.1Skamil	if (child == 0) {
59541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59561.1Skamil
59571.1Skamil		sigemptyset(&intmask);
59581.1Skamil		sigaddset(&intmask, sigmasked);
59591.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59601.1Skamil
59611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59631.1Skamil
59641.13Schristos		DPRINTF("Before calling execve(2) from child\n");
59651.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
59661.1Skamil
59671.13Schristos		DPRINTF("Before exiting of the child process\n");
59681.1Skamil		_exit(exitval);
59691.1Skamil	}
59701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59711.1Skamil
59721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59741.1Skamil
59751.1Skamil	validate_status_stopped(status, sigval);
59761.1Skamil
59771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59781.1Skamil	    "without signal to be sent\n");
59791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59801.1Skamil
59811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59831.1Skamil
59841.1Skamil	validate_status_stopped(status, sigmasked);
59851.1Skamil
59861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59871.1Skamil	    "without signal to be sent\n");
59881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59891.1Skamil
59901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59921.1Skamil
59931.1Skamil	validate_status_exited(status, exitval);
59941.1Skamil
59951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59971.1Skamil}
59981.1Skamil
59991.1Skamil#if defined(TWAIT_HAVE_PID)
60001.1SkamilATF_TC(signal6);
60011.1SkamilATF_TC_HEAD(signal6, tc)
60021.1Skamil{
60031.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
60041.1Skamil	atf_tc_set_md_var(tc, "descr",
60051.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
60061.1Skamil	    "catching PTRACE_FORK breakpoint");
60071.1Skamil}
60081.1Skamil
60091.1SkamilATF_TC_BODY(signal6, tc)
60101.1Skamil{
60111.1Skamil	const int exitval = 5;
60121.1Skamil	const int exitval2 = 15;
60131.1Skamil	const int sigval = SIGSTOP;
60141.1Skamil	const int sigmasked = SIGTRAP;
60151.1Skamil	pid_t child, child2, wpid;
60161.1Skamil#if defined(TWAIT_HAVE_STATUS)
60171.1Skamil	int status;
60181.1Skamil#endif
60191.1Skamil	sigset_t intmask;
60201.1Skamil	ptrace_state_t state;
60211.1Skamil	const int slen = sizeof(state);
60221.1Skamil	ptrace_event_t event;
60231.1Skamil	const int elen = sizeof(event);
60241.1Skamil
60251.38Skamil	atf_tc_expect_fail("PR kern/51918");
60261.14Schristos
60271.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60281.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60291.1Skamil	if (child == 0) {
60301.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60311.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60321.1Skamil
60331.1Skamil		sigemptyset(&intmask);
60341.1Skamil		sigaddset(&intmask, sigmasked);
60351.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60361.1Skamil
60371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60391.1Skamil
60401.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
60411.1Skamil
60421.1Skamil		if (child2 == 0)
60431.1Skamil			_exit(exitval2);
60441.1Skamil
60451.1Skamil		FORKEE_REQUIRE_SUCCESS
60461.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60471.1Skamil
60481.1Skamil		forkee_status_exited(status, exitval2);
60491.1Skamil
60501.13Schristos		DPRINTF("Before exiting of the child process\n");
60511.1Skamil		_exit(exitval);
60521.1Skamil	}
60531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60541.1Skamil
60551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60571.1Skamil
60581.1Skamil	validate_status_stopped(status, sigval);
60591.1Skamil
60601.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
60611.1Skamil	event.pe_set_event = PTRACE_FORK;
60621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60631.1Skamil
60641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60651.1Skamil	    "without signal to be sent\n");
60661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60671.1Skamil
60681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60701.1Skamil
60711.1Skamil	validate_status_stopped(status, sigmasked);
60721.1Skamil
60731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60741.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60751.1Skamil
60761.1Skamil	child2 = state.pe_other_pid;
60771.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
60781.1Skamil
60791.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
60801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60811.1Skamil	    child2);
60821.1Skamil
60831.1Skamil	validate_status_stopped(status, SIGTRAP);
60841.1Skamil
60851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
60861.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60871.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
60881.1Skamil
60891.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
60901.1Skamil	    "without signal to be sent\n");
60911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
60921.1Skamil
60931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60941.1Skamil	    "without signal to be sent\n");
60951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60961.1Skamil
60971.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60981.1Skamil	    TWAIT_FNAME);
60991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
61001.1Skamil	    child2);
61011.1Skamil
61021.1Skamil	validate_status_exited(status, exitval2);
61031.1Skamil
61041.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
61051.1Skamil	    TWAIT_FNAME);
61061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
61071.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
61081.1Skamil
61091.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61101.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
61111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61121.1Skamil
61131.1Skamil	validate_status_stopped(status, SIGCHLD);
61141.1Skamil
61151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61161.1Skamil	    "without signal to be sent\n");
61171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61181.1Skamil
61191.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61201.1Skamil	    TWAIT_FNAME);
61211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61221.1Skamil
61231.1Skamil	validate_status_exited(status, exitval);
61241.1Skamil
61251.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61261.1Skamil	    TWAIT_FNAME);
61271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61281.1Skamil}
61291.1Skamil#endif
61301.1Skamil
61311.1Skamil#if defined(TWAIT_HAVE_PID)
61321.1SkamilATF_TC(signal7);
61331.1SkamilATF_TC_HEAD(signal7, tc)
61341.1Skamil{
61351.1Skamil	atf_tc_set_md_var(tc, "descr",
61361.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61371.1Skamil	    "catching PTRACE_VFORK breakpoint");
61381.1Skamil}
61391.1Skamil
61401.1SkamilATF_TC_BODY(signal7, tc)
61411.1Skamil{
61421.1Skamil	const int exitval = 5;
61431.1Skamil	const int exitval2 = 15;
61441.1Skamil	const int sigval = SIGSTOP;
61451.1Skamil	const int sigmasked = SIGTRAP;
61461.1Skamil	pid_t child, child2, wpid;
61471.1Skamil#if defined(TWAIT_HAVE_STATUS)
61481.1Skamil	int status;
61491.1Skamil#endif
61501.1Skamil	sigset_t intmask;
61511.1Skamil	ptrace_state_t state;
61521.1Skamil	const int slen = sizeof(state);
61531.1Skamil	ptrace_event_t event;
61541.1Skamil	const int elen = sizeof(event);
61551.1Skamil
61561.38Skamil	atf_tc_expect_fail("PR kern/51918");
61571.14Schristos
61581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61601.1Skamil	if (child == 0) {
61611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61631.1Skamil
61641.1Skamil		sigemptyset(&intmask);
61651.1Skamil		sigaddset(&intmask, sigmasked);
61661.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61671.1Skamil
61681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61701.1Skamil
61711.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
61721.1Skamil
61731.1Skamil		if (child2 == 0)
61741.1Skamil			_exit(exitval2);
61751.1Skamil
61761.1Skamil		FORKEE_REQUIRE_SUCCESS
61771.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
61781.1Skamil
61791.1Skamil		forkee_status_exited(status, exitval2);
61801.1Skamil
61811.13Schristos		DPRINTF("Before exiting of the child process\n");
61821.1Skamil		_exit(exitval);
61831.1Skamil	}
61841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61851.1Skamil
61861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61881.1Skamil
61891.1Skamil	validate_status_stopped(status, sigval);
61901.1Skamil
61911.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
61921.1Skamil	event.pe_set_event = PTRACE_VFORK;
61931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
61941.1Skamil
61951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61961.1Skamil	    "without signal to be sent\n");
61971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61981.1Skamil
61991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62011.1Skamil
62021.1Skamil	validate_status_stopped(status, sigmasked);
62031.1Skamil
62041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
62051.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
62061.1Skamil
62071.1Skamil	child2 = state.pe_other_pid;
62081.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
62091.1Skamil
62101.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
62111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62121.1Skamil	    child2);
62131.1Skamil
62141.1Skamil	validate_status_stopped(status, SIGTRAP);
62151.1Skamil
62161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
62171.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
62181.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
62191.1Skamil
62201.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
62211.1Skamil	    "without signal to be sent\n");
62221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
62231.1Skamil
62241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62251.1Skamil	    "without signal to be sent\n");
62261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62271.1Skamil
62281.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
62291.1Skamil	    TWAIT_FNAME);
62301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62311.1Skamil	    child2);
62321.1Skamil
62331.1Skamil	validate_status_exited(status, exitval2);
62341.1Skamil
62351.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
62361.1Skamil	    TWAIT_FNAME);
62371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
62381.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
62391.1Skamil
62401.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62411.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
62421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62431.1Skamil
62441.1Skamil	validate_status_stopped(status, SIGCHLD);
62451.1Skamil
62461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62471.1Skamil	    "without signal to be sent\n");
62481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62491.1Skamil
62501.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62511.1Skamil	    TWAIT_FNAME);
62521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62531.1Skamil
62541.1Skamil	validate_status_exited(status, exitval);
62551.1Skamil
62561.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62571.1Skamil	    TWAIT_FNAME);
62581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62591.1Skamil}
62601.1Skamil#endif
62611.1Skamil
62621.1SkamilATF_TC(signal8);
62631.1SkamilATF_TC_HEAD(signal8, tc)
62641.1Skamil{
62651.1Skamil	atf_tc_set_md_var(tc, "descr",
62661.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62671.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
62681.1Skamil}
62691.1Skamil
62701.1SkamilATF_TC_BODY(signal8, tc)
62711.1Skamil{
62721.1Skamil	const int exitval = 5;
62731.1Skamil	const int exitval2 = 15;
62741.1Skamil	const int sigval = SIGSTOP;
62751.1Skamil	const int sigmasked = SIGTRAP;
62761.1Skamil	pid_t child, child2, wpid;
62771.1Skamil#if defined(TWAIT_HAVE_STATUS)
62781.1Skamil	int status;
62791.1Skamil#endif
62801.1Skamil	sigset_t intmask;
62811.1Skamil	ptrace_state_t state;
62821.1Skamil	const int slen = sizeof(state);
62831.1Skamil	ptrace_event_t event;
62841.1Skamil	const int elen = sizeof(event);
62851.1Skamil
62861.14Schristos	atf_tc_expect_fail("PR kern/51918");
62871.14Schristos
62881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62901.1Skamil	if (child == 0) {
62911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62931.1Skamil
62941.1Skamil		sigemptyset(&intmask);
62951.1Skamil		sigaddset(&intmask, sigmasked);
62961.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62971.1Skamil
62981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63001.1Skamil
63011.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
63021.1Skamil
63031.1Skamil		if (child2 == 0)
63041.1Skamil			_exit(exitval2);
63051.1Skamil
63061.1Skamil		FORKEE_REQUIRE_SUCCESS
63071.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
63081.1Skamil
63091.1Skamil		forkee_status_exited(status, exitval2);
63101.1Skamil
63111.13Schristos		DPRINTF("Before exiting of the child process\n");
63121.1Skamil		_exit(exitval);
63131.1Skamil	}
63141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63151.1Skamil
63161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63181.1Skamil
63191.1Skamil	validate_status_stopped(status, sigval);
63201.1Skamil
63211.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
63221.1Skamil	    child);
63231.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
63241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
63251.1Skamil
63261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63271.1Skamil	    "without signal to be sent\n");
63281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63291.1Skamil
63301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63321.1Skamil
63331.1Skamil	validate_status_stopped(status, sigmasked);
63341.1Skamil
63351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63361.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
63371.1Skamil
63381.1Skamil	child2 = state.pe_other_pid;
63391.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
63401.1Skamil
63411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63421.1Skamil	    "without signal to be sent\n");
63431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63441.1Skamil
63451.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63461.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
63471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63481.1Skamil
63491.1Skamil	validate_status_stopped(status, SIGCHLD);
63501.1Skamil
63511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63521.1Skamil	    "without signal to be sent\n");
63531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63541.1Skamil
63551.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63561.1Skamil	    TWAIT_FNAME);
63571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63581.1Skamil
63591.1Skamil	validate_status_exited(status, exitval);
63601.1Skamil
63611.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63621.1Skamil	    TWAIT_FNAME);
63631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63641.1Skamil}
63651.1Skamil
63661.1SkamilATF_TC(signal9);
63671.1SkamilATF_TC_HEAD(signal9, tc)
63681.1Skamil{
63691.1Skamil	atf_tc_set_md_var(tc, "descr",
63701.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
63711.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
63721.1Skamil}
63731.1Skamil
63741.1SkamilATF_TC_BODY(signal9, tc)
63751.1Skamil{
63761.1Skamil	const int exitval = 5;
63771.1Skamil	const int sigval = SIGSTOP;
63781.1Skamil	const int sigmasked = SIGTRAP;
63791.1Skamil	pid_t child, wpid;
63801.1Skamil#if defined(TWAIT_HAVE_STATUS)
63811.1Skamil	int status;
63821.1Skamil#endif
63831.1Skamil	sigset_t intmask;
63841.1Skamil	ptrace_state_t state;
63851.1Skamil	const int slen = sizeof(state);
63861.1Skamil	ptrace_event_t event;
63871.1Skamil	const int elen = sizeof(event);
63881.1Skamil	ucontext_t uc;
63891.1Skamil	lwpid_t lid;
63901.1Skamil	static const size_t ssize = 16*1024;
63911.1Skamil	void *stack;
63921.1Skamil
63931.14Schristos	atf_tc_expect_fail("PR kern/51918");
63941.14Schristos
63951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63971.1Skamil	if (child == 0) {
63981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64001.1Skamil
64011.1Skamil		sigemptyset(&intmask);
64021.1Skamil		sigaddset(&intmask, sigmasked);
64031.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
64041.1Skamil
64051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64071.1Skamil
64081.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64091.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64101.1Skamil
64111.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64121.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
64131.1Skamil
64141.13Schristos		DPRINTF("Before creating new in child\n");
64151.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64161.1Skamil
64171.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64181.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64191.1Skamil
64201.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64211.1Skamil		    "are the same\n", lid, the_lwp_id);
64221.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64231.1Skamil
64241.13Schristos		DPRINTF("Before exiting of the child process\n");
64251.1Skamil		_exit(exitval);
64261.1Skamil	}
64271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64281.1Skamil
64291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64311.1Skamil
64321.1Skamil	validate_status_stopped(status, sigval);
64331.1Skamil
64341.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
64351.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
64361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
64371.1Skamil
64381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64391.1Skamil	    "without signal to be sent\n");
64401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64411.1Skamil
64421.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64431.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64451.1Skamil
64461.1Skamil	validate_status_stopped(status, sigmasked);
64471.1Skamil
64481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
64491.1Skamil
64501.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
64511.1Skamil
64521.1Skamil	lid = state.pe_lwp;
64531.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
64541.1Skamil
64551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64561.1Skamil	    "without signal to be sent\n");
64571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64581.1Skamil
64591.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64601.1Skamil	    TWAIT_FNAME);
64611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64621.1Skamil
64631.1Skamil	validate_status_exited(status, exitval);
64641.1Skamil
64651.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64661.1Skamil	    TWAIT_FNAME);
64671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64681.1Skamil}
64691.1Skamil
64701.1SkamilATF_TC(signal10);
64711.1SkamilATF_TC_HEAD(signal10, tc)
64721.1Skamil{
64731.1Skamil	atf_tc_set_md_var(tc, "descr",
64741.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
64751.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
64761.1Skamil}
64771.1Skamil
64781.1SkamilATF_TC_BODY(signal10, tc)
64791.1Skamil{
64801.1Skamil	const int exitval = 5;
64811.1Skamil	const int sigval = SIGSTOP;
64821.1Skamil	const int sigmasked = SIGTRAP;
64831.1Skamil	pid_t child, wpid;
64841.1Skamil#if defined(TWAIT_HAVE_STATUS)
64851.1Skamil	int status;
64861.1Skamil#endif
64871.1Skamil	sigset_t intmask;
64881.1Skamil	ptrace_state_t state;
64891.1Skamil	const int slen = sizeof(state);
64901.1Skamil	ptrace_event_t event;
64911.1Skamil	const int elen = sizeof(event);
64921.1Skamil	ucontext_t uc;
64931.1Skamil	lwpid_t lid;
64941.1Skamil	static const size_t ssize = 16*1024;
64951.1Skamil	void *stack;
64961.1Skamil
64971.14Schristos	atf_tc_expect_fail("PR kern/51918");
64981.14Schristos
64991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65011.1Skamil	if (child == 0) {
65021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65041.1Skamil
65051.1Skamil		sigemptyset(&intmask);
65061.1Skamil		sigaddset(&intmask, sigmasked);
65071.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
65081.1Skamil
65091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65111.1Skamil
65121.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
65131.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
65141.1Skamil
65151.13Schristos		DPRINTF("Before making context for new lwp in child\n");
65161.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
65171.1Skamil
65181.13Schristos		DPRINTF("Before creating new in child\n");
65191.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
65201.1Skamil
65211.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
65221.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
65231.1Skamil
65241.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
65251.1Skamil		    "are the same\n", lid, the_lwp_id);
65261.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
65271.1Skamil
65281.13Schristos		DPRINTF("Before exiting of the child process\n");
65291.1Skamil		_exit(exitval);
65301.1Skamil	}
65311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65321.1Skamil
65331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65351.1Skamil
65361.1Skamil	validate_status_stopped(status, sigval);
65371.1Skamil
65381.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
65391.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
65401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
65411.1Skamil
65421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65431.1Skamil	    "without signal to be sent\n");
65441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65451.1Skamil
65461.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65471.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65491.1Skamil
65501.1Skamil	validate_status_stopped(status, sigmasked);
65511.1Skamil
65521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
65531.1Skamil
65541.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
65551.1Skamil
65561.1Skamil	lid = state.pe_lwp;
65571.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
65581.1Skamil
65591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65601.1Skamil	    "without signal to be sent\n");
65611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65621.1Skamil
65631.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65641.1Skamil	    TWAIT_FNAME);
65651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65661.1Skamil
65671.1Skamil	validate_status_exited(status, exitval);
65681.1Skamil
65691.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65701.1Skamil	    TWAIT_FNAME);
65711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65721.1Skamil}
65731.1Skamil
65741.1Skamilstatic void
65751.1Skamillwp_main_stop(void *arg)
65761.1Skamil{
65771.1Skamil	the_lwp_id = _lwp_self();
65781.1Skamil
65791.1Skamil	raise(SIGTRAP);
65801.1Skamil
65811.1Skamil	_lwp_exit();
65821.1Skamil}
65831.1Skamil
65841.1SkamilATF_TC(suspend1);
65851.1SkamilATF_TC_HEAD(suspend1, tc)
65861.1Skamil{
65871.1Skamil	atf_tc_set_md_var(tc, "descr",
65881.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
65891.1Skamil	    "resumed by a tracee");
65901.1Skamil}
65911.1Skamil
65921.1SkamilATF_TC_BODY(suspend1, tc)
65931.1Skamil{
65941.1Skamil	const int exitval = 5;
65951.1Skamil	const int sigval = SIGSTOP;
65961.1Skamil	pid_t child, wpid;
65971.1Skamil#if defined(TWAIT_HAVE_STATUS)
65981.1Skamil	int status;
65991.1Skamil#endif
66001.1Skamil	ucontext_t uc;
66011.1Skamil	lwpid_t lid;
66021.1Skamil	static const size_t ssize = 16*1024;
66031.1Skamil	void *stack;
66041.1Skamil	struct ptrace_lwpinfo pl;
66051.1Skamil	struct ptrace_siginfo psi;
66061.1Skamil	volatile int go = 0;
66071.1Skamil
66081.17Skamil	// Feature pending for refactoring
66091.17Skamil	atf_tc_expect_fail("PR kern/51995");
66101.17Skamil
66111.16Skamil	// Hangs with qemu
66121.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
66131.16Skamil
66141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66161.1Skamil	if (child == 0) {
66171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66191.1Skamil
66201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66221.1Skamil
66231.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
66241.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
66251.1Skamil
66261.13Schristos		DPRINTF("Before making context for new lwp in child\n");
66271.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
66281.1Skamil
66291.13Schristos		DPRINTF("Before creating new in child\n");
66301.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
66311.1Skamil
66321.1Skamil		while (go == 0)
66331.1Skamil			continue;
66341.1Skamil
66351.1Skamil		raise(SIGINT);
66361.1Skamil
66371.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
66381.1Skamil
66391.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
66401.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
66411.1Skamil
66421.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
66431.1Skamil		    "are the same\n", lid, the_lwp_id);
66441.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
66451.1Skamil
66461.13Schristos		DPRINTF("Before exiting of the child process\n");
66471.1Skamil		_exit(exitval);
66481.1Skamil	}
66491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66501.1Skamil
66511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66531.1Skamil
66541.1Skamil	validate_status_stopped(status, sigval);
66551.1Skamil
66561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66571.1Skamil	    "without signal to be sent\n");
66581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66591.1Skamil
66601.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66611.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
66621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66631.1Skamil
66641.1Skamil	validate_status_stopped(status, SIGTRAP);
66651.1Skamil
66661.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
66671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
66681.1Skamil
66691.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
66701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
66711.1Skamil
66721.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
66731.1Skamil	    child, getpid());
66741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
66751.1Skamil
66761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66771.1Skamil	    "without signal to be sent\n");
66781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66791.1Skamil
66801.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66811.1Skamil	    "SIGINT\n", TWAIT_FNAME);
66821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66831.1Skamil
66841.1Skamil	validate_status_stopped(status, SIGINT);
66851.1Skamil
66861.1Skamil	pl.pl_lwpid = 0;
66871.1Skamil
66881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66891.1Skamil	while (pl.pl_lwpid != 0) {
66901.1Skamil
66911.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66921.1Skamil		switch (pl.pl_lwpid) {
66931.1Skamil		case 1:
66941.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
66951.1Skamil			break;
66961.1Skamil		case 2:
66971.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
66981.1Skamil			break;
66991.1Skamil		}
67001.1Skamil	}
67011.1Skamil
67021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67031.1Skamil	    "without signal to be sent\n");
67041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67051.1Skamil
67061.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
67071.1Skamil	    TWAIT_FNAME);
67081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67091.1Skamil
67101.1Skamil	validate_status_exited(status, exitval);
67111.1Skamil
67121.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
67131.1Skamil	    TWAIT_FNAME);
67141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67151.1Skamil}
67161.1Skamil
67171.1SkamilATF_TC(suspend2);
67181.1SkamilATF_TC_HEAD(suspend2, tc)
67191.1Skamil{
67201.1Skamil	atf_tc_set_md_var(tc, "descr",
67211.1Skamil	    "Verify that the while the only thread within a process is "
67221.1Skamil	    "suspended, the whole process cannot be unstopped");
67231.1Skamil}
67241.1Skamil
67251.1SkamilATF_TC_BODY(suspend2, tc)
67261.1Skamil{
67271.1Skamil	const int exitval = 5;
67281.1Skamil	const int sigval = SIGSTOP;
67291.1Skamil	pid_t child, wpid;
67301.1Skamil#if defined(TWAIT_HAVE_STATUS)
67311.1Skamil	int status;
67321.1Skamil#endif
67331.1Skamil	struct ptrace_siginfo psi;
67341.1Skamil
67351.17Skamil	// Feature pending for refactoring
67361.17Skamil	atf_tc_expect_fail("PR kern/51995");
67371.17Skamil
67381.16Skamil	// Hangs with qemu
67391.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
67401.16Skamil
67411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67431.1Skamil	if (child == 0) {
67441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67461.1Skamil
67471.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67481.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67491.1Skamil
67501.13Schristos		DPRINTF("Before exiting of the child process\n");
67511.1Skamil		_exit(exitval);
67521.1Skamil	}
67531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67541.1Skamil
67551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67571.1Skamil
67581.1Skamil	validate_status_stopped(status, sigval);
67591.1Skamil
67601.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
67611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
67621.1Skamil
67631.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
67641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
67651.1Skamil
67661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67671.1Skamil	    "without signal to be sent\n");
67681.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
67691.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
67701.1Skamil
67711.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
67721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
67731.1Skamil
67741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67751.1Skamil	    "without signal to be sent\n");
67761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67771.1Skamil
67781.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
67791.1Skamil	    TWAIT_FNAME);
67801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67811.1Skamil
67821.1Skamil	validate_status_exited(status, exitval);
67831.1Skamil
67841.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
67851.1Skamil	    TWAIT_FNAME);
67861.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67871.1Skamil}
67881.1Skamil
67891.1SkamilATF_TC(resume1);
67901.1SkamilATF_TC_HEAD(resume1, tc)
67911.1Skamil{
67921.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
67931.1Skamil	atf_tc_set_md_var(tc, "descr",
67941.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
67951.1Skamil	    "resumed by the debugger");
67961.1Skamil}
67971.1Skamil
67981.1SkamilATF_TC_BODY(resume1, tc)
67991.1Skamil{
68001.1Skamil	struct msg_fds fds;
68011.1Skamil	const int exitval = 5;
68021.1Skamil	const int sigval = SIGSTOP;
68031.1Skamil	pid_t child, wpid;
68041.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
68051.1Skamil#if defined(TWAIT_HAVE_STATUS)
68061.1Skamil	int status;
68071.1Skamil#endif
68081.1Skamil	ucontext_t uc;
68091.1Skamil	lwpid_t lid;
68101.1Skamil	static const size_t ssize = 16*1024;
68111.1Skamil	void *stack;
68121.1Skamil	struct ptrace_lwpinfo pl;
68131.1Skamil	struct ptrace_siginfo psi;
68141.1Skamil
68151.17Skamil	// Feature pending for refactoring
68161.17Skamil	atf_tc_expect_fail("PR kern/51995");
68171.17Skamil
68181.15Schristos	// Hangs with qemu
68191.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
68201.1Skamil
68211.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
68221.1Skamil
68231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
68241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
68251.1Skamil	if (child == 0) {
68261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68281.1Skamil
68291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68311.1Skamil
68321.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
68331.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
68341.1Skamil
68351.13Schristos		DPRINTF("Before making context for new lwp in child\n");
68361.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
68371.1Skamil
68381.13Schristos		DPRINTF("Before creating new in child\n");
68391.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
68401.1Skamil
68411.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
68421.1Skamil
68431.1Skamil		raise(SIGINT);
68441.1Skamil
68451.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
68461.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
68471.1Skamil
68481.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
68491.1Skamil		    "are the same\n", lid, the_lwp_id);
68501.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
68511.1Skamil
68521.13Schristos		DPRINTF("Before exiting of the child process\n");
68531.1Skamil		_exit(exitval);
68541.1Skamil	}
68551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68561.1Skamil
68571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68591.1Skamil
68601.1Skamil	validate_status_stopped(status, sigval);
68611.1Skamil
68621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68631.1Skamil	    "without signal to be sent\n");
68641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68651.1Skamil
68661.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68671.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
68681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68691.1Skamil
68701.1Skamil	validate_status_stopped(status, SIGTRAP);
68711.1Skamil
68721.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
68731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
68741.1Skamil
68751.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
68761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
68771.1Skamil
68781.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
68791.1Skamil
68801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68811.1Skamil	    "without signal to be sent\n");
68821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68831.1Skamil
68841.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68851.1Skamil	    "SIGINT\n", TWAIT_FNAME);
68861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68871.1Skamil
68881.1Skamil	validate_status_stopped(status, SIGINT);
68891.1Skamil
68901.1Skamil	pl.pl_lwpid = 0;
68911.1Skamil
68921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68931.1Skamil	while (pl.pl_lwpid != 0) {
68941.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68951.1Skamil		switch (pl.pl_lwpid) {
68961.1Skamil		case 1:
68971.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
68981.1Skamil			break;
68991.1Skamil		case 2:
69001.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
69011.1Skamil			break;
69021.1Skamil		}
69031.1Skamil	}
69041.1Skamil
69051.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
69061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
69071.1Skamil
69081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69091.1Skamil	    "without signal to be sent\n");
69101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69111.1Skamil
69121.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
69131.1Skamil	    TWAIT_FNAME);
69141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69151.1Skamil
69161.1Skamil	validate_status_exited(status, exitval);
69171.1Skamil
69181.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
69191.1Skamil	    TWAIT_FNAME);
69201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69211.1Skamil
69221.1Skamil	msg_close(&fds);
69231.1Skamil
69241.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
69251.1Skamil	sleep(10);
69261.1Skamil}
69271.1Skamil
69281.1SkamilATF_TC(syscall1);
69291.1SkamilATF_TC_HEAD(syscall1, tc)
69301.1Skamil{
69311.1Skamil	atf_tc_set_md_var(tc, "descr",
69321.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
69331.1Skamil}
69341.1Skamil
69351.1SkamilATF_TC_BODY(syscall1, tc)
69361.1Skamil{
69371.1Skamil	const int exitval = 5;
69381.1Skamil	const int sigval = SIGSTOP;
69391.1Skamil	pid_t child, wpid;
69401.1Skamil#if defined(TWAIT_HAVE_STATUS)
69411.1Skamil	int status;
69421.1Skamil#endif
69431.1Skamil	struct ptrace_siginfo info;
69441.1Skamil	memset(&info, 0, sizeof(info));
69451.1Skamil
69461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69481.1Skamil	if (child == 0) {
69491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69511.1Skamil
69521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
69541.1Skamil
69551.1Skamil		syscall(SYS_getpid);
69561.1Skamil
69571.13Schristos		DPRINTF("Before exiting of the child process\n");
69581.1Skamil		_exit(exitval);
69591.1Skamil	}
69601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
69611.1Skamil
69621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69641.1Skamil
69651.1Skamil	validate_status_stopped(status, sigval);
69661.1Skamil
69671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69681.1Skamil	    "without signal to be sent\n");
69691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69701.1Skamil
69711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69731.1Skamil
69741.1Skamil	validate_status_stopped(status, SIGTRAP);
69751.1Skamil
69761.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69781.1Skamil
69791.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
69801.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
69811.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69821.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
69831.1Skamil
69841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69851.1Skamil	    "without signal to be sent\n");
69861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69871.1Skamil
69881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69901.1Skamil
69911.1Skamil	validate_status_stopped(status, SIGTRAP);
69921.1Skamil
69931.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69951.1Skamil
69961.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
69971.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
69981.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69991.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
70001.1Skamil
70011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70021.1Skamil	    "without signal to be sent\n");
70031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70041.1Skamil
70051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70071.1Skamil
70081.1Skamil	validate_status_exited(status, exitval);
70091.1Skamil
70101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70121.1Skamil}
70131.1Skamil
70141.1SkamilATF_TC(syscallemu1);
70151.1SkamilATF_TC_HEAD(syscallemu1, tc)
70161.1Skamil{
70171.1Skamil	atf_tc_set_md_var(tc, "descr",
70181.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
70191.1Skamil}
70201.1Skamil
70211.1SkamilATF_TC_BODY(syscallemu1, tc)
70221.1Skamil{
70231.1Skamil	const int exitval = 5;
70241.1Skamil	const int sigval = SIGSTOP;
70251.1Skamil	pid_t child, wpid;
70261.1Skamil#if defined(TWAIT_HAVE_STATUS)
70271.1Skamil	int status;
70281.1Skamil#endif
70291.1Skamil
70301.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
70311.6Skamil	/* syscallemu does not work on sparc (32-bit) */
70321.6Skamil	atf_tc_expect_fail("PR kern/52166");
70331.6Skamil#endif
70341.6Skamil
70351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
70361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
70371.1Skamil	if (child == 0) {
70381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
70391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
70401.1Skamil
70411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70431.1Skamil
70441.1Skamil		syscall(SYS_exit, 100);
70451.1Skamil
70461.13Schristos		DPRINTF("Before exiting of the child process\n");
70471.1Skamil		_exit(exitval);
70481.1Skamil	}
70491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70501.1Skamil
70511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70531.1Skamil
70541.1Skamil	validate_status_stopped(status, sigval);
70551.1Skamil
70561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70571.1Skamil	    "without signal to be sent\n");
70581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70591.1Skamil
70601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70621.1Skamil
70631.1Skamil	validate_status_stopped(status, SIGTRAP);
70641.1Skamil
70651.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
70661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
70671.1Skamil
70681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70691.1Skamil	    "without signal to be sent\n");
70701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70711.1Skamil
70721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70741.1Skamil
70751.1Skamil	validate_status_stopped(status, SIGTRAP);
70761.1Skamil
70771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70781.1Skamil	    "without signal to be sent\n");
70791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70801.1Skamil
70811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70831.1Skamil
70841.1Skamil	validate_status_exited(status, exitval);
70851.1Skamil
70861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70881.1Skamil}
70891.1Skamil
70901.26Skamil#if defined(TWAIT_HAVE_PID)
70911.26SkamilATF_TC(race1);
70921.26SkamilATF_TC_HEAD(race1, tc)
70931.26Skamil{
70941.26Skamil	atf_tc_set_md_var(tc, "descr",
70951.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
70961.26Skamil	    "process and no other error is reported");
70971.26Skamil}
70981.26Skamil
70991.26SkamilATF_TC_BODY(race1, tc)
71001.26Skamil{
71011.26Skamil	time_t start, end;
71021.26Skamil	double diff;
71031.26Skamil	unsigned long N = 0;
71041.26Skamil
71051.26Skamil	/* Reuse this test with attach1 */
71061.26Skamil
71071.26Skamil	start = time(NULL);
71081.26Skamil	while (true) {
71091.26Skamil		DPRINTF("Step: %lu\n", N);
71101.26Skamil		attach1_raw(true);
71111.26Skamil		end = time(NULL);
71121.26Skamil		diff = difftime(end, start);
71131.26Skamil		if (diff >= 5.0)
71141.26Skamil			break;
71151.26Skamil		++N;
71161.26Skamil	}
71171.26Skamil	DPRINTF("Iterations: %lu\n", N);
71181.26Skamil}
71191.26Skamil#endif
71201.26Skamil
71211.1Skamil#include "t_ptrace_amd64_wait.h"
71221.1Skamil#include "t_ptrace_i386_wait.h"
71231.1Skamil#include "t_ptrace_x86_wait.h"
71241.1Skamil
71251.1SkamilATF_TP_ADD_TCS(tp)
71261.1Skamil{
71271.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
71281.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
71291.33Skamil
71301.36Skamil	ATF_TP_ADD_TC(tp, traceme_raise1);
71311.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
71321.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
71331.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
71341.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
71351.33Skamil
71361.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
71371.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
71381.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
71391.34Skamil
71401.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler1);
71411.48Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler2);
71421.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler3);
71431.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler4);
71441.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);
71451.1Skamil
71461.37Skamil	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
71471.37Skamil
71481.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
71491.46Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
71501.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
71511.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
71521.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
71531.47Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
71541.47Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
71551.47Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
71561.40Skamil
71571.41Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_breakpoint);
71581.41Skamil
71591.43Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
71601.43Skamil
71611.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
71621.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
71631.1Skamil	ATF_TP_ADD_TC(tp, attach3);
71641.1Skamil	ATF_TP_ADD_TC(tp, attach4);
71651.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
71661.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
71671.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
71681.1Skamil
71691.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
71701.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
71711.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
71721.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
71731.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
71741.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
71751.1Skamil
71761.31Skamil	ATF_TP_ADD_TC(tp, fork1);
71771.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
71781.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
71791.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
71801.31Skamil	ATF_TP_ADD_TC(tp, fork5);
71811.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
71821.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
71831.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
71841.31Skamil
71851.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
71861.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
71871.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
71881.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
71891.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
71901.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
71911.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
71921.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
71931.1Skamil
71941.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
71951.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
71961.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
71971.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
71981.1Skamil
71991.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
72001.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
72011.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
72021.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
72031.1Skamil
72041.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
72051.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
72061.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
72071.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
72081.1Skamil
72091.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
72101.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
72111.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
72121.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
72131.1Skamil
72141.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
72151.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
72161.1Skamil
72171.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
72181.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
72191.1Skamil
72201.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
72211.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
72221.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
72231.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
72241.1Skamil
72251.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
72261.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
72271.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
72281.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
72291.1Skamil
72301.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
72311.1Skamil
72321.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
72331.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
72341.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
72351.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
72361.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
72371.1Skamil
72381.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
72391.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
72401.1Skamil
72411.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
72421.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
72431.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
72441.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
72451.1Skamil
72461.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
72471.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
72481.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
72491.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
72501.2Skamil
72511.1Skamil	ATF_TP_ADD_TC(tp, kill1);
72521.1Skamil	ATF_TP_ADD_TC(tp, kill2);
72531.1Skamil
72541.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
72551.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
72561.1Skamil
72571.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
72581.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
72591.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
72601.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
72611.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
72621.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
72631.1Skamil
72641.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
72651.1Skamil
72661.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
72671.1Skamil
72681.1Skamil	ATF_TP_ADD_TC(tp, signal1);
72691.1Skamil	ATF_TP_ADD_TC(tp, signal2);
72701.1Skamil	ATF_TP_ADD_TC(tp, signal3);
72711.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
72721.1Skamil	ATF_TP_ADD_TC(tp, signal5);
72731.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
72741.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
72751.1Skamil	ATF_TP_ADD_TC(tp, signal8);
72761.1Skamil	ATF_TP_ADD_TC(tp, signal9);
72771.1Skamil	ATF_TP_ADD_TC(tp, signal10);
72781.1Skamil
72791.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
72801.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
72811.1Skamil
72821.1Skamil	ATF_TP_ADD_TC(tp, resume1);
72831.1Skamil
72841.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
72851.1Skamil
72861.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
72871.1Skamil
72881.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
72891.26Skamil
72901.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
72911.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
72921.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
72931.1Skamil
72941.1Skamil	return atf_no_error();
72951.1Skamil}
7296