t_ptrace_wait.c revision 1.46
11.46Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.46 2018/05/19 05:07:42 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.46Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.46 2018/05/19 05:07:42 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.35Skamil			_exit(exitval);
3031.35Skamil		default:
3041.35Skamil			/* NOTREACHED */
3051.35Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
3061.35Skamil		}
3071.1Skamil	}
3081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3091.1Skamil
3101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3121.1Skamil
3131.1Skamil	validate_status_stopped(status, sigval);
3141.1Skamil
3151.45Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3161.45Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
3171.45Skamil	                != -1);
3181.45Skamil
3191.45Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3201.45Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3211.45Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3221.45Skamil	    info.psi_siginfo.si_errno);
3231.45Skamil
3241.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3251.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3261.45Skamil
3271.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
3281.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
3291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
3301.1Skamil
3311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3331.1Skamil
3341.35Skamil	switch (sigsent) {
3351.35Skamil	case SIGCONT:
3361.35Skamil		validate_status_exited(status, exitval);
3371.35Skamil		break;
3381.35Skamil	default:
3391.35Skamil		validate_status_signaled(status, sigsent, expect_core);
3401.35Skamil		break;
3411.35Skamil	}
3421.1Skamil
3431.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
3441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3451.1Skamil}
3461.1Skamil
3471.35Skamil#define TRACEME_SIGNAL_NOHANDLER(test, sig)					\
3481.35SkamilATF_TC(test);									\
3491.35SkamilATF_TC_HEAD(test, tc)								\
3501.35Skamil{										\
3511.35Skamil	atf_tc_set_md_var(tc, "descr",						\
3521.35Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
3531.35Skamil	    "handled correctly in a child without a signal handler");		\
3541.35Skamil}										\
3551.35Skamil										\
3561.35SkamilATF_TC_BODY(test, tc)								\
3571.35Skamil{										\
3581.35Skamil										\
3591.35Skamil	traceme_signal_nohandler(sig);						\
3601.35Skamil}
3611.35Skamil
3621.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */
3631.35Skamil//TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */
3641.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */
3651.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP)  /* hangup */
3661.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */
3671.35Skamil
3681.35Skamil/// ----------------------------------------------------------------------------
3691.35Skamil
3701.37SkamilATF_TC(traceme_pid1_parent);
3711.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc)
3721.37Skamil{
3731.37Skamil	atf_tc_set_md_var(tc, "descr",
3741.37Skamil	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
3751.37Skamil}
3761.37Skamil
3771.37SkamilATF_TC_BODY(traceme_pid1_parent, tc)
3781.37Skamil{
3791.37Skamil	struct msg_fds parent_child;
3801.37Skamil	int exitval_child1 = 1, exitval_child2 = 2;
3811.37Skamil	pid_t child1, child2, wpid;
3821.37Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3831.37Skamil#if defined(TWAIT_HAVE_STATUS)
3841.37Skamil	int status;
3851.37Skamil#endif
3861.37Skamil
3871.37Skamil	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
3881.37Skamil
3891.37Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
3901.37Skamil	SYSCALL_REQUIRE((child1 = fork()) != -1);
3911.37Skamil	if (child1 == 0) {
3921.37Skamil		DPRINTF("Before forking process PID=%d\n", getpid());
3931.37Skamil		SYSCALL_REQUIRE((child2 = fork()) != -1);
3941.37Skamil		if (child2 != 0) {
3951.37Skamil			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
3961.37Skamil			        getpid(), child2);
3971.37Skamil			_exit(exitval_child1);
3981.37Skamil		}
3991.37Skamil		CHILD_FROM_PARENT("exit child1", parent_child, msg);
4001.37Skamil
4011.37Skamil		DPRINTF("Assert that our parent is PID1 (initproc)\n");
4021.37Skamil		FORKEE_ASSERT_EQ(getppid(), 1);
4031.37Skamil
4041.37Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4051.37Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
4061.37Skamil		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
4071.37Skamil
4081.37Skamil		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
4091.37Skamil
4101.37Skamil		_exit(exitval_child2);
4111.37Skamil	}
4121.37Skamil	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
4131.37Skamil
4141.37Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4151.37Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child1, &status, WEXITED),
4161.37Skamil	                      child1);
4171.37Skamil
4181.37Skamil	validate_status_exited(status, exitval_child1);
4191.37Skamil
4201.37Skamil	DPRINTF("Notify that child1 is dead\n");
4211.37Skamil	PARENT_TO_CHILD("exit child1", parent_child, msg);
4221.37Skamil
4231.37Skamil	DPRINTF("Wait for exiting of child2\n");
4241.37Skamil	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
4251.37Skamil}
4261.37Skamil
4271.37Skamil/// ----------------------------------------------------------------------------
4281.37Skamil
4291.40Skamilstatic void
4301.40Skamiltraceme_vfork_raise(int sigval)
4311.40Skamil{
4321.46Skamil	const int exitval = 5, exitval_watcher = 10;
4331.46Skamil	pid_t child, parent, watcher, wpid;
4341.46Skamil	int rv;
4351.40Skamil#if defined(TWAIT_HAVE_STATUS)
4361.40Skamil	int status;
4371.40Skamil	int expect_core = (sigval == SIGABRT) ? 1 : 0;
4381.40Skamil#endif
4391.40Skamil
4401.46Skamil	/*
4411.46Skamil	 * Spawn a dedicated thread to watch for a stopped child and emit
4421.46Skamil	 * the SIGKILL signal to it.
4431.46Skamil	 *
4441.46Skamil	 * vfork(2) might clobber watcher, this means that it's safer and
4451.46Skamil	 * simpler to reparent this process to initproc and forget about it.
4461.46Skamil	 */
4471.46Skamil	if (sigval == SIGSTOP) {
4481.46Skamil		parent = getpid();
4491.46Skamil
4501.46Skamil		watcher = fork();
4511.46Skamil		ATF_REQUIRE(watcher != 1);
4521.46Skamil		if (watcher == 0) {
4531.46Skamil			/* Double fork(2) trick to reparent to initproc */
4541.46Skamil			watcher = fork();
4551.46Skamil			FORKEE_ASSERT_NEQ(watcher, -1);
4561.46Skamil			if (watcher != 0)
4571.46Skamil				_exit(exitval_watcher);
4581.46Skamil
4591.46Skamil			child = await_stopped_child(parent);
4601.46Skamil
4611.46Skamil			errno = 0;
4621.46Skamil			rv = kill(child, SIGKILL);
4631.46Skamil			FORKEE_ASSERT_EQ(rv, 0);
4641.46Skamil			FORKEE_ASSERT_EQ(errno, 0);
4651.46Skamil
4661.46Skamil			/* This exit value will be collected by initproc */
4671.46Skamil			_exit(0);
4681.46Skamil		}
4691.46Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4701.46Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
4711.46Skamil		                      watcher);
4721.46Skamil
4731.46Skamil		validate_status_exited(status, exitval_watcher);
4741.46Skamil
4751.46Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4761.46Skamil		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(watcher,
4771.46Skamil		                                                   &status, 0));
4781.46Skamil	}
4791.46Skamil
4801.40Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
4811.40Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
4821.40Skamil	if (child == 0) {
4831.40Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4841.40Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4851.40Skamil
4861.40Skamil		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4871.40Skamil		FORKEE_ASSERT(raise(sigval) == 0);
4881.40Skamil
4891.40Skamil		switch (sigval) {
4901.46Skamil		case SIGSTOP:
4911.40Skamil		case SIGKILL:
4921.40Skamil		case SIGABRT:
4931.40Skamil		case SIGHUP:
4941.40Skamil			/* NOTREACHED */
4951.40Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
4961.40Skamil		default:
4971.40Skamil			DPRINTF("Before exiting of the child process\n");
4981.40Skamil			_exit(exitval);
4991.40Skamil		}
5001.40Skamil	}
5011.40Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5021.40Skamil
5031.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5041.40Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5051.40Skamil
5061.40Skamil	switch (sigval) {
5071.40Skamil	case SIGKILL:
5081.40Skamil	case SIGABRT:
5091.40Skamil	case SIGHUP:
5101.40Skamil		validate_status_signaled(status, sigval, expect_core);
5111.40Skamil		break;
5121.40Skamil	case SIGSTOP:
5131.46Skamil		validate_status_signaled(status, SIGKILL, 0);
5141.46Skamil		break;
5151.40Skamil	case SIGCONT:
5161.40Skamil		validate_status_exited(status, exitval);
5171.40Skamil		break;
5181.40Skamil	default:
5191.40Skamil		/* NOTREACHED */
5201.40Skamil		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
5211.40Skamil		break;
5221.40Skamil	}
5231.40Skamil
5241.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5251.40Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5261.40Skamil}
5271.40Skamil
5281.40Skamil#define TRACEME_VFORK_RAISE(test, sig)						\
5291.40SkamilATF_TC(test);									\
5301.40SkamilATF_TC_HEAD(test, tc)								\
5311.40Skamil{										\
5321.40Skamil	atf_tc_set_md_var(tc, "descr",						\
5331.42Skamil	    "Verify PT_TRACE_ME followed by raise of " #sig " in a vfork(2)ed "	\
5341.42Skamil	    "child");								\
5351.40Skamil}										\
5361.40Skamil										\
5371.40SkamilATF_TC_BODY(test, tc)								\
5381.40Skamil{										\
5391.40Skamil										\
5401.40Skamil	traceme_vfork_raise(sig);						\
5411.40Skamil}
5421.40Skamil
5431.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
5441.46SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
5451.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGABRT) /* regular abort trap */
5461.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGHUP)  /* hangup */
5471.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGCONT) /* continued? */
5481.40Skamil
5491.40Skamil/// ----------------------------------------------------------------------------
5501.40Skamil
5511.41SkamilATF_TC(traceme_vfork_breakpoint);
5521.41SkamilATF_TC_HEAD(traceme_vfork_breakpoint, tc)
5531.41Skamil{
5541.41Skamil	atf_tc_set_md_var(tc, "descr",
5551.44Skamil	    "Verify PT_TRACE_ME followed by a software breakpoint in a "
5561.44Skamil	    "vfork(2)ed child");
5571.41Skamil}
5581.41Skamil
5591.41SkamilATF_TC_BODY(traceme_vfork_breakpoint, tc)
5601.41Skamil{
5611.41Skamil	pid_t child, wpid;
5621.41Skamil#if defined(TWAIT_HAVE_STATUS)
5631.41Skamil	int status;
5641.41Skamil#endif
5651.41Skamil
5661.41Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
5671.41Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
5681.41Skamil	if (child == 0) {
5691.41Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5701.41Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5711.41Skamil
5721.41Skamil		DPRINTF("Before executing a software breakpoint\n");
5731.41Skamil#ifdef PTRACE_BREAKPOINT_ASM
5741.41Skamil		PTRACE_BREAKPOINT_ASM;
5751.41Skamil#else
5761.41Skamil		/* port me */
5771.41Skamil#endif
5781.41Skamil
5791.41Skamil		/* NOTREACHED */
5801.41Skamil		FORKEE_ASSERTX(0 && "This shall not be reached");
5811.41Skamil	}
5821.41Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5831.41Skamil
5841.41Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5851.41Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5861.41Skamil
5871.41Skamil	validate_status_signaled(status, SIGTRAP, 1);
5881.41Skamil
5891.41Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5901.41Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5911.41Skamil}
5921.41Skamil
5931.41Skamil/// ----------------------------------------------------------------------------
5941.41Skamil
5951.43SkamilATF_TC(traceme_vfork_exec);
5961.43SkamilATF_TC_HEAD(traceme_vfork_exec, tc)
5971.43Skamil{
5981.43Skamil	atf_tc_set_md_var(tc, "descr",
5991.43Skamil	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child");
6001.43Skamil}
6011.43Skamil
6021.43SkamilATF_TC_BODY(traceme_vfork_exec, tc)
6031.43Skamil{
6041.43Skamil	const int sigval = SIGTRAP;
6051.43Skamil	pid_t child, wpid;
6061.43Skamil#if defined(TWAIT_HAVE_STATUS)
6071.43Skamil	int status;
6081.43Skamil#endif
6091.43Skamil
6101.43Skamil	struct ptrace_siginfo info;
6111.43Skamil	memset(&info, 0, sizeof(info));
6121.43Skamil
6131.43Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
6141.43Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
6151.43Skamil	if (child == 0) {
6161.43Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6171.43Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6181.43Skamil
6191.43Skamil		DPRINTF("Before calling execve(2) from child\n");
6201.43Skamil		execlp("/bin/echo", "/bin/echo", NULL);
6211.43Skamil
6221.43Skamil		/* NOTREACHED */
6231.43Skamil		FORKEE_ASSERTX(0 && "Not reached");
6241.43Skamil	}
6251.43Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6261.43Skamil
6271.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6281.43Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6291.43Skamil
6301.43Skamil	validate_status_stopped(status, sigval);
6311.43Skamil
6321.43Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6331.43Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6341.43Skamil
6351.43Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6361.43Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
6371.43Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6381.43Skamil	    info.psi_siginfo.si_errno);
6391.43Skamil
6401.43Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
6411.43Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
6421.43Skamil
6431.43Skamil	DPRINTF("Before resuming the child process where it left off and "
6441.43Skamil	    "without signal to be sent\n");
6451.43Skamil	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6461.43Skamil
6471.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6481.43Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6491.43Skamil
6501.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6511.43Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6521.43Skamil}
6531.43Skamil
6541.43Skamil/// ----------------------------------------------------------------------------
6551.43Skamil
6561.1Skamil#if defined(TWAIT_HAVE_PID)
6571.1SkamilATF_TC(attach1);
6581.1SkamilATF_TC_HEAD(attach1, tc)
6591.1Skamil{
6601.1Skamil	atf_tc_set_md_var(tc, "descr",
6611.1Skamil	    "Assert that tracer sees process termination before the parent");
6621.1Skamil}
6631.1Skamil
6641.26Skamilstatic void
6651.26Skamilattach1_raw(bool raw)
6661.1Skamil{
6671.1Skamil	struct msg_fds parent_tracee, parent_tracer;
6681.1Skamil	const int exitval_tracee = 5;
6691.1Skamil	const int exitval_tracer = 10;
6701.1Skamil	pid_t tracee, tracer, wpid;
6711.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6721.1Skamil#if defined(TWAIT_HAVE_STATUS)
6731.1Skamil	int status;
6741.1Skamil#endif
6751.1Skamil
6761.13Schristos	DPRINTF("Spawn tracee\n");
6771.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6781.1Skamil	tracee = atf_utils_fork();
6791.1Skamil	if (tracee == 0) {
6801.1Skamil		// Wait for parent to let us exit
6811.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6821.1Skamil		_exit(exitval_tracee);
6831.1Skamil	}
6841.1Skamil
6851.13Schristos	DPRINTF("Spawn debugger\n");
6861.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6871.1Skamil	tracer = atf_utils_fork();
6881.1Skamil	if (tracer == 0) {
6891.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6901.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6911.1Skamil
6921.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6931.1Skamil		FORKEE_REQUIRE_SUCCESS(
6941.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6951.1Skamil
6961.1Skamil		forkee_status_stopped(status, SIGSTOP);
6971.1Skamil
6981.1Skamil		/* Resume tracee with PT_CONTINUE */
6991.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7001.1Skamil
7011.1Skamil		/* Inform parent that tracer has attached to tracee */
7021.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
7031.1Skamil
7041.1Skamil		/* Wait for parent to tell use that tracee should have exited */
7051.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
7061.1Skamil
7071.1Skamil		/* Wait for tracee and assert that it exited */
7081.1Skamil		FORKEE_REQUIRE_SUCCESS(
7091.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7101.1Skamil
7111.1Skamil		forkee_status_exited(status, exitval_tracee);
7121.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
7131.1Skamil
7141.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7151.1Skamil		_exit(exitval_tracer);
7161.1Skamil	}
7171.1Skamil
7181.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7191.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
7201.1Skamil
7211.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7221.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
7231.1Skamil
7241.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7251.26Skamil	if (raw)
7261.26Skamil		await_zombie_raw(tracee, 0);
7271.26Skamil	else
7281.26Skamil		await_zombie(tracee);
7291.1Skamil
7301.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
7311.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
7321.1Skamil	    TWAIT_FNAME);
7331.1Skamil	TWAIT_REQUIRE_SUCCESS(
7341.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7351.1Skamil
7361.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7371.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
7381.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
7391.1Skamil	    TWAIT_FNAME);
7401.1Skamil
7411.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7431.1Skamil	    tracer);
7441.1Skamil
7451.1Skamil	validate_status_exited(status, exitval_tracer);
7461.1Skamil
7471.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7481.1Skamil	    TWAIT_FNAME);
7491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7501.1Skamil	    tracee);
7511.1Skamil
7521.1Skamil	validate_status_exited(status, exitval_tracee);
7531.1Skamil
7541.1Skamil	msg_close(&parent_tracer);
7551.1Skamil	msg_close(&parent_tracee);
7561.1Skamil}
7571.26Skamil
7581.26SkamilATF_TC_BODY(attach1, tc)
7591.26Skamil{
7601.26Skamil
7611.26Skamil	/* Reuse this test with race1 */
7621.26Skamil	attach1_raw(false);
7631.26Skamil}
7641.26Skamil
7651.1Skamil#endif
7661.1Skamil
7671.1Skamil#if defined(TWAIT_HAVE_PID)
7681.1SkamilATF_TC(attach2);
7691.1SkamilATF_TC_HEAD(attach2, tc)
7701.1Skamil{
7711.1Skamil	atf_tc_set_md_var(tc, "descr",
7721.1Skamil	    "Assert that any tracer sees process termination before its "
7731.1Skamil	    "parent");
7741.1Skamil}
7751.1Skamil
7761.1SkamilATF_TC_BODY(attach2, tc)
7771.1Skamil{
7781.1Skamil	struct msg_fds parent_tracer, parent_tracee;
7791.1Skamil	const int exitval_tracee = 5;
7801.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
7811.1Skamil	pid_t tracee, tracer, wpid;
7821.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7831.1Skamil#if defined(TWAIT_HAVE_STATUS)
7841.1Skamil	int status;
7851.1Skamil#endif
7861.1Skamil
7871.13Schristos	DPRINTF("Spawn tracee\n");
7881.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7891.1Skamil	tracee = atf_utils_fork();
7901.1Skamil	if (tracee == 0) {
7911.1Skamil		/* Wait for message from the parent */
7921.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
7931.1Skamil		_exit(exitval_tracee);
7941.1Skamil	}
7951.1Skamil
7961.13Schristos	DPRINTF("Spawn debugger\n");
7971.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7981.1Skamil	tracer = atf_utils_fork();
7991.1Skamil	if (tracer == 0) {
8001.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
8011.1Skamil		tracer = atf_utils_fork();
8021.1Skamil		if (tracer != 0)
8031.1Skamil			_exit(exitval_tracer1);
8041.1Skamil
8051.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8061.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8071.1Skamil
8081.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8091.1Skamil		FORKEE_REQUIRE_SUCCESS(
8101.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8111.1Skamil
8121.1Skamil		forkee_status_stopped(status, SIGSTOP);
8131.1Skamil
8141.1Skamil		/* Resume tracee with PT_CONTINUE */
8151.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8161.1Skamil
8171.1Skamil		/* Inform parent that tracer has attached to tracee */
8181.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8191.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8201.1Skamil
8211.1Skamil		/* Wait for tracee and assert that it exited */
8221.1Skamil		FORKEE_REQUIRE_SUCCESS(
8231.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8241.1Skamil
8251.1Skamil		forkee_status_exited(status, exitval_tracee);
8261.1Skamil
8271.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8281.1Skamil		_exit(exitval_tracer2);
8291.1Skamil	}
8301.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
8311.1Skamil	    "%s()\n", TWAIT_FNAME);
8321.1Skamil	TWAIT_REQUIRE_SUCCESS(
8331.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
8341.1Skamil
8351.1Skamil	validate_status_exited(status, exitval_tracer1);
8361.1Skamil
8371.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
8381.1Skamil	    TWAIT_FNAME);
8391.1Skamil	TWAIT_REQUIRE_SUCCESS(
8401.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
8411.1Skamil
8421.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8431.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8441.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8451.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8461.1Skamil
8471.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8481.1Skamil	await_zombie(tracee);
8491.1Skamil
8501.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8511.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8521.1Skamil	TWAIT_REQUIRE_SUCCESS(
8531.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8541.1Skamil
8551.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8561.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8571.1Skamil
8581.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8591.1Skamil	    TWAIT_FNAME);
8601.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
8611.1Skamil	    tracee);
8621.1Skamil
8631.1Skamil	validate_status_exited(status, exitval_tracee);
8641.1Skamil
8651.1Skamil	msg_close(&parent_tracer);
8661.1Skamil	msg_close(&parent_tracee);
8671.1Skamil}
8681.1Skamil#endif
8691.1Skamil
8701.1SkamilATF_TC(attach3);
8711.1SkamilATF_TC_HEAD(attach3, tc)
8721.1Skamil{
8731.1Skamil	atf_tc_set_md_var(tc, "descr",
8741.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
8751.1Skamil}
8761.1Skamil
8771.1SkamilATF_TC_BODY(attach3, tc)
8781.1Skamil{
8791.1Skamil	struct msg_fds parent_tracee;
8801.1Skamil	const int exitval_tracee = 5;
8811.1Skamil	pid_t tracee, wpid;
8821.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8831.1Skamil#if defined(TWAIT_HAVE_STATUS)
8841.1Skamil	int status;
8851.1Skamil#endif
8861.1Skamil
8871.13Schristos	DPRINTF("Spawn tracee\n");
8881.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8891.1Skamil	tracee = atf_utils_fork();
8901.1Skamil	if (tracee == 0) {
8911.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
8921.13Schristos		DPRINTF("Parent should now attach to tracee\n");
8931.1Skamil
8941.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
8951.1Skamil		/* Wait for message from the parent */
8961.1Skamil		_exit(exitval_tracee);
8971.1Skamil	}
8981.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8991.1Skamil
9001.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
9011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9021.1Skamil
9031.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
9041.1Skamil	    TWAIT_FNAME);
9051.1Skamil	TWAIT_REQUIRE_SUCCESS(
9061.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9071.1Skamil
9081.1Skamil	validate_status_stopped(status, SIGSTOP);
9091.1Skamil
9101.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
9111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9121.1Skamil
9131.13Schristos	DPRINTF("Let the tracee exit now\n");
9141.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
9151.1Skamil
9161.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
9171.1Skamil	TWAIT_REQUIRE_SUCCESS(
9181.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9191.1Skamil
9201.1Skamil	validate_status_exited(status, exitval_tracee);
9211.1Skamil
9221.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
9231.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
9241.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
9251.1Skamil
9261.1Skamil	msg_close(&parent_tracee);
9271.1Skamil}
9281.1Skamil
9291.1SkamilATF_TC(attach4);
9301.1SkamilATF_TC_HEAD(attach4, tc)
9311.1Skamil{
9321.1Skamil	atf_tc_set_md_var(tc, "descr",
9331.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
9341.1Skamil}
9351.1Skamil
9361.1SkamilATF_TC_BODY(attach4, tc)
9371.1Skamil{
9381.1Skamil	struct msg_fds parent_tracee;
9391.1Skamil	const int exitval_tracer = 5;
9401.1Skamil	pid_t tracer, wpid;
9411.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
9421.1Skamil#if defined(TWAIT_HAVE_STATUS)
9431.1Skamil	int status;
9441.1Skamil#endif
9451.1Skamil
9461.13Schristos	DPRINTF("Spawn tracer\n");
9471.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9481.1Skamil	tracer = atf_utils_fork();
9491.1Skamil	if (tracer == 0) {
9501.1Skamil
9511.1Skamil		/* Wait for message from the parent */
9521.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
9531.1Skamil
9541.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
9551.1Skamil		    getppid());
9561.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
9571.1Skamil
9581.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
9591.1Skamil		    TWAIT_FNAME);
9601.1Skamil		FORKEE_REQUIRE_SUCCESS(
9611.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
9621.1Skamil
9631.1Skamil		forkee_status_stopped(status, SIGSTOP);
9641.1Skamil
9651.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
9661.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
9671.1Skamil		    != -1);
9681.1Skamil
9691.1Skamil		/* Tell parent we are ready */
9701.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
9711.1Skamil
9721.1Skamil		_exit(exitval_tracer);
9731.1Skamil	}
9741.1Skamil
9751.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
9761.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
9771.13Schristos	DPRINTF("Allow the tracer to exit now\n");
9781.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
9791.1Skamil
9801.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
9811.1Skamil	TWAIT_REQUIRE_SUCCESS(
9821.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
9831.1Skamil
9841.1Skamil	validate_status_exited(status, exitval_tracer);
9851.1Skamil
9861.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
9871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
9881.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
9891.1Skamil
9901.1Skamil	msg_close(&parent_tracee);
9911.1Skamil}
9921.1Skamil
9931.1Skamil#if defined(TWAIT_HAVE_PID)
9941.1SkamilATF_TC(attach5);
9951.1SkamilATF_TC_HEAD(attach5, tc)
9961.1Skamil{
9971.1Skamil	atf_tc_set_md_var(tc, "descr",
9981.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
9991.1Skamil	    "(check getppid(2))");
10001.1Skamil}
10011.1Skamil
10021.1SkamilATF_TC_BODY(attach5, tc)
10031.1Skamil{
10041.1Skamil	struct msg_fds parent_tracer, parent_tracee;
10051.1Skamil	const int exitval_tracee = 5;
10061.1Skamil	const int exitval_tracer = 10;
10071.1Skamil	pid_t parent, tracee, tracer, wpid;
10081.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
10091.1Skamil#if defined(TWAIT_HAVE_STATUS)
10101.1Skamil	int status;
10111.1Skamil#endif
10121.1Skamil
10131.13Schristos	DPRINTF("Spawn tracee\n");
10141.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
10151.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
10161.1Skamil	tracee = atf_utils_fork();
10171.1Skamil	if (tracee == 0) {
10181.1Skamil		parent = getppid();
10191.1Skamil
10201.1Skamil		/* Emit message to the parent */
10211.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
10221.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
10231.1Skamil
10241.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
10251.1Skamil
10261.1Skamil		_exit(exitval_tracee);
10271.1Skamil	}
10281.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
10291.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
10301.1Skamil
10311.13Schristos	DPRINTF("Spawn debugger\n");
10321.1Skamil	tracer = atf_utils_fork();
10331.1Skamil	if (tracer == 0) {
10341.1Skamil		/* No IPC to communicate with the child */
10351.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
10361.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
10371.1Skamil
10381.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
10391.1Skamil		FORKEE_REQUIRE_SUCCESS(
10401.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10411.1Skamil
10421.1Skamil		forkee_status_stopped(status, SIGSTOP);
10431.1Skamil
10441.1Skamil		/* Resume tracee with PT_CONTINUE */
10451.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
10461.1Skamil
10471.1Skamil		/* Inform parent that tracer has attached to tracee */
10481.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
10491.1Skamil
10501.1Skamil		/* Wait for parent to tell use that tracee should have exited */
10511.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
10521.1Skamil
10531.1Skamil		/* Wait for tracee and assert that it exited */
10541.1Skamil		FORKEE_REQUIRE_SUCCESS(
10551.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10561.1Skamil
10571.1Skamil		forkee_status_exited(status, exitval_tracee);
10581.1Skamil
10591.13Schristos		DPRINTF("Before exiting of the tracer process\n");
10601.1Skamil		_exit(exitval_tracer);
10611.1Skamil	}
10621.1Skamil
10631.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
10641.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
10651.1Skamil
10661.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
10671.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
10681.1Skamil
10691.13Schristos	DPRINTF("Detect that tracee is zombie\n");
10701.1Skamil	await_zombie(tracee);
10711.1Skamil
10721.13Schristos	DPRINTF("Assert that there is no status about tracee - "
10731.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
10741.1Skamil	TWAIT_REQUIRE_SUCCESS(
10751.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
10761.1Skamil
10771.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
10781.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
10791.1Skamil
10801.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
10811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
10821.1Skamil	    tracer);
10831.1Skamil
10841.1Skamil	validate_status_exited(status, exitval_tracer);
10851.1Skamil
10861.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
10871.1Skamil	    TWAIT_FNAME);
10881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
10891.1Skamil	    tracee);
10901.1Skamil
10911.1Skamil	validate_status_exited(status, exitval_tracee);
10921.1Skamil
10931.1Skamil	msg_close(&parent_tracer);
10941.1Skamil	msg_close(&parent_tracee);
10951.1Skamil}
10961.1Skamil#endif
10971.1Skamil
10981.1Skamil#if defined(TWAIT_HAVE_PID)
10991.1SkamilATF_TC(attach6);
11001.1SkamilATF_TC_HEAD(attach6, tc)
11011.1Skamil{
11021.1Skamil	atf_tc_set_md_var(tc, "descr",
11031.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
11041.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
11051.1Skamil}
11061.1Skamil
11071.1SkamilATF_TC_BODY(attach6, tc)
11081.1Skamil{
11091.1Skamil	struct msg_fds parent_tracee, parent_tracer;
11101.1Skamil	const int exitval_tracee = 5;
11111.1Skamil	const int exitval_tracer = 10;
11121.1Skamil	pid_t parent, tracee, tracer, wpid;
11131.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
11141.1Skamil#if defined(TWAIT_HAVE_STATUS)
11151.1Skamil	int status;
11161.1Skamil#endif
11171.1Skamil	int name[CTL_MAXNAME];
11181.1Skamil	struct kinfo_proc2 kp;
11191.1Skamil	size_t len = sizeof(kp);
11201.1Skamil	unsigned int namelen;
11211.1Skamil
11221.13Schristos	DPRINTF("Spawn tracee\n");
11231.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
11241.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
11251.1Skamil	tracee = atf_utils_fork();
11261.1Skamil	if (tracee == 0) {
11271.1Skamil		parent = getppid();
11281.1Skamil
11291.1Skamil		/* Emit message to the parent */
11301.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
11311.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
11321.1Skamil
11331.1Skamil		namelen = 0;
11341.1Skamil		name[namelen++] = CTL_KERN;
11351.1Skamil		name[namelen++] = KERN_PROC2;
11361.1Skamil		name[namelen++] = KERN_PROC_PID;
11371.1Skamil		name[namelen++] = getpid();
11381.1Skamil		name[namelen++] = len;
11391.1Skamil		name[namelen++] = 1;
11401.1Skamil
11411.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
11421.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
11431.1Skamil
11441.1Skamil		_exit(exitval_tracee);
11451.1Skamil	}
11461.1Skamil
11471.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
11481.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
11491.1Skamil
11501.13Schristos	DPRINTF("Spawn debugger\n");
11511.1Skamil	tracer = atf_utils_fork();
11521.1Skamil	if (tracer == 0) {
11531.1Skamil		/* No IPC to communicate with the child */
11541.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
11551.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
11561.1Skamil
11571.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
11581.1Skamil		FORKEE_REQUIRE_SUCCESS(
11591.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
11601.1Skamil
11611.1Skamil		forkee_status_stopped(status, SIGSTOP);
11621.1Skamil
11631.1Skamil		/* Resume tracee with PT_CONTINUE */
11641.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
11651.1Skamil
11661.1Skamil		/* Inform parent that tracer has attached to tracee */
11671.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
11681.1Skamil
11691.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
11701.1Skamil
11711.1Skamil		/* Wait for tracee and assert that it exited */
11721.1Skamil		FORKEE_REQUIRE_SUCCESS(
11731.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
11741.1Skamil
11751.1Skamil		forkee_status_exited(status, exitval_tracee);
11761.1Skamil
11771.13Schristos		DPRINTF("Before exiting of the tracer process\n");
11781.1Skamil		_exit(exitval_tracer);
11791.1Skamil	}
11801.1Skamil
11811.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
11821.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
11831.1Skamil
11841.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
11851.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
11861.1Skamil
11871.13Schristos	DPRINTF("Detect that tracee is zombie\n");
11881.1Skamil	await_zombie(tracee);
11891.1Skamil
11901.13Schristos	DPRINTF("Assert that there is no status about tracee - "
11911.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
11921.1Skamil	TWAIT_REQUIRE_SUCCESS(
11931.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
11941.1Skamil
11951.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
11961.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
11971.1Skamil
11981.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
11991.1Skamil	    TWAIT_FNAME);
12001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
12011.1Skamil	    tracer);
12021.1Skamil
12031.1Skamil	validate_status_exited(status, exitval_tracer);
12041.1Skamil
12051.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
12061.1Skamil	    TWAIT_FNAME);
12071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
12081.1Skamil	    tracee);
12091.1Skamil
12101.1Skamil	validate_status_exited(status, exitval_tracee);
12111.1Skamil
12121.1Skamil	msg_close(&parent_tracee);
12131.1Skamil	msg_close(&parent_tracer);
12141.1Skamil}
12151.1Skamil#endif
12161.1Skamil
12171.1Skamil#if defined(TWAIT_HAVE_PID)
12181.1SkamilATF_TC(attach7);
12191.1SkamilATF_TC_HEAD(attach7, tc)
12201.1Skamil{
12211.1Skamil	atf_tc_set_md_var(tc, "descr",
12221.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
12231.1Skamil	    "(check /proc/curproc/status 3rd column)");
12241.1Skamil}
12251.1Skamil
12261.1SkamilATF_TC_BODY(attach7, tc)
12271.1Skamil{
12281.1Skamil	struct msg_fds parent_tracee, parent_tracer;
12291.1Skamil	int rv;
12301.1Skamil	const int exitval_tracee = 5;
12311.1Skamil	const int exitval_tracer = 10;
12321.1Skamil	pid_t parent, tracee, tracer, wpid;
12331.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
12341.1Skamil#if defined(TWAIT_HAVE_STATUS)
12351.1Skamil	int status;
12361.1Skamil#endif
12371.1Skamil	FILE *fp;
12381.1Skamil	struct stat st;
12391.1Skamil	const char *fname = "/proc/curproc/status";
12401.1Skamil	char s_executable[MAXPATHLEN];
12411.1Skamil	int s_pid, s_ppid;
12421.1Skamil	/*
12431.1Skamil	 * Format:
12441.1Skamil	 *  EXECUTABLE PID PPID ...
12451.1Skamil	 */
12461.1Skamil
12471.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
12481.1Skamil	if (rv != 0) {
12491.1Skamil		atf_tc_skip("/proc/curproc/status not found");
12501.1Skamil	}
12511.1Skamil
12521.13Schristos	DPRINTF("Spawn tracee\n");
12531.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
12541.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
12551.1Skamil	tracee = atf_utils_fork();
12561.1Skamil	if (tracee == 0) {
12571.1Skamil		parent = getppid();
12581.1Skamil
12591.1Skamil		// Wait for parent to let us exit
12601.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
12611.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
12621.1Skamil
12631.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
12641.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
12651.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
12661.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
12671.1Skamil
12681.1Skamil		_exit(exitval_tracee);
12691.1Skamil	}
12701.1Skamil
12711.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
12721.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
12731.1Skamil
12741.13Schristos	DPRINTF("Spawn debugger\n");
12751.1Skamil	tracer = atf_utils_fork();
12761.1Skamil	if (tracer == 0) {
12771.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
12781.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
12791.1Skamil
12801.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
12811.1Skamil		FORKEE_REQUIRE_SUCCESS(
12821.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
12831.1Skamil
12841.1Skamil		forkee_status_stopped(status, SIGSTOP);
12851.1Skamil
12861.1Skamil		/* Resume tracee with PT_CONTINUE */
12871.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
12881.1Skamil
12891.1Skamil		/* Inform parent that tracer has attached to tracee */
12901.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
12911.1Skamil
12921.1Skamil		/* Wait for parent to tell use that tracee should have exited */
12931.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
12941.1Skamil
12951.1Skamil		/* Wait for tracee and assert that it exited */
12961.1Skamil		FORKEE_REQUIRE_SUCCESS(
12971.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
12981.1Skamil
12991.1Skamil		forkee_status_exited(status, exitval_tracee);
13001.1Skamil
13011.13Schristos		DPRINTF("Before exiting of the tracer process\n");
13021.1Skamil		_exit(exitval_tracer);
13031.1Skamil	}
13041.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
13051.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
13061.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
13071.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
13081.1Skamil
13091.13Schristos	DPRINTF("Detect that tracee is zombie\n");
13101.1Skamil	await_zombie(tracee);
13111.1Skamil
13121.13Schristos	DPRINTF("Assert that there is no status about tracee - "
13131.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
13141.1Skamil	TWAIT_REQUIRE_SUCCESS(
13151.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
13161.1Skamil
13171.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
13181.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
13191.1Skamil
13201.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
13211.1Skamil	    TWAIT_FNAME);
13221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
13231.1Skamil	    tracer);
13241.1Skamil
13251.1Skamil	validate_status_exited(status, exitval_tracer);
13261.1Skamil
13271.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
13281.1Skamil	    TWAIT_FNAME);
13291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
13301.1Skamil	    tracee);
13311.1Skamil
13321.1Skamil	validate_status_exited(status, exitval_tracee);
13331.1Skamil
13341.1Skamil	msg_close(&parent_tracee);
13351.1Skamil	msg_close(&parent_tracer);
13361.1Skamil}
13371.1Skamil#endif
13381.1Skamil
13391.1SkamilATF_TC(eventmask1);
13401.1SkamilATF_TC_HEAD(eventmask1, tc)
13411.1Skamil{
13421.1Skamil	atf_tc_set_md_var(tc, "descr",
13431.1Skamil	    "Verify that empty EVENT_MASK is preserved");
13441.1Skamil}
13451.1Skamil
13461.1SkamilATF_TC_BODY(eventmask1, tc)
13471.1Skamil{
13481.1Skamil	const int exitval = 5;
13491.1Skamil	const int sigval = SIGSTOP;
13501.1Skamil	pid_t child, wpid;
13511.1Skamil#if defined(TWAIT_HAVE_STATUS)
13521.1Skamil	int status;
13531.1Skamil#endif
13541.1Skamil	ptrace_event_t set_event, get_event;
13551.1Skamil	const int len = sizeof(ptrace_event_t);
13561.1Skamil
13571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13591.1Skamil	if (child == 0) {
13601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13621.1Skamil
13631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13651.1Skamil
13661.13Schristos		DPRINTF("Before exiting of the child process\n");
13671.1Skamil		_exit(exitval);
13681.1Skamil	}
13691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13701.1Skamil
13711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13731.1Skamil
13741.1Skamil	validate_status_stopped(status, sigval);
13751.1Skamil
13761.1Skamil	set_event.pe_set_event = 0;
13771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13791.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13801.1Skamil
13811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13821.1Skamil	    "without signal to be sent\n");
13831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13841.1Skamil
13851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13871.1Skamil
13881.1Skamil	validate_status_exited(status, exitval);
13891.1Skamil
13901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13921.1Skamil}
13931.1Skamil
13941.1SkamilATF_TC(eventmask2);
13951.1SkamilATF_TC_HEAD(eventmask2, tc)
13961.1Skamil{
13971.1Skamil	atf_tc_set_md_var(tc, "descr",
13981.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
13991.1Skamil}
14001.1Skamil
14011.1SkamilATF_TC_BODY(eventmask2, tc)
14021.1Skamil{
14031.1Skamil	const int exitval = 5;
14041.1Skamil	const int sigval = SIGSTOP;
14051.1Skamil	pid_t child, wpid;
14061.1Skamil#if defined(TWAIT_HAVE_STATUS)
14071.1Skamil	int status;
14081.1Skamil#endif
14091.1Skamil	ptrace_event_t set_event, get_event;
14101.1Skamil	const int len = sizeof(ptrace_event_t);
14111.1Skamil
14121.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14131.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14141.1Skamil	if (child == 0) {
14151.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14161.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14171.1Skamil
14181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14201.1Skamil
14211.13Schristos		DPRINTF("Before exiting of the child process\n");
14221.1Skamil		_exit(exitval);
14231.1Skamil	}
14241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14251.1Skamil
14261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14281.1Skamil
14291.1Skamil	validate_status_stopped(status, sigval);
14301.1Skamil
14311.1Skamil	set_event.pe_set_event = PTRACE_FORK;
14321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
14331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
14341.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
14351.1Skamil
14361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14371.1Skamil	    "without signal to be sent\n");
14381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14391.1Skamil
14401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14421.1Skamil
14431.1Skamil	validate_status_exited(status, exitval);
14441.1Skamil
14451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14471.1Skamil}
14481.1Skamil
14491.1SkamilATF_TC(eventmask3);
14501.1SkamilATF_TC_HEAD(eventmask3, tc)
14511.1Skamil{
14521.1Skamil	atf_tc_set_md_var(tc, "descr",
14531.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
14541.1Skamil}
14551.1Skamil
14561.1SkamilATF_TC_BODY(eventmask3, tc)
14571.1Skamil{
14581.1Skamil	const int exitval = 5;
14591.1Skamil	const int sigval = SIGSTOP;
14601.1Skamil	pid_t child, wpid;
14611.1Skamil#if defined(TWAIT_HAVE_STATUS)
14621.1Skamil	int status;
14631.1Skamil#endif
14641.1Skamil	ptrace_event_t set_event, get_event;
14651.1Skamil	const int len = sizeof(ptrace_event_t);
14661.1Skamil
14671.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14681.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14691.1Skamil	if (child == 0) {
14701.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14711.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14721.1Skamil
14731.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14741.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14751.1Skamil
14761.13Schristos		DPRINTF("Before exiting of the child process\n");
14771.1Skamil		_exit(exitval);
14781.1Skamil	}
14791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14801.1Skamil
14811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14831.1Skamil
14841.1Skamil	validate_status_stopped(status, sigval);
14851.1Skamil
14861.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
14871.38Skamil	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
14881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
14891.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
14901.1Skamil
14911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14921.1Skamil	    "without signal to be sent\n");
14931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14941.1Skamil
14951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14971.1Skamil
14981.1Skamil	validate_status_exited(status, exitval);
14991.1Skamil
15001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15021.1Skamil}
15031.1Skamil
15041.1SkamilATF_TC(eventmask4);
15051.1SkamilATF_TC_HEAD(eventmask4, tc)
15061.1Skamil{
15071.1Skamil	atf_tc_set_md_var(tc, "descr",
15081.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
15091.1Skamil}
15101.1Skamil
15111.1SkamilATF_TC_BODY(eventmask4, tc)
15121.1Skamil{
15131.1Skamil	const int exitval = 5;
15141.1Skamil	const int sigval = SIGSTOP;
15151.1Skamil	pid_t child, wpid;
15161.1Skamil#if defined(TWAIT_HAVE_STATUS)
15171.1Skamil	int status;
15181.1Skamil#endif
15191.1Skamil	ptrace_event_t set_event, get_event;
15201.1Skamil	const int len = sizeof(ptrace_event_t);
15211.1Skamil
15221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15241.1Skamil	if (child == 0) {
15251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15271.1Skamil
15281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15301.1Skamil
15311.13Schristos		DPRINTF("Before exiting of the child process\n");
15321.1Skamil		_exit(exitval);
15331.1Skamil	}
15341.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15351.1Skamil
15361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15381.1Skamil
15391.1Skamil	validate_status_stopped(status, sigval);
15401.1Skamil
15411.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
15421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
15431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
15441.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
15451.1Skamil
15461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15471.1Skamil	    "without signal to be sent\n");
15481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15491.1Skamil
15501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15521.1Skamil
15531.1Skamil	validate_status_exited(status, exitval);
15541.1Skamil
15551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15561.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15571.1Skamil}
15581.1Skamil
15591.1SkamilATF_TC(eventmask5);
15601.1SkamilATF_TC_HEAD(eventmask5, tc)
15611.1Skamil{
15621.1Skamil	atf_tc_set_md_var(tc, "descr",
15631.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
15641.1Skamil}
15651.1Skamil
15661.1SkamilATF_TC_BODY(eventmask5, tc)
15671.1Skamil{
15681.1Skamil	const int exitval = 5;
15691.1Skamil	const int sigval = SIGSTOP;
15701.1Skamil	pid_t child, wpid;
15711.1Skamil#if defined(TWAIT_HAVE_STATUS)
15721.1Skamil	int status;
15731.1Skamil#endif
15741.1Skamil	ptrace_event_t set_event, get_event;
15751.1Skamil	const int len = sizeof(ptrace_event_t);
15761.1Skamil
15771.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15781.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15791.1Skamil	if (child == 0) {
15801.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15811.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15821.1Skamil
15831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15851.1Skamil
15861.13Schristos		DPRINTF("Before exiting of the child process\n");
15871.1Skamil		_exit(exitval);
15881.1Skamil	}
15891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15901.1Skamil
15911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15931.1Skamil
15941.1Skamil	validate_status_stopped(status, sigval);
15951.1Skamil
15961.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
15971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
15981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
15991.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
16001.1Skamil
16011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16021.1Skamil	    "without signal to be sent\n");
16031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16041.1Skamil
16051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16071.1Skamil
16081.1Skamil	validate_status_exited(status, exitval);
16091.1Skamil
16101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16121.1Skamil}
16131.1Skamil
16141.1SkamilATF_TC(eventmask6);
16151.1SkamilATF_TC_HEAD(eventmask6, tc)
16161.1Skamil{
16171.1Skamil	atf_tc_set_md_var(tc, "descr",
16181.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
16191.1Skamil}
16201.1Skamil
16211.1SkamilATF_TC_BODY(eventmask6, tc)
16221.1Skamil{
16231.1Skamil	const int exitval = 5;
16241.1Skamil	const int sigval = SIGSTOP;
16251.1Skamil	pid_t child, wpid;
16261.1Skamil#if defined(TWAIT_HAVE_STATUS)
16271.1Skamil	int status;
16281.1Skamil#endif
16291.1Skamil	ptrace_event_t set_event, get_event;
16301.1Skamil	const int len = sizeof(ptrace_event_t);
16311.1Skamil
16321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16341.1Skamil	if (child == 0) {
16351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16371.1Skamil
16381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16401.1Skamil
16411.13Schristos		DPRINTF("Before exiting of the child process\n");
16421.1Skamil		_exit(exitval);
16431.1Skamil	}
16441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16451.1Skamil
16461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16481.1Skamil
16491.1Skamil	validate_status_stopped(status, sigval);
16501.1Skamil
16511.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
16521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
16531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
16541.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
16551.1Skamil
16561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16571.1Skamil	    "without signal to be sent\n");
16581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16591.1Skamil
16601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16621.1Skamil
16631.1Skamil	validate_status_exited(status, exitval);
16641.1Skamil
16651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16671.1Skamil}
16681.1Skamil
16691.28Skamilstatic void
16701.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
16711.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
16721.1Skamil{
16731.1Skamil	const int exitval = 5;
16741.1Skamil	const int exitval2 = 15;
16751.1Skamil	const int sigval = SIGSTOP;
16761.31Skamil	pid_t child, child2 = 0, wpid;
16771.1Skamil#if defined(TWAIT_HAVE_STATUS)
16781.1Skamil	int status;
16791.1Skamil#endif
16801.1Skamil	ptrace_state_t state;
16811.1Skamil	const int slen = sizeof(state);
16821.1Skamil	ptrace_event_t event;
16831.1Skamil	const int elen = sizeof(event);
16841.1Skamil
16851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16871.1Skamil	if (child == 0) {
16881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16901.1Skamil
16911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16931.1Skamil
16941.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
16951.1Skamil
16961.1Skamil		if (child2 == 0)
16971.1Skamil			_exit(exitval2);
16981.1Skamil
16991.1Skamil		FORKEE_REQUIRE_SUCCESS
17001.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
17011.1Skamil
17021.1Skamil		forkee_status_exited(status, exitval2);
17031.1Skamil
17041.13Schristos		DPRINTF("Before exiting of the child process\n");
17051.1Skamil		_exit(exitval);
17061.1Skamil	}
17071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17081.1Skamil
17091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17111.1Skamil
17121.1Skamil	validate_status_stopped(status, sigval);
17131.1Skamil
17141.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
17151.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
17161.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
17171.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
17181.30Skamil	event.pe_set_event = 0;
17191.30Skamil	if (trackfork)
17201.30Skamil		event.pe_set_event |= PTRACE_FORK;
17211.30Skamil	if (trackvfork)
17221.30Skamil		event.pe_set_event |= PTRACE_VFORK;
17231.30Skamil	if (trackvforkdone)
17241.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
17251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17261.1Skamil
17271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17281.1Skamil	    "without signal to be sent\n");
17291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17301.1Skamil
17311.29Skamil#if defined(TWAIT_HAVE_PID)
17321.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
17331.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
17341.29Skamil		        child);
17351.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
17361.29Skamil		                      child);
17371.1Skamil
17381.29Skamil		validate_status_stopped(status, SIGTRAP);
17391.1Skamil
17401.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
17411.29Skamil		                       slen) != -1);
17421.31Skamil		if (trackfork && fn == fork) {
17431.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
17441.30Skamil			       PTRACE_FORK);
17451.30Skamil		}
17461.31Skamil		if (trackvfork && fn == vfork) {
17471.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
17481.30Skamil			       PTRACE_VFORK);
17491.30Skamil		}
17501.29Skamil
17511.29Skamil		child2 = state.pe_other_pid;
17521.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
17531.29Skamil
17541.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
17551.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
17561.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
17571.29Skamil		    child2);
17581.1Skamil
17591.29Skamil		validate_status_stopped(status, SIGTRAP);
17601.1Skamil
17611.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
17621.29Skamil		                       slen) != -1);
17631.31Skamil		if (trackfork && fn == fork) {
17641.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
17651.30Skamil			       PTRACE_FORK);
17661.30Skamil		}
17671.31Skamil		if (trackvfork && fn == vfork) {
17681.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
17691.30Skamil			       PTRACE_VFORK);
17701.30Skamil		}
17711.30Skamil
17721.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
17731.29Skamil
17741.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
17751.29Skamil		    "and without signal to be sent\n");
17761.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
17771.29Skamil		                != -1);
17781.29Skamil
17791.29Skamil		DPRINTF("Before resuming the child process where it left off "
17801.29Skamil		        "and without signal to be sent\n");
17811.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17821.30Skamil	}
17831.30Skamil#endif
17841.30Skamil
17851.31Skamil	if (trackvforkdone && fn == vfork) {
17861.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
17871.30Skamil		        child);
17881.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
17891.30Skamil		                      child);
17901.30Skamil
17911.30Skamil		validate_status_stopped(status, SIGTRAP);
17921.30Skamil
17931.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
17941.30Skamil		                       slen) != -1);
17951.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
17961.30Skamil
17971.30Skamil		child2 = state.pe_other_pid;
17981.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
17991.30Skamil		        child2);
18001.30Skamil
18011.30Skamil		DPRINTF("Before resuming the child process where it left off "
18021.30Skamil		        "and without signal to be sent\n");
18031.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18041.30Skamil	}
18051.29Skamil
18061.30Skamil#if defined(TWAIT_HAVE_PID)
18071.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
18081.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
18091.29Skamil		        "\n", TWAIT_FNAME);
18101.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
18111.29Skamil		    child2);
18121.29Skamil
18131.29Skamil		validate_status_exited(status, exitval2);
18141.29Skamil
18151.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
18161.29Skamil		        "process\n", TWAIT_FNAME);
18171.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
18181.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
18191.29Skamil	}
18201.29Skamil#endif
18211.1Skamil
18221.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18231.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18251.1Skamil
18261.1Skamil	validate_status_stopped(status, SIGCHLD);
18271.1Skamil
18281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18291.1Skamil	    "without signal to be sent\n");
18301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18311.1Skamil
18321.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
18331.1Skamil	    TWAIT_FNAME);
18341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18351.1Skamil
18361.1Skamil	validate_status_exited(status, exitval);
18371.1Skamil
18381.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
18391.1Skamil	    TWAIT_FNAME);
18401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18411.1Skamil}
18421.28Skamil
18431.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
18441.32SkamilATF_TC(name);									\
18451.32SkamilATF_TC_HEAD(name, tc)								\
18461.32Skamil{										\
18471.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
18481.32Skamil}										\
18491.32Skamil										\
18501.32SkamilATF_TC_BODY(name, tc)								\
18511.32Skamil{										\
18521.32Skamil										\
18531.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
18541.32Skamil}
18551.32Skamil
18561.32Skamil#define F false
18571.32Skamil#define T true
18581.32Skamil
18591.32Skamil#define F_IF__0(x)
18601.32Skamil#define F_IF__1(x) x
18611.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
18621.32Skamil#define F_IF_(x,y) F_IF__(x,y)
18631.32Skamil#define F_IF(x,y) F_IF_(x,y)
18641.32Skamil
18651.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
18661.32Skamil        "Verify " #function "(2) called with 0"					\
18671.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
18681.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
18691.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
18701.32Skamil        " in EVENT_MASK."							\
18711.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
18721.32Skamil        F_IF(dparentbit," Detach parent in this test.")
18731.1Skamil
18741.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
18751.31Skamil#if defined(TWAIT_HAVE_PID)
18761.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
18771.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
18781.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
18791.31Skamil#endif
18801.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
18811.31Skamil#if defined(TWAIT_HAVE_PID)
18821.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
18831.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
18841.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
18851.31Skamil#endif
18861.1Skamil
18871.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
18881.31Skamil#if defined(TWAIT_HAVE_PID)
18891.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
18901.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
18911.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
18921.31Skamil#endif
18931.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
18941.31Skamil#if defined(TWAIT_HAVE_PID)
18951.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
18961.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
18971.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
18981.31Skamil#endif
18991.31Skamil
19001.31Skamil
19011.31Skamil
19021.1Skamil
19031.1SkamilATF_TC(io_read_d1);
19041.1SkamilATF_TC_HEAD(io_read_d1, tc)
19051.1Skamil{
19061.1Skamil	atf_tc_set_md_var(tc, "descr",
19071.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
19081.1Skamil}
19091.1Skamil
19101.1SkamilATF_TC_BODY(io_read_d1, tc)
19111.1Skamil{
19121.1Skamil	const int exitval = 5;
19131.1Skamil	const int sigval = SIGSTOP;
19141.1Skamil	pid_t child, wpid;
19151.1Skamil	uint8_t lookup_me = 0;
19161.1Skamil	const uint8_t magic = 0xab;
19171.1Skamil	struct ptrace_io_desc io = {
19181.1Skamil		.piod_op = PIOD_READ_D,
19191.1Skamil		.piod_offs = &lookup_me,
19201.1Skamil		.piod_addr = &lookup_me,
19211.1Skamil		.piod_len = sizeof(lookup_me)
19221.1Skamil	};
19231.1Skamil#if defined(TWAIT_HAVE_STATUS)
19241.1Skamil	int status;
19251.1Skamil#endif
19261.1Skamil
19271.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19281.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19291.1Skamil	if (child == 0) {
19301.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19311.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19321.1Skamil
19331.1Skamil		lookup_me = magic;
19341.1Skamil
19351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19371.1Skamil
19381.13Schristos		DPRINTF("Before exiting of the child process\n");
19391.1Skamil		_exit(exitval);
19401.1Skamil	}
19411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19421.1Skamil
19431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19451.1Skamil
19461.1Skamil	validate_status_stopped(status, sigval);
19471.1Skamil
19481.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19491.1Skamil	    child, getpid());
19501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19511.1Skamil
19521.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19531.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
19541.1Skamil
19551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19561.1Skamil	    "without signal to be sent\n");
19571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19581.1Skamil
19591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19611.1Skamil
19621.1Skamil	validate_status_exited(status, exitval);
19631.1Skamil
19641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19661.1Skamil}
19671.1Skamil
19681.1SkamilATF_TC(io_read_d2);
19691.1SkamilATF_TC_HEAD(io_read_d2, tc)
19701.1Skamil{
19711.1Skamil	atf_tc_set_md_var(tc, "descr",
19721.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
19731.1Skamil}
19741.1Skamil
19751.1SkamilATF_TC_BODY(io_read_d2, tc)
19761.1Skamil{
19771.1Skamil	const int exitval = 5;
19781.1Skamil	const int sigval = SIGSTOP;
19791.1Skamil	pid_t child, wpid;
19801.1Skamil	uint16_t lookup_me = 0;
19811.1Skamil	const uint16_t magic = 0x1234;
19821.1Skamil	struct ptrace_io_desc io = {
19831.1Skamil		.piod_op = PIOD_READ_D,
19841.1Skamil		.piod_offs = &lookup_me,
19851.1Skamil		.piod_addr = &lookup_me,
19861.1Skamil		.piod_len = sizeof(lookup_me)
19871.1Skamil	};
19881.1Skamil#if defined(TWAIT_HAVE_STATUS)
19891.1Skamil	int status;
19901.1Skamil#endif
19911.1Skamil
19921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19941.1Skamil	if (child == 0) {
19951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19971.1Skamil
19981.1Skamil		lookup_me = magic;
19991.1Skamil
20001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20021.1Skamil
20031.13Schristos		DPRINTF("Before exiting of the child process\n");
20041.1Skamil		_exit(exitval);
20051.1Skamil	}
20061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20071.1Skamil
20081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20101.1Skamil
20111.1Skamil	validate_status_stopped(status, sigval);
20121.1Skamil
20131.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20141.1Skamil	    child, getpid());
20151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20161.1Skamil
20171.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20181.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
20191.1Skamil
20201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20211.1Skamil	    "without signal to be sent\n");
20221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20231.1Skamil
20241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20261.1Skamil
20271.1Skamil	validate_status_exited(status, exitval);
20281.1Skamil
20291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20311.1Skamil}
20321.1Skamil
20331.1SkamilATF_TC(io_read_d3);
20341.1SkamilATF_TC_HEAD(io_read_d3, tc)
20351.1Skamil{
20361.1Skamil	atf_tc_set_md_var(tc, "descr",
20371.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
20381.1Skamil}
20391.1Skamil
20401.1SkamilATF_TC_BODY(io_read_d3, tc)
20411.1Skamil{
20421.1Skamil	const int exitval = 5;
20431.1Skamil	const int sigval = SIGSTOP;
20441.1Skamil	pid_t child, wpid;
20451.1Skamil	uint32_t lookup_me = 0;
20461.1Skamil	const uint32_t magic = 0x1234abcd;
20471.1Skamil	struct ptrace_io_desc io = {
20481.1Skamil		.piod_op = PIOD_READ_D,
20491.1Skamil		.piod_offs = &lookup_me,
20501.1Skamil		.piod_addr = &lookup_me,
20511.1Skamil		.piod_len = sizeof(lookup_me)
20521.1Skamil	};
20531.1Skamil#if defined(TWAIT_HAVE_STATUS)
20541.1Skamil	int status;
20551.1Skamil#endif
20561.1Skamil
20571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20591.1Skamil	if (child == 0) {
20601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20621.1Skamil
20631.1Skamil		lookup_me = magic;
20641.1Skamil
20651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20671.1Skamil
20681.13Schristos		DPRINTF("Before exiting of the child process\n");
20691.1Skamil		_exit(exitval);
20701.1Skamil	}
20711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20721.1Skamil
20731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20751.1Skamil
20761.1Skamil	validate_status_stopped(status, sigval);
20771.1Skamil
20781.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20791.1Skamil	    child, getpid());
20801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20811.1Skamil
20821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20831.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
20841.1Skamil
20851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20861.1Skamil	    "without signal to be sent\n");
20871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20881.1Skamil
20891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20911.1Skamil
20921.1Skamil	validate_status_exited(status, exitval);
20931.1Skamil
20941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20961.1Skamil}
20971.1Skamil
20981.1SkamilATF_TC(io_read_d4);
20991.1SkamilATF_TC_HEAD(io_read_d4, tc)
21001.1Skamil{
21011.1Skamil	atf_tc_set_md_var(tc, "descr",
21021.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
21031.1Skamil}
21041.1Skamil
21051.1SkamilATF_TC_BODY(io_read_d4, tc)
21061.1Skamil{
21071.1Skamil	const int exitval = 5;
21081.1Skamil	const int sigval = SIGSTOP;
21091.1Skamil	pid_t child, wpid;
21101.1Skamil	uint64_t lookup_me = 0;
21111.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
21121.1Skamil	struct ptrace_io_desc io = {
21131.1Skamil		.piod_op = PIOD_READ_D,
21141.1Skamil		.piod_offs = &lookup_me,
21151.1Skamil		.piod_addr = &lookup_me,
21161.1Skamil		.piod_len = sizeof(lookup_me)
21171.1Skamil	};
21181.1Skamil#if defined(TWAIT_HAVE_STATUS)
21191.1Skamil	int status;
21201.1Skamil#endif
21211.1Skamil
21221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21241.1Skamil	if (child == 0) {
21251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21271.1Skamil
21281.1Skamil		lookup_me = magic;
21291.1Skamil
21301.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21311.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21321.1Skamil
21331.13Schristos		DPRINTF("Before exiting of the child process\n");
21341.1Skamil		_exit(exitval);
21351.1Skamil	}
21361.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21371.1Skamil
21381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21401.1Skamil
21411.1Skamil	validate_status_stopped(status, sigval);
21421.1Skamil
21431.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21441.1Skamil	    child, getpid());
21451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21461.1Skamil
21471.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21481.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
21491.1Skamil
21501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21511.1Skamil	    "without signal to be sent\n");
21521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21531.1Skamil
21541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21561.1Skamil
21571.1Skamil	validate_status_exited(status, exitval);
21581.1Skamil
21591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21611.1Skamil}
21621.1Skamil
21631.1SkamilATF_TC(io_write_d1);
21641.1SkamilATF_TC_HEAD(io_write_d1, tc)
21651.1Skamil{
21661.1Skamil	atf_tc_set_md_var(tc, "descr",
21671.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
21681.1Skamil}
21691.1Skamil
21701.1SkamilATF_TC_BODY(io_write_d1, tc)
21711.1Skamil{
21721.1Skamil	const int exitval = 5;
21731.1Skamil	const int sigval = SIGSTOP;
21741.1Skamil	pid_t child, wpid;
21751.1Skamil	uint8_t lookup_me = 0;
21761.1Skamil	const uint8_t magic = 0xab;
21771.1Skamil	struct ptrace_io_desc io = {
21781.1Skamil		.piod_op = PIOD_WRITE_D,
21791.1Skamil		.piod_offs = &lookup_me,
21801.1Skamil		.piod_addr = &lookup_me,
21811.1Skamil		.piod_len = sizeof(lookup_me)
21821.1Skamil	};
21831.1Skamil#if defined(TWAIT_HAVE_STATUS)
21841.1Skamil	int status;
21851.1Skamil#endif
21861.1Skamil
21871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21891.1Skamil	if (child == 0) {
21901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21921.1Skamil
21931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21951.1Skamil
21961.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
21971.1Skamil
21981.13Schristos		DPRINTF("Before exiting of the child process\n");
21991.1Skamil		_exit(exitval);
22001.1Skamil	}
22011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22021.1Skamil
22031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22051.1Skamil
22061.1Skamil	validate_status_stopped(status, sigval);
22071.1Skamil
22081.1Skamil	lookup_me = magic;
22091.1Skamil
22101.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22111.1Skamil	    child, getpid());
22121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22131.1Skamil
22141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22151.1Skamil	    "without signal to be sent\n");
22161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22171.1Skamil
22181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22201.1Skamil
22211.1Skamil	validate_status_exited(status, exitval);
22221.1Skamil
22231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22251.1Skamil}
22261.1Skamil
22271.1SkamilATF_TC(io_write_d2);
22281.1SkamilATF_TC_HEAD(io_write_d2, tc)
22291.1Skamil{
22301.1Skamil	atf_tc_set_md_var(tc, "descr",
22311.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
22321.1Skamil}
22331.1Skamil
22341.1SkamilATF_TC_BODY(io_write_d2, tc)
22351.1Skamil{
22361.1Skamil	const int exitval = 5;
22371.1Skamil	const int sigval = SIGSTOP;
22381.1Skamil	pid_t child, wpid;
22391.1Skamil	uint16_t lookup_me = 0;
22401.1Skamil	const uint16_t magic = 0xab12;
22411.1Skamil	struct ptrace_io_desc io = {
22421.1Skamil		.piod_op = PIOD_WRITE_D,
22431.1Skamil		.piod_offs = &lookup_me,
22441.1Skamil		.piod_addr = &lookup_me,
22451.1Skamil		.piod_len = sizeof(lookup_me)
22461.1Skamil	};
22471.1Skamil#if defined(TWAIT_HAVE_STATUS)
22481.1Skamil	int status;
22491.1Skamil#endif
22501.1Skamil
22511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22531.1Skamil	if (child == 0) {
22541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22561.1Skamil
22571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22591.1Skamil
22601.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22611.1Skamil
22621.13Schristos		DPRINTF("Before exiting of the child process\n");
22631.1Skamil		_exit(exitval);
22641.1Skamil	}
22651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22661.1Skamil
22671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22691.1Skamil
22701.1Skamil	validate_status_stopped(status, sigval);
22711.1Skamil
22721.1Skamil	lookup_me = magic;
22731.1Skamil
22741.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22751.1Skamil	    child, getpid());
22761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22771.1Skamil
22781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22791.1Skamil	    "without signal to be sent\n");
22801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22811.1Skamil
22821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22841.1Skamil
22851.1Skamil	validate_status_exited(status, exitval);
22861.1Skamil
22871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22881.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22891.1Skamil}
22901.1Skamil
22911.1SkamilATF_TC(io_write_d3);
22921.1SkamilATF_TC_HEAD(io_write_d3, tc)
22931.1Skamil{
22941.1Skamil	atf_tc_set_md_var(tc, "descr",
22951.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
22961.1Skamil}
22971.1Skamil
22981.1SkamilATF_TC_BODY(io_write_d3, tc)
22991.1Skamil{
23001.1Skamil	const int exitval = 5;
23011.1Skamil	const int sigval = SIGSTOP;
23021.1Skamil	pid_t child, wpid;
23031.1Skamil	uint32_t lookup_me = 0;
23041.1Skamil	const uint32_t magic = 0xab127643;
23051.1Skamil	struct ptrace_io_desc io = {
23061.1Skamil		.piod_op = PIOD_WRITE_D,
23071.1Skamil		.piod_offs = &lookup_me,
23081.1Skamil		.piod_addr = &lookup_me,
23091.1Skamil		.piod_len = sizeof(lookup_me)
23101.1Skamil	};
23111.1Skamil#if defined(TWAIT_HAVE_STATUS)
23121.1Skamil	int status;
23131.1Skamil#endif
23141.1Skamil
23151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23171.1Skamil	if (child == 0) {
23181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23201.1Skamil
23211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23231.1Skamil
23241.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23251.1Skamil
23261.13Schristos		DPRINTF("Before exiting of the child process\n");
23271.1Skamil		_exit(exitval);
23281.1Skamil	}
23291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23301.1Skamil
23311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23331.1Skamil
23341.1Skamil	validate_status_stopped(status, sigval);
23351.1Skamil
23361.1Skamil	lookup_me = magic;
23371.1Skamil
23381.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23391.1Skamil	    child, getpid());
23401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23411.1Skamil
23421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23431.1Skamil	    "without signal to be sent\n");
23441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23451.1Skamil
23461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23481.1Skamil
23491.1Skamil	validate_status_exited(status, exitval);
23501.1Skamil
23511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23521.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23531.1Skamil}
23541.1Skamil
23551.1SkamilATF_TC(io_write_d4);
23561.1SkamilATF_TC_HEAD(io_write_d4, tc)
23571.1Skamil{
23581.1Skamil	atf_tc_set_md_var(tc, "descr",
23591.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
23601.1Skamil}
23611.1Skamil
23621.1SkamilATF_TC_BODY(io_write_d4, tc)
23631.1Skamil{
23641.1Skamil	const int exitval = 5;
23651.1Skamil	const int sigval = SIGSTOP;
23661.1Skamil	pid_t child, wpid;
23671.1Skamil	uint64_t lookup_me = 0;
23681.1Skamil	const uint64_t magic = 0xab12764376490123;
23691.1Skamil	struct ptrace_io_desc io = {
23701.1Skamil		.piod_op = PIOD_WRITE_D,
23711.1Skamil		.piod_offs = &lookup_me,
23721.1Skamil		.piod_addr = &lookup_me,
23731.1Skamil		.piod_len = sizeof(lookup_me)
23741.1Skamil	};
23751.1Skamil#if defined(TWAIT_HAVE_STATUS)
23761.1Skamil	int status;
23771.1Skamil#endif
23781.1Skamil
23791.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23801.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23811.1Skamil	if (child == 0) {
23821.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23831.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23841.1Skamil
23851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23871.1Skamil
23881.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23891.1Skamil
23901.13Schristos		DPRINTF("Before exiting of the child process\n");
23911.1Skamil		_exit(exitval);
23921.1Skamil	}
23931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23941.1Skamil
23951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23971.1Skamil
23981.1Skamil	validate_status_stopped(status, sigval);
23991.1Skamil
24001.1Skamil	lookup_me = magic;
24011.1Skamil
24021.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24031.1Skamil	    child, getpid());
24041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24051.1Skamil
24061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24071.1Skamil	    "without signal to be sent\n");
24081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24091.1Skamil
24101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24121.1Skamil
24131.1Skamil	validate_status_exited(status, exitval);
24141.1Skamil
24151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24171.1Skamil}
24181.1Skamil
24191.1SkamilATF_TC(io_read_auxv1);
24201.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
24211.1Skamil{
24221.1Skamil	atf_tc_set_md_var(tc, "descr",
24231.1Skamil	    "Verify PT_READ_AUXV called for tracee");
24241.1Skamil}
24251.1Skamil
24261.1SkamilATF_TC_BODY(io_read_auxv1, tc)
24271.1Skamil{
24281.1Skamil	const int exitval = 5;
24291.1Skamil	const int sigval = SIGSTOP;
24301.1Skamil	pid_t child, wpid;
24311.1Skamil#if defined(TWAIT_HAVE_STATUS)
24321.1Skamil	int status;
24331.1Skamil#endif
24341.1Skamil	AuxInfo ai[100], *aip;
24351.1Skamil	struct ptrace_io_desc io = {
24361.1Skamil		.piod_op = PIOD_READ_AUXV,
24371.1Skamil		.piod_offs = 0,
24381.1Skamil		.piod_addr = ai,
24391.1Skamil		.piod_len = sizeof(ai)
24401.1Skamil	};
24411.1Skamil
24421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24441.1Skamil	if (child == 0) {
24451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24471.1Skamil
24481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24501.1Skamil
24511.13Schristos		DPRINTF("Before exiting of the child process\n");
24521.1Skamil		_exit(exitval);
24531.1Skamil	}
24541.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24551.1Skamil
24561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24581.1Skamil
24591.1Skamil	validate_status_stopped(status, sigval);
24601.1Skamil
24611.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
24621.1Skamil	    child, getpid());
24631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24641.1Skamil
24651.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
24661.1Skamil	ATF_REQUIRE(io.piod_len > 0);
24671.1Skamil
24681.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
24691.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
24701.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
24711.1Skamil
24721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24731.1Skamil	    "without signal to be sent\n");
24741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24751.1Skamil
24761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24781.1Skamil
24791.1Skamil	validate_status_exited(status, exitval);
24801.1Skamil
24811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24831.1Skamil}
24841.1Skamil
24851.1SkamilATF_TC(read_d1);
24861.1SkamilATF_TC_HEAD(read_d1, tc)
24871.1Skamil{
24881.1Skamil	atf_tc_set_md_var(tc, "descr",
24891.1Skamil	    "Verify PT_READ_D called once");
24901.1Skamil}
24911.1Skamil
24921.1SkamilATF_TC_BODY(read_d1, tc)
24931.1Skamil{
24941.1Skamil	const int exitval = 5;
24951.1Skamil	const int sigval = SIGSTOP;
24961.1Skamil	pid_t child, wpid;
24971.1Skamil	int lookup_me = 0;
24981.1Skamil	const int magic = (int)random();
24991.1Skamil#if defined(TWAIT_HAVE_STATUS)
25001.1Skamil	int status;
25011.1Skamil#endif
25021.1Skamil
25031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25051.1Skamil	if (child == 0) {
25061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25081.1Skamil
25091.1Skamil		lookup_me = magic;
25101.1Skamil
25111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25131.1Skamil
25141.13Schristos		DPRINTF("Before exiting of the child process\n");
25151.1Skamil		_exit(exitval);
25161.1Skamil	}
25171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25181.1Skamil
25191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25211.1Skamil
25221.1Skamil	validate_status_stopped(status, sigval);
25231.1Skamil
25241.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
25251.1Skamil	    child, getpid());
25261.1Skamil	errno = 0;
25271.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
25281.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25291.1Skamil
25301.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
25311.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
25321.1Skamil
25331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25341.1Skamil	    "without signal to be sent\n");
25351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25361.1Skamil
25371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25391.1Skamil
25401.1Skamil	validate_status_exited(status, exitval);
25411.1Skamil
25421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25441.1Skamil}
25451.1Skamil
25461.1SkamilATF_TC(read_d2);
25471.1SkamilATF_TC_HEAD(read_d2, tc)
25481.1Skamil{
25491.1Skamil	atf_tc_set_md_var(tc, "descr",
25501.1Skamil	    "Verify PT_READ_D called twice");
25511.1Skamil}
25521.1Skamil
25531.1SkamilATF_TC_BODY(read_d2, tc)
25541.1Skamil{
25551.1Skamil	const int exitval = 5;
25561.1Skamil	const int sigval = SIGSTOP;
25571.1Skamil	pid_t child, wpid;
25581.1Skamil	int lookup_me1 = 0;
25591.1Skamil	int lookup_me2 = 0;
25601.1Skamil	const int magic1 = (int)random();
25611.1Skamil	const int magic2 = (int)random();
25621.1Skamil#if defined(TWAIT_HAVE_STATUS)
25631.1Skamil	int status;
25641.1Skamil#endif
25651.1Skamil
25661.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25671.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25681.1Skamil	if (child == 0) {
25691.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25701.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25711.1Skamil
25721.1Skamil		lookup_me1 = magic1;
25731.1Skamil		lookup_me2 = magic2;
25741.1Skamil
25751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25771.1Skamil
25781.13Schristos		DPRINTF("Before exiting of the child process\n");
25791.1Skamil		_exit(exitval);
25801.1Skamil	}
25811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25821.1Skamil
25831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25851.1Skamil
25861.1Skamil	validate_status_stopped(status, sigval);
25871.1Skamil
25881.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
25891.1Skamil	    child, getpid());
25901.1Skamil	errno = 0;
25911.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
25921.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25931.1Skamil
25941.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
25951.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
25961.1Skamil
25971.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
25981.1Skamil	    child, getpid());
25991.1Skamil	errno = 0;
26001.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26011.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26021.1Skamil
26031.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26041.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26051.1Skamil
26061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26071.1Skamil	    "without signal to be sent\n");
26081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26091.1Skamil
26101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26121.1Skamil
26131.1Skamil	validate_status_exited(status, exitval);
26141.1Skamil
26151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26171.1Skamil}
26181.1Skamil
26191.1SkamilATF_TC(read_d3);
26201.1SkamilATF_TC_HEAD(read_d3, tc)
26211.1Skamil{
26221.1Skamil	atf_tc_set_md_var(tc, "descr",
26231.1Skamil	    "Verify PT_READ_D called three times");
26241.1Skamil}
26251.1Skamil
26261.1SkamilATF_TC_BODY(read_d3, tc)
26271.1Skamil{
26281.1Skamil	const int exitval = 5;
26291.1Skamil	const int sigval = SIGSTOP;
26301.1Skamil	pid_t child, wpid;
26311.1Skamil	int lookup_me1 = 0;
26321.1Skamil	int lookup_me2 = 0;
26331.1Skamil	int lookup_me3 = 0;
26341.1Skamil	const int magic1 = (int)random();
26351.1Skamil	const int magic2 = (int)random();
26361.1Skamil	const int magic3 = (int)random();
26371.1Skamil#if defined(TWAIT_HAVE_STATUS)
26381.1Skamil	int status;
26391.1Skamil#endif
26401.1Skamil
26411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26431.1Skamil	if (child == 0) {
26441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26461.1Skamil
26471.1Skamil		lookup_me1 = magic1;
26481.1Skamil		lookup_me2 = magic2;
26491.1Skamil		lookup_me3 = magic3;
26501.1Skamil
26511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26531.1Skamil
26541.13Schristos		DPRINTF("Before exiting of the child process\n");
26551.1Skamil		_exit(exitval);
26561.1Skamil	}
26571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26581.1Skamil
26591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26611.1Skamil
26621.1Skamil	validate_status_stopped(status, sigval);
26631.1Skamil
26641.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26651.1Skamil	    child, getpid());
26661.1Skamil	errno = 0;
26671.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26681.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26691.1Skamil
26701.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26711.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26721.1Skamil
26731.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26741.1Skamil	    child, getpid());
26751.1Skamil	errno = 0;
26761.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26771.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26781.1Skamil
26791.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26801.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26811.1Skamil
26821.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
26831.1Skamil	    child, getpid());
26841.1Skamil	errno = 0;
26851.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
26861.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26871.1Skamil
26881.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
26891.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
26901.1Skamil
26911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26921.1Skamil	    "without signal to be sent\n");
26931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26941.1Skamil
26951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26971.1Skamil
26981.1Skamil	validate_status_exited(status, exitval);
26991.1Skamil
27001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27021.1Skamil}
27031.1Skamil
27041.1SkamilATF_TC(read_d4);
27051.1SkamilATF_TC_HEAD(read_d4, tc)
27061.1Skamil{
27071.1Skamil	atf_tc_set_md_var(tc, "descr",
27081.1Skamil	    "Verify PT_READ_D called four times");
27091.1Skamil}
27101.1Skamil
27111.1SkamilATF_TC_BODY(read_d4, tc)
27121.1Skamil{
27131.1Skamil	const int exitval = 5;
27141.1Skamil	const int sigval = SIGSTOP;
27151.1Skamil	pid_t child, wpid;
27161.1Skamil	int lookup_me1 = 0;
27171.1Skamil	int lookup_me2 = 0;
27181.1Skamil	int lookup_me3 = 0;
27191.1Skamil	int lookup_me4 = 0;
27201.1Skamil	const int magic1 = (int)random();
27211.1Skamil	const int magic2 = (int)random();
27221.1Skamil	const int magic3 = (int)random();
27231.1Skamil	const int magic4 = (int)random();
27241.1Skamil#if defined(TWAIT_HAVE_STATUS)
27251.1Skamil	int status;
27261.1Skamil#endif
27271.1Skamil
27281.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27291.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27301.1Skamil	if (child == 0) {
27311.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27321.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27331.1Skamil
27341.1Skamil		lookup_me1 = magic1;
27351.1Skamil		lookup_me2 = magic2;
27361.1Skamil		lookup_me3 = magic3;
27371.1Skamil		lookup_me4 = magic4;
27381.1Skamil
27391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27411.1Skamil
27421.13Schristos		DPRINTF("Before exiting of the child process\n");
27431.1Skamil		_exit(exitval);
27441.1Skamil	}
27451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27461.1Skamil
27471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27491.1Skamil
27501.1Skamil	validate_status_stopped(status, sigval);
27511.1Skamil
27521.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
27531.1Skamil	    child, getpid());
27541.1Skamil	errno = 0;
27551.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
27561.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27571.1Skamil
27581.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27591.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27601.1Skamil
27611.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27621.1Skamil	    child, getpid());
27631.1Skamil	errno = 0;
27641.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27651.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27661.1Skamil
27671.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27681.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27691.1Skamil
27701.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27711.1Skamil	    child, getpid());
27721.1Skamil	errno = 0;
27731.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27741.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27751.1Skamil
27761.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27771.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27781.1Skamil
27791.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
27801.1Skamil	    child, getpid());
27811.1Skamil	errno = 0;
27821.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
27831.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27841.1Skamil
27851.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
27861.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
27871.1Skamil
27881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27891.1Skamil	    "without signal to be sent\n");
27901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27911.1Skamil
27921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27941.1Skamil
27951.1Skamil	validate_status_exited(status, exitval);
27961.1Skamil
27971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27991.1Skamil}
28001.1Skamil
28011.1SkamilATF_TC(write_d1);
28021.1SkamilATF_TC_HEAD(write_d1, tc)
28031.1Skamil{
28041.1Skamil	atf_tc_set_md_var(tc, "descr",
28051.1Skamil	    "Verify PT_WRITE_D called once");
28061.1Skamil}
28071.1Skamil
28081.1SkamilATF_TC_BODY(write_d1, tc)
28091.1Skamil{
28101.1Skamil	const int exitval = 5;
28111.1Skamil	const int sigval = SIGSTOP;
28121.1Skamil	pid_t child, wpid;
28131.1Skamil	int lookup_me = 0;
28141.1Skamil	const int magic = (int)random();
28151.1Skamil#if defined(TWAIT_HAVE_STATUS)
28161.1Skamil	int status;
28171.1Skamil#endif
28181.1Skamil
28191.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28201.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28211.1Skamil	if (child == 0) {
28221.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28231.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28241.1Skamil
28251.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28261.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28271.1Skamil
28281.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
28291.1Skamil
28301.13Schristos		DPRINTF("Before exiting of the child process\n");
28311.1Skamil		_exit(exitval);
28321.1Skamil	}
28331.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28341.1Skamil
28351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28371.1Skamil
28381.1Skamil	validate_status_stopped(status, sigval);
28391.1Skamil
28401.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
28411.1Skamil	    child, getpid());
28421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
28431.1Skamil
28441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28451.1Skamil	    "without signal to be sent\n");
28461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28471.1Skamil
28481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28501.1Skamil
28511.1Skamil	validate_status_exited(status, exitval);
28521.1Skamil
28531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28551.1Skamil}
28561.1Skamil
28571.1SkamilATF_TC(write_d2);
28581.1SkamilATF_TC_HEAD(write_d2, tc)
28591.1Skamil{
28601.1Skamil	atf_tc_set_md_var(tc, "descr",
28611.1Skamil	    "Verify PT_WRITE_D called twice");
28621.1Skamil}
28631.1Skamil
28641.1SkamilATF_TC_BODY(write_d2, tc)
28651.1Skamil{
28661.1Skamil	const int exitval = 5;
28671.1Skamil	const int sigval = SIGSTOP;
28681.1Skamil	pid_t child, wpid;
28691.1Skamil	int lookup_me1 = 0;
28701.1Skamil	int lookup_me2 = 0;
28711.1Skamil	const int magic1 = (int)random();
28721.1Skamil	const int magic2 = (int)random();
28731.1Skamil#if defined(TWAIT_HAVE_STATUS)
28741.1Skamil	int status;
28751.1Skamil#endif
28761.1Skamil
28771.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28781.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28791.1Skamil	if (child == 0) {
28801.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28811.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28821.1Skamil
28831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28851.1Skamil
28861.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
28871.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
28881.1Skamil
28891.13Schristos		DPRINTF("Before exiting of the child process\n");
28901.1Skamil		_exit(exitval);
28911.1Skamil	}
28921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28931.1Skamil
28941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28961.1Skamil
28971.1Skamil	validate_status_stopped(status, sigval);
28981.1Skamil
28991.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29001.1Skamil	    child, getpid());
29011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29021.1Skamil
29031.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29041.1Skamil	    child, getpid());
29051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29061.1Skamil
29071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29081.1Skamil	    "without signal to be sent\n");
29091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29101.1Skamil
29111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29131.1Skamil
29141.1Skamil	validate_status_exited(status, exitval);
29151.1Skamil
29161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29181.1Skamil}
29191.1Skamil
29201.1SkamilATF_TC(write_d3);
29211.1SkamilATF_TC_HEAD(write_d3, tc)
29221.1Skamil{
29231.1Skamil	atf_tc_set_md_var(tc, "descr",
29241.1Skamil	    "Verify PT_WRITE_D called three times");
29251.1Skamil}
29261.1Skamil
29271.1SkamilATF_TC_BODY(write_d3, tc)
29281.1Skamil{
29291.1Skamil	const int exitval = 5;
29301.1Skamil	const int sigval = SIGSTOP;
29311.1Skamil	pid_t child, wpid;
29321.1Skamil	int lookup_me1 = 0;
29331.1Skamil	int lookup_me2 = 0;
29341.1Skamil	int lookup_me3 = 0;
29351.1Skamil	const int magic1 = (int)random();
29361.1Skamil	const int magic2 = (int)random();
29371.1Skamil	const int magic3 = (int)random();
29381.1Skamil#if defined(TWAIT_HAVE_STATUS)
29391.1Skamil	int status;
29401.1Skamil#endif
29411.1Skamil
29421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29441.1Skamil	if (child == 0) {
29451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29471.1Skamil
29481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29501.1Skamil
29511.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29521.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29531.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
29541.1Skamil
29551.13Schristos		DPRINTF("Before exiting of the child process\n");
29561.1Skamil		_exit(exitval);
29571.1Skamil	}
29581.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29591.1Skamil
29601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29621.1Skamil
29631.1Skamil	validate_status_stopped(status, sigval);
29641.1Skamil
29651.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29661.1Skamil	    child, getpid());
29671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29681.1Skamil
29691.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29701.1Skamil	    child, getpid());
29711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29721.1Skamil
29731.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
29741.1Skamil	    child, getpid());
29751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
29761.1Skamil
29771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29781.1Skamil	    "without signal to be sent\n");
29791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29801.1Skamil
29811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29831.1Skamil
29841.1Skamil	validate_status_exited(status, exitval);
29851.1Skamil
29861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29881.1Skamil}
29891.1Skamil
29901.1SkamilATF_TC(write_d4);
29911.1SkamilATF_TC_HEAD(write_d4, tc)
29921.1Skamil{
29931.1Skamil	atf_tc_set_md_var(tc, "descr",
29941.1Skamil	    "Verify PT_WRITE_D called four times");
29951.1Skamil}
29961.1Skamil
29971.1SkamilATF_TC_BODY(write_d4, tc)
29981.1Skamil{
29991.1Skamil	const int exitval = 5;
30001.1Skamil	const int sigval = SIGSTOP;
30011.1Skamil	pid_t child, wpid;
30021.1Skamil	int lookup_me1 = 0;
30031.1Skamil	int lookup_me2 = 0;
30041.1Skamil	int lookup_me3 = 0;
30051.1Skamil	int lookup_me4 = 0;
30061.1Skamil	const int magic1 = (int)random();
30071.1Skamil	const int magic2 = (int)random();
30081.1Skamil	const int magic3 = (int)random();
30091.1Skamil	const int magic4 = (int)random();
30101.1Skamil#if defined(TWAIT_HAVE_STATUS)
30111.1Skamil	int status;
30121.1Skamil#endif
30131.1Skamil
30141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30161.1Skamil	if (child == 0) {
30171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30191.1Skamil
30201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30221.1Skamil
30231.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
30241.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
30251.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
30261.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
30271.1Skamil
30281.13Schristos		DPRINTF("Before exiting of the child process\n");
30291.1Skamil		_exit(exitval);
30301.1Skamil	}
30311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30321.1Skamil
30331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30351.1Skamil
30361.1Skamil	validate_status_stopped(status, sigval);
30371.1Skamil
30381.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
30391.1Skamil	    child, getpid());
30401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
30411.1Skamil
30421.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30431.1Skamil	    child, getpid());
30441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30451.1Skamil
30461.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30471.1Skamil	    child, getpid());
30481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30491.1Skamil
30501.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
30511.1Skamil	    child, getpid());
30521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
30531.1Skamil
30541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30551.1Skamil	    "without signal to be sent\n");
30561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30571.1Skamil
30581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30601.1Skamil
30611.1Skamil	validate_status_exited(status, exitval);
30621.1Skamil
30631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30651.1Skamil}
30661.1Skamil
30671.1SkamilATF_TC(io_read_d_write_d_handshake1);
30681.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
30691.1Skamil{
30701.1Skamil	atf_tc_set_md_var(tc, "descr",
30711.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
30721.1Skamil}
30731.1Skamil
30741.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
30751.1Skamil{
30761.1Skamil	const int exitval = 5;
30771.1Skamil	const int sigval = SIGSTOP;
30781.1Skamil	pid_t child, wpid;
30791.1Skamil	uint8_t lookup_me_fromtracee = 0;
30801.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
30811.1Skamil	uint8_t lookup_me_totracee = 0;
30821.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
30831.1Skamil	struct ptrace_io_desc io_fromtracee = {
30841.1Skamil		.piod_op = PIOD_READ_D,
30851.1Skamil		.piod_offs = &lookup_me_fromtracee,
30861.1Skamil		.piod_addr = &lookup_me_fromtracee,
30871.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
30881.1Skamil	};
30891.1Skamil	struct ptrace_io_desc io_totracee = {
30901.1Skamil		.piod_op = PIOD_WRITE_D,
30911.1Skamil		.piod_offs = &lookup_me_totracee,
30921.1Skamil		.piod_addr = &lookup_me_totracee,
30931.1Skamil		.piod_len = sizeof(lookup_me_totracee)
30941.1Skamil	};
30951.1Skamil#if defined(TWAIT_HAVE_STATUS)
30961.1Skamil	int status;
30971.1Skamil#endif
30981.1Skamil
30991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31011.1Skamil	if (child == 0) {
31021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31041.1Skamil
31051.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31061.1Skamil
31071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31091.1Skamil
31101.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31111.1Skamil
31121.13Schristos		DPRINTF("Before exiting of the child process\n");
31131.1Skamil		_exit(exitval);
31141.1Skamil	}
31151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31161.1Skamil
31171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31191.1Skamil
31201.1Skamil	validate_status_stopped(status, sigval);
31211.1Skamil
31221.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31231.1Skamil	    child, getpid());
31241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
31251.1Skamil
31261.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31271.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
31281.1Skamil	    magic_fromtracee);
31291.1Skamil
31301.1Skamil	lookup_me_totracee = magic_totracee;
31311.1Skamil
31321.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
31331.1Skamil	    child, getpid());
31341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
31351.1Skamil
31361.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
31371.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
31381.1Skamil	    magic_totracee);
31391.1Skamil
31401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31411.1Skamil	    "without signal to be sent\n");
31421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31431.1Skamil
31441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31461.1Skamil
31471.1Skamil	validate_status_exited(status, exitval);
31481.1Skamil
31491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31511.1Skamil}
31521.1Skamil
31531.1SkamilATF_TC(io_read_d_write_d_handshake2);
31541.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
31551.1Skamil{
31561.1Skamil	atf_tc_set_md_var(tc, "descr",
31571.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
31581.1Skamil}
31591.1Skamil
31601.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
31611.1Skamil{
31621.1Skamil	const int exitval = 5;
31631.1Skamil	const int sigval = SIGSTOP;
31641.1Skamil	pid_t child, wpid;
31651.1Skamil	uint8_t lookup_me_fromtracee = 0;
31661.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31671.1Skamil	uint8_t lookup_me_totracee = 0;
31681.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31691.1Skamil	struct ptrace_io_desc io_fromtracee = {
31701.1Skamil		.piod_op = PIOD_READ_D,
31711.1Skamil		.piod_offs = &lookup_me_fromtracee,
31721.1Skamil		.piod_addr = &lookup_me_fromtracee,
31731.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31741.1Skamil	};
31751.1Skamil	struct ptrace_io_desc io_totracee = {
31761.1Skamil		.piod_op = PIOD_WRITE_D,
31771.1Skamil		.piod_offs = &lookup_me_totracee,
31781.1Skamil		.piod_addr = &lookup_me_totracee,
31791.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31801.1Skamil	};
31811.1Skamil#if defined(TWAIT_HAVE_STATUS)
31821.1Skamil	int status;
31831.1Skamil#endif
31841.1Skamil
31851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31871.1Skamil	if (child == 0) {
31881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31901.1Skamil
31911.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31921.1Skamil
31931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31951.1Skamil
31961.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31971.1Skamil
31981.13Schristos		DPRINTF("Before exiting of the child process\n");
31991.1Skamil		_exit(exitval);
32001.1Skamil	}
32011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32021.1Skamil
32031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32051.1Skamil
32061.1Skamil	validate_status_stopped(status, sigval);
32071.1Skamil
32081.1Skamil	lookup_me_totracee = magic_totracee;
32091.1Skamil
32101.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
32111.1Skamil	    child, getpid());
32121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
32131.1Skamil
32141.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
32151.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
32161.1Skamil	    magic_totracee);
32171.1Skamil
32181.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32191.1Skamil	    child, getpid());
32201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
32211.1Skamil
32221.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32231.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
32241.1Skamil	    magic_fromtracee);
32251.1Skamil
32261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32271.1Skamil	    "without signal to be sent\n");
32281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32291.1Skamil
32301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32321.1Skamil
32331.1Skamil	validate_status_exited(status, exitval);
32341.1Skamil
32351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32371.1Skamil}
32381.1Skamil
32391.1SkamilATF_TC(read_d_write_d_handshake1);
32401.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
32411.1Skamil{
32421.1Skamil	atf_tc_set_md_var(tc, "descr",
32431.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
32441.1Skamil}
32451.1Skamil
32461.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
32471.1Skamil{
32481.1Skamil	const int exitval = 5;
32491.1Skamil	const int sigval = SIGSTOP;
32501.1Skamil	pid_t child, wpid;
32511.1Skamil	int lookup_me_fromtracee = 0;
32521.1Skamil	const int magic_fromtracee = (int)random();
32531.1Skamil	int lookup_me_totracee = 0;
32541.1Skamil	const int magic_totracee = (int)random();
32551.1Skamil#if defined(TWAIT_HAVE_STATUS)
32561.1Skamil	int status;
32571.1Skamil#endif
32581.1Skamil
32591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32611.1Skamil	if (child == 0) {
32621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32641.1Skamil
32651.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32661.1Skamil
32671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32691.1Skamil
32701.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32711.1Skamil
32721.13Schristos		DPRINTF("Before exiting of the child process\n");
32731.1Skamil		_exit(exitval);
32741.1Skamil	}
32751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32761.1Skamil
32771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32791.1Skamil
32801.1Skamil	validate_status_stopped(status, sigval);
32811.1Skamil
32821.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32831.1Skamil	    child, getpid());
32841.1Skamil	errno = 0;
32851.1Skamil	lookup_me_fromtracee =
32861.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
32871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
32881.1Skamil
32891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32901.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
32911.1Skamil	    magic_fromtracee);
32921.1Skamil
32931.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
32941.1Skamil	    child, getpid());
32951.1Skamil	ATF_REQUIRE
32961.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
32971.1Skamil	    != -1);
32981.1Skamil
32991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33001.1Skamil	    "without signal to be sent\n");
33011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33021.1Skamil
33031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33051.1Skamil
33061.1Skamil	validate_status_exited(status, exitval);
33071.1Skamil
33081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33101.1Skamil}
33111.1Skamil
33121.1SkamilATF_TC(read_d_write_d_handshake2);
33131.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
33141.1Skamil{
33151.1Skamil	atf_tc_set_md_var(tc, "descr",
33161.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
33171.1Skamil}
33181.1Skamil
33191.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
33201.1Skamil{
33211.1Skamil	const int exitval = 5;
33221.1Skamil	const int sigval = SIGSTOP;
33231.1Skamil	pid_t child, wpid;
33241.1Skamil	int lookup_me_fromtracee = 0;
33251.1Skamil	const int magic_fromtracee = (int)random();
33261.1Skamil	int lookup_me_totracee = 0;
33271.1Skamil	const int magic_totracee = (int)random();
33281.1Skamil#if defined(TWAIT_HAVE_STATUS)
33291.1Skamil	int status;
33301.1Skamil#endif
33311.1Skamil
33321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33341.1Skamil	if (child == 0) {
33351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33371.1Skamil
33381.1Skamil		lookup_me_fromtracee = magic_fromtracee;
33391.1Skamil
33401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33421.1Skamil
33431.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33441.1Skamil
33451.13Schristos		DPRINTF("Before exiting of the child process\n");
33461.1Skamil		_exit(exitval);
33471.1Skamil	}
33481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33491.1Skamil
33501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33521.1Skamil
33531.1Skamil	validate_status_stopped(status, sigval);
33541.1Skamil
33551.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33561.1Skamil	    child, getpid());
33571.1Skamil	ATF_REQUIRE
33581.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33591.1Skamil	    != -1);
33601.1Skamil
33611.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33621.1Skamil	    child, getpid());
33631.1Skamil	errno = 0;
33641.1Skamil	lookup_me_fromtracee =
33651.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33661.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33671.1Skamil
33681.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33691.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33701.1Skamil	    magic_fromtracee);
33711.1Skamil
33721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33731.1Skamil	    "without signal to be sent\n");
33741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33751.1Skamil
33761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33781.1Skamil
33791.1Skamil	validate_status_exited(status, exitval);
33801.1Skamil
33811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33831.1Skamil}
33841.1Skamil
33851.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
33861.1Skamilstatic int __used
33871.1Skamildummy_fn1(int a, int b, int c, int d)
33881.1Skamil{
33891.1Skamil
33901.1Skamil	a *= 1;
33911.1Skamil	b += 2;
33921.1Skamil	c -= 3;
33931.1Skamil	d /= 4;
33941.1Skamil
33951.1Skamil	return a + b * c - d;
33961.1Skamil}
33971.1Skamil
33981.1Skamilstatic int __used
33991.1Skamildummy_fn2(int a, int b, int c, int d)
34001.1Skamil{
34011.1Skamil
34021.1Skamil	a *= 4;
34031.1Skamil	b += 3;
34041.1Skamil	c -= 2;
34051.1Skamil	d /= 1;
34061.1Skamil
34071.1Skamil	return a + b * c - d;
34081.1Skamil}
34091.1Skamil
34101.1Skamilstatic int __used
34111.1Skamildummy_fn3(int a, int b, int c, int d)
34121.1Skamil{
34131.1Skamil
34141.1Skamil	a *= 10;
34151.1Skamil	b += 20;
34161.1Skamil	c -= 30;
34171.1Skamil	d /= 40;
34181.1Skamil
34191.1Skamil	return a + b * c - d;
34201.1Skamil}
34211.1Skamil
34221.1Skamilstatic int __used
34231.1Skamildummy_fn4(int a, int b, int c, int d)
34241.1Skamil{
34251.1Skamil
34261.1Skamil	a *= 40;
34271.1Skamil	b += 30;
34281.1Skamil	c -= 20;
34291.1Skamil	d /= 10;
34301.1Skamil
34311.1Skamil	return a + b * c - d;
34321.1Skamil}
34331.1Skamil
34341.1SkamilATF_TC(io_read_i1);
34351.1SkamilATF_TC_HEAD(io_read_i1, tc)
34361.1Skamil{
34371.1Skamil	atf_tc_set_md_var(tc, "descr",
34381.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
34391.1Skamil}
34401.1Skamil
34411.1SkamilATF_TC_BODY(io_read_i1, tc)
34421.1Skamil{
34431.1Skamil	const int exitval = 5;
34441.1Skamil	const int sigval = SIGSTOP;
34451.1Skamil	pid_t child, wpid;
34461.1Skamil	uint8_t lookup_me = 0;
34471.1Skamil	uint8_t magic;
34481.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34491.1Skamil	struct ptrace_io_desc io = {
34501.1Skamil		.piod_op = PIOD_READ_I,
34511.1Skamil		.piod_offs = dummy_fn1,
34521.1Skamil		.piod_addr = &lookup_me,
34531.1Skamil		.piod_len = sizeof(lookup_me)
34541.1Skamil	};
34551.1Skamil#if defined(TWAIT_HAVE_STATUS)
34561.1Skamil	int status;
34571.1Skamil#endif
34581.1Skamil
34591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34611.1Skamil	if (child == 0) {
34621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34641.1Skamil
34651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34671.1Skamil
34681.13Schristos		DPRINTF("Before exiting of the child process\n");
34691.1Skamil		_exit(exitval);
34701.1Skamil	}
34711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34721.1Skamil
34731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34751.1Skamil
34761.1Skamil	validate_status_stopped(status, sigval);
34771.1Skamil
34781.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34791.1Skamil	    child, getpid());
34801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34811.1Skamil
34821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34831.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
34841.1Skamil
34851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34861.1Skamil	    "without signal to be sent\n");
34871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34881.1Skamil
34891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34911.1Skamil
34921.1Skamil	validate_status_exited(status, exitval);
34931.1Skamil
34941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34961.1Skamil}
34971.1Skamil
34981.1SkamilATF_TC(io_read_i2);
34991.1SkamilATF_TC_HEAD(io_read_i2, tc)
35001.1Skamil{
35011.1Skamil	atf_tc_set_md_var(tc, "descr",
35021.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
35031.1Skamil}
35041.1Skamil
35051.1SkamilATF_TC_BODY(io_read_i2, tc)
35061.1Skamil{
35071.1Skamil	const int exitval = 5;
35081.1Skamil	const int sigval = SIGSTOP;
35091.1Skamil	pid_t child, wpid;
35101.1Skamil	uint16_t lookup_me = 0;
35111.1Skamil	uint16_t magic;
35121.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35131.1Skamil	struct ptrace_io_desc io = {
35141.1Skamil		.piod_op = PIOD_READ_I,
35151.1Skamil		.piod_offs = dummy_fn1,
35161.1Skamil		.piod_addr = &lookup_me,
35171.1Skamil		.piod_len = sizeof(lookup_me)
35181.1Skamil	};
35191.1Skamil#if defined(TWAIT_HAVE_STATUS)
35201.1Skamil	int status;
35211.1Skamil#endif
35221.1Skamil
35231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35251.1Skamil	if (child == 0) {
35261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35281.1Skamil
35291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35311.1Skamil
35321.13Schristos		DPRINTF("Before exiting of the child process\n");
35331.1Skamil		_exit(exitval);
35341.1Skamil	}
35351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35361.1Skamil
35371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35391.1Skamil
35401.1Skamil	validate_status_stopped(status, sigval);
35411.1Skamil
35421.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35431.1Skamil	    child, getpid());
35441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35451.1Skamil
35461.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35471.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
35481.1Skamil
35491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35501.1Skamil	    "without signal to be sent\n");
35511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35521.1Skamil
35531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35551.1Skamil
35561.1Skamil	validate_status_exited(status, exitval);
35571.1Skamil
35581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35601.1Skamil}
35611.1Skamil
35621.1SkamilATF_TC(io_read_i3);
35631.1SkamilATF_TC_HEAD(io_read_i3, tc)
35641.1Skamil{
35651.1Skamil	atf_tc_set_md_var(tc, "descr",
35661.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
35671.1Skamil}
35681.1Skamil
35691.1SkamilATF_TC_BODY(io_read_i3, tc)
35701.1Skamil{
35711.1Skamil	const int exitval = 5;
35721.1Skamil	const int sigval = SIGSTOP;
35731.1Skamil	pid_t child, wpid;
35741.1Skamil	uint32_t lookup_me = 0;
35751.1Skamil	uint32_t magic;
35761.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35771.1Skamil	struct ptrace_io_desc io = {
35781.1Skamil		.piod_op = PIOD_READ_I,
35791.1Skamil		.piod_offs = dummy_fn1,
35801.1Skamil		.piod_addr = &lookup_me,
35811.1Skamil		.piod_len = sizeof(lookup_me)
35821.1Skamil	};
35831.1Skamil#if defined(TWAIT_HAVE_STATUS)
35841.1Skamil	int status;
35851.1Skamil#endif
35861.1Skamil
35871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35891.1Skamil	if (child == 0) {
35901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35921.1Skamil
35931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35951.1Skamil
35961.13Schristos		DPRINTF("Before exiting of the child process\n");
35971.1Skamil		_exit(exitval);
35981.1Skamil	}
35991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36001.1Skamil
36011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36031.1Skamil
36041.1Skamil	validate_status_stopped(status, sigval);
36051.1Skamil
36061.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36071.1Skamil	    child, getpid());
36081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36091.1Skamil
36101.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36111.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
36121.1Skamil
36131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36141.1Skamil	    "without signal to be sent\n");
36151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36161.1Skamil
36171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36191.1Skamil
36201.1Skamil	validate_status_exited(status, exitval);
36211.1Skamil
36221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36231.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36241.1Skamil}
36251.1Skamil
36261.1SkamilATF_TC(io_read_i4);
36271.1SkamilATF_TC_HEAD(io_read_i4, tc)
36281.1Skamil{
36291.1Skamil	atf_tc_set_md_var(tc, "descr",
36301.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
36311.1Skamil}
36321.1Skamil
36331.1SkamilATF_TC_BODY(io_read_i4, tc)
36341.1Skamil{
36351.1Skamil	const int exitval = 5;
36361.1Skamil	const int sigval = SIGSTOP;
36371.1Skamil	pid_t child, wpid;
36381.1Skamil	uint64_t lookup_me = 0;
36391.1Skamil	uint64_t magic;
36401.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36411.1Skamil	struct ptrace_io_desc io = {
36421.1Skamil		.piod_op = PIOD_READ_I,
36431.1Skamil		.piod_offs = dummy_fn1,
36441.1Skamil		.piod_addr = &lookup_me,
36451.1Skamil		.piod_len = sizeof(lookup_me)
36461.1Skamil	};
36471.1Skamil#if defined(TWAIT_HAVE_STATUS)
36481.1Skamil	int status;
36491.1Skamil#endif
36501.1Skamil
36511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36531.1Skamil	if (child == 0) {
36541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36561.1Skamil
36571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36591.1Skamil
36601.13Schristos		DPRINTF("Before exiting of the child process\n");
36611.1Skamil		_exit(exitval);
36621.1Skamil	}
36631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36641.1Skamil
36651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36671.1Skamil
36681.1Skamil	validate_status_stopped(status, sigval);
36691.1Skamil
36701.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36711.1Skamil	    child, getpid());
36721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36731.1Skamil
36741.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36751.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
36761.1Skamil
36771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36781.1Skamil	    "without signal to be sent\n");
36791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36801.1Skamil
36811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36831.1Skamil
36841.1Skamil	validate_status_exited(status, exitval);
36851.1Skamil
36861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36881.1Skamil}
36891.1Skamil
36901.1SkamilATF_TC(read_i1);
36911.1SkamilATF_TC_HEAD(read_i1, tc)
36921.1Skamil{
36931.1Skamil	atf_tc_set_md_var(tc, "descr",
36941.1Skamil	    "Verify PT_READ_I called once");
36951.1Skamil}
36961.1Skamil
36971.1SkamilATF_TC_BODY(read_i1, tc)
36981.1Skamil{
36991.1Skamil	const int exitval = 5;
37001.1Skamil	const int sigval = SIGSTOP;
37011.1Skamil	pid_t child, wpid;
37021.1Skamil	int lookup_me = 0;
37031.1Skamil	int magic;
37041.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
37051.1Skamil#if defined(TWAIT_HAVE_STATUS)
37061.1Skamil	int status;
37071.1Skamil#endif
37081.1Skamil
37091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37111.1Skamil	if (child == 0) {
37121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37141.1Skamil
37151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37171.1Skamil
37181.13Schristos		DPRINTF("Before exiting of the child process\n");
37191.1Skamil		_exit(exitval);
37201.1Skamil	}
37211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37221.1Skamil
37231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37251.1Skamil
37261.1Skamil	validate_status_stopped(status, sigval);
37271.1Skamil
37281.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37291.1Skamil	    child, getpid());
37301.1Skamil	errno = 0;
37311.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
37321.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37331.1Skamil
37341.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37351.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
37361.1Skamil
37371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37381.1Skamil	    "without signal to be sent\n");
37391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37401.1Skamil
37411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37431.1Skamil
37441.1Skamil	validate_status_exited(status, exitval);
37451.1Skamil
37461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37481.1Skamil}
37491.1Skamil
37501.1SkamilATF_TC(read_i2);
37511.1SkamilATF_TC_HEAD(read_i2, tc)
37521.1Skamil{
37531.1Skamil	atf_tc_set_md_var(tc, "descr",
37541.1Skamil	    "Verify PT_READ_I called twice");
37551.1Skamil}
37561.1Skamil
37571.1SkamilATF_TC_BODY(read_i2, tc)
37581.1Skamil{
37591.1Skamil	const int exitval = 5;
37601.1Skamil	const int sigval = SIGSTOP;
37611.1Skamil	pid_t child, wpid;
37621.1Skamil	int lookup_me1 = 0;
37631.1Skamil	int lookup_me2 = 0;
37641.1Skamil	int magic1;
37651.1Skamil	int magic2;
37661.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37671.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37681.1Skamil#if defined(TWAIT_HAVE_STATUS)
37691.1Skamil	int status;
37701.1Skamil#endif
37711.1Skamil
37721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37741.1Skamil	if (child == 0) {
37751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37771.1Skamil
37781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37801.1Skamil
37811.13Schristos		DPRINTF("Before exiting of the child process\n");
37821.1Skamil		_exit(exitval);
37831.1Skamil	}
37841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37851.1Skamil
37861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37881.1Skamil
37891.1Skamil	validate_status_stopped(status, sigval);
37901.1Skamil
37911.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
37921.1Skamil	    child, getpid());
37931.1Skamil	errno = 0;
37941.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
37951.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37961.1Skamil
37971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
37981.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
37991.1Skamil
38001.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38011.1Skamil	    child, getpid());
38021.1Skamil	errno = 0;
38031.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38041.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38051.1Skamil
38061.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38071.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38081.1Skamil
38091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38101.1Skamil	    "without signal to be sent\n");
38111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38121.1Skamil
38131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38151.1Skamil
38161.1Skamil	validate_status_exited(status, exitval);
38171.1Skamil
38181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38201.1Skamil}
38211.1Skamil
38221.1SkamilATF_TC(read_i3);
38231.1SkamilATF_TC_HEAD(read_i3, tc)
38241.1Skamil{
38251.1Skamil	atf_tc_set_md_var(tc, "descr",
38261.1Skamil	    "Verify PT_READ_I called three times");
38271.1Skamil}
38281.1Skamil
38291.1SkamilATF_TC_BODY(read_i3, tc)
38301.1Skamil{
38311.1Skamil	const int exitval = 5;
38321.1Skamil	const int sigval = SIGSTOP;
38331.1Skamil	pid_t child, wpid;
38341.1Skamil	int lookup_me1 = 0;
38351.1Skamil	int lookup_me2 = 0;
38361.1Skamil	int lookup_me3 = 0;
38371.1Skamil	int magic1;
38381.1Skamil	int magic2;
38391.1Skamil	int magic3;
38401.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
38411.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
38421.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
38431.1Skamil#if defined(TWAIT_HAVE_STATUS)
38441.1Skamil	int status;
38451.1Skamil#endif
38461.1Skamil
38471.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38481.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38491.1Skamil	if (child == 0) {
38501.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38511.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38521.1Skamil
38531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38551.1Skamil
38561.13Schristos		DPRINTF("Before exiting of the child process\n");
38571.1Skamil		_exit(exitval);
38581.1Skamil	}
38591.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38601.1Skamil
38611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38631.1Skamil
38641.1Skamil	validate_status_stopped(status, sigval);
38651.1Skamil
38661.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38671.1Skamil	    child, getpid());
38681.1Skamil	errno = 0;
38691.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38701.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38711.1Skamil
38721.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38731.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38741.1Skamil
38751.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38761.1Skamil	    child, getpid());
38771.1Skamil	errno = 0;
38781.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38791.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38801.1Skamil
38811.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38821.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38831.1Skamil
38841.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
38851.1Skamil	    child, getpid());
38861.1Skamil	errno = 0;
38871.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
38881.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38891.1Skamil
38901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
38911.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
38921.1Skamil
38931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38941.1Skamil	    "without signal to be sent\n");
38951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38961.1Skamil
38971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38991.1Skamil
39001.1Skamil	validate_status_exited(status, exitval);
39011.1Skamil
39021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39041.1Skamil}
39051.1Skamil
39061.1SkamilATF_TC(read_i4);
39071.1SkamilATF_TC_HEAD(read_i4, tc)
39081.1Skamil{
39091.1Skamil	atf_tc_set_md_var(tc, "descr",
39101.1Skamil	    "Verify PT_READ_I called four times");
39111.1Skamil}
39121.1Skamil
39131.1SkamilATF_TC_BODY(read_i4, tc)
39141.1Skamil{
39151.1Skamil	const int exitval = 5;
39161.1Skamil	const int sigval = SIGSTOP;
39171.1Skamil	pid_t child, wpid;
39181.1Skamil	int lookup_me1 = 0;
39191.1Skamil	int lookup_me2 = 0;
39201.1Skamil	int lookup_me3 = 0;
39211.1Skamil	int lookup_me4 = 0;
39221.1Skamil	int magic1;
39231.1Skamil	int magic2;
39241.1Skamil	int magic3;
39251.1Skamil	int magic4;
39261.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
39271.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
39281.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
39291.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
39301.1Skamil#if defined(TWAIT_HAVE_STATUS)
39311.1Skamil	int status;
39321.1Skamil#endif
39331.1Skamil
39341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39361.1Skamil	if (child == 0) {
39371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39391.1Skamil
39401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39421.1Skamil
39431.13Schristos		DPRINTF("Before exiting of the child process\n");
39441.1Skamil		_exit(exitval);
39451.1Skamil	}
39461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39471.1Skamil
39481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39501.1Skamil
39511.1Skamil	validate_status_stopped(status, sigval);
39521.1Skamil
39531.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
39541.1Skamil	    child, getpid());
39551.1Skamil	errno = 0;
39561.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39571.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39581.1Skamil
39591.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39601.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39611.1Skamil
39621.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39631.1Skamil	    child, getpid());
39641.1Skamil	errno = 0;
39651.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39661.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39671.1Skamil
39681.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39691.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39701.1Skamil
39711.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39721.1Skamil	    child, getpid());
39731.1Skamil	errno = 0;
39741.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39751.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39761.1Skamil
39771.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39781.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39791.1Skamil
39801.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
39811.1Skamil	    child, getpid());
39821.1Skamil	errno = 0;
39831.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
39841.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39851.1Skamil
39861.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
39871.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
39881.1Skamil
39891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39901.1Skamil	    "without signal to be sent\n");
39911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39921.1Skamil
39931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39951.1Skamil
39961.1Skamil	validate_status_exited(status, exitval);
39971.1Skamil
39981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40001.1Skamil}
40011.1Skamil
40021.1Skamil#if defined(HAVE_GPREGS)
40031.1SkamilATF_TC(regs1);
40041.1SkamilATF_TC_HEAD(regs1, tc)
40051.1Skamil{
40061.1Skamil	atf_tc_set_md_var(tc, "descr",
40071.1Skamil	    "Verify plain PT_GETREGS call without further steps");
40081.1Skamil}
40091.1Skamil
40101.1SkamilATF_TC_BODY(regs1, tc)
40111.1Skamil{
40121.1Skamil	const int exitval = 5;
40131.1Skamil	const int sigval = SIGSTOP;
40141.1Skamil	pid_t child, wpid;
40151.1Skamil#if defined(TWAIT_HAVE_STATUS)
40161.1Skamil	int status;
40171.1Skamil#endif
40181.1Skamil	struct reg r;
40191.1Skamil
40201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40221.1Skamil	if (child == 0) {
40231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40251.1Skamil
40261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40281.1Skamil
40291.13Schristos		DPRINTF("Before exiting of the child process\n");
40301.1Skamil		_exit(exitval);
40311.1Skamil	}
40321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40331.1Skamil
40341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40361.1Skamil
40371.1Skamil	validate_status_stopped(status, sigval);
40381.1Skamil
40391.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40411.1Skamil
40421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40431.1Skamil	    "without signal to be sent\n");
40441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40451.1Skamil
40461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40481.1Skamil
40491.1Skamil	validate_status_exited(status, exitval);
40501.1Skamil
40511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40521.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40531.1Skamil}
40541.1Skamil#endif
40551.1Skamil
40561.1Skamil#if defined(HAVE_GPREGS)
40571.1SkamilATF_TC(regs2);
40581.1SkamilATF_TC_HEAD(regs2, tc)
40591.1Skamil{
40601.1Skamil	atf_tc_set_md_var(tc, "descr",
40611.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
40621.1Skamil}
40631.1Skamil
40641.1SkamilATF_TC_BODY(regs2, tc)
40651.1Skamil{
40661.1Skamil	const int exitval = 5;
40671.1Skamil	const int sigval = SIGSTOP;
40681.1Skamil	pid_t child, wpid;
40691.1Skamil#if defined(TWAIT_HAVE_STATUS)
40701.1Skamil	int status;
40711.1Skamil#endif
40721.1Skamil	struct reg r;
40731.1Skamil
40741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40761.1Skamil	if (child == 0) {
40771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40791.1Skamil
40801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40821.1Skamil
40831.13Schristos		DPRINTF("Before exiting of the child process\n");
40841.1Skamil		_exit(exitval);
40851.1Skamil	}
40861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40871.1Skamil
40881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40901.1Skamil
40911.1Skamil	validate_status_stopped(status, sigval);
40921.1Skamil
40931.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40951.1Skamil
40961.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
40971.1Skamil
40981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40991.1Skamil	    "without signal to be sent\n");
41001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41011.1Skamil
41021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41041.1Skamil
41051.1Skamil	validate_status_exited(status, exitval);
41061.1Skamil
41071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41091.1Skamil}
41101.1Skamil#endif
41111.1Skamil
41121.1Skamil#if defined(HAVE_GPREGS)
41131.1SkamilATF_TC(regs3);
41141.1SkamilATF_TC_HEAD(regs3, tc)
41151.1Skamil{
41161.1Skamil	atf_tc_set_md_var(tc, "descr",
41171.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
41181.1Skamil}
41191.1Skamil
41201.1SkamilATF_TC_BODY(regs3, tc)
41211.1Skamil{
41221.1Skamil	const int exitval = 5;
41231.1Skamil	const int sigval = SIGSTOP;
41241.1Skamil	pid_t child, wpid;
41251.1Skamil#if defined(TWAIT_HAVE_STATUS)
41261.1Skamil	int status;
41271.1Skamil#endif
41281.1Skamil	struct reg r;
41291.1Skamil
41301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41321.1Skamil	if (child == 0) {
41331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41351.1Skamil
41361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41381.1Skamil
41391.13Schristos		DPRINTF("Before exiting of the child process\n");
41401.1Skamil		_exit(exitval);
41411.1Skamil	}
41421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41431.1Skamil
41441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41461.1Skamil
41471.1Skamil	validate_status_stopped(status, sigval);
41481.1Skamil
41491.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41511.1Skamil
41521.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
41531.1Skamil
41541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41551.1Skamil	    "without signal to be sent\n");
41561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41571.1Skamil
41581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41601.1Skamil
41611.1Skamil	validate_status_exited(status, exitval);
41621.1Skamil
41631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41651.1Skamil}
41661.1Skamil#endif
41671.1Skamil
41681.1Skamil#if defined(HAVE_GPREGS)
41691.1SkamilATF_TC(regs4);
41701.1SkamilATF_TC_HEAD(regs4, tc)
41711.1Skamil{
41721.1Skamil	atf_tc_set_md_var(tc, "descr",
41731.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
41741.1Skamil}
41751.1Skamil
41761.1SkamilATF_TC_BODY(regs4, tc)
41771.1Skamil{
41781.1Skamil	const int exitval = 5;
41791.1Skamil	const int sigval = SIGSTOP;
41801.1Skamil	pid_t child, wpid;
41811.1Skamil#if defined(TWAIT_HAVE_STATUS)
41821.1Skamil	int status;
41831.1Skamil#endif
41841.1Skamil	struct reg r;
41851.1Skamil
41861.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41871.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41881.1Skamil	if (child == 0) {
41891.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41901.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41911.1Skamil
41921.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41931.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41941.1Skamil
41951.13Schristos		DPRINTF("Before exiting of the child process\n");
41961.1Skamil		_exit(exitval);
41971.1Skamil	}
41981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41991.1Skamil
42001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42021.1Skamil
42031.1Skamil	validate_status_stopped(status, sigval);
42041.1Skamil
42051.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42071.1Skamil
42081.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
42091.1Skamil
42101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42111.1Skamil	    "without signal to be sent\n");
42121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42131.1Skamil
42141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42161.1Skamil
42171.1Skamil	validate_status_exited(status, exitval);
42181.1Skamil
42191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42211.1Skamil}
42221.1Skamil#endif
42231.1Skamil
42241.1Skamil#if defined(HAVE_GPREGS)
42251.1SkamilATF_TC(regs5);
42261.1SkamilATF_TC_HEAD(regs5, tc)
42271.1Skamil{
42281.1Skamil	atf_tc_set_md_var(tc, "descr",
42291.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
42301.1Skamil}
42311.1Skamil
42321.1SkamilATF_TC_BODY(regs5, tc)
42331.1Skamil{
42341.1Skamil	const int exitval = 5;
42351.1Skamil	const int sigval = SIGSTOP;
42361.1Skamil	pid_t child, wpid;
42371.1Skamil#if defined(TWAIT_HAVE_STATUS)
42381.1Skamil	int status;
42391.1Skamil#endif
42401.1Skamil	struct reg r;
42411.1Skamil
42421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42441.1Skamil	if (child == 0) {
42451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42471.1Skamil
42481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42501.1Skamil
42511.13Schristos		DPRINTF("Before exiting of the child process\n");
42521.1Skamil		_exit(exitval);
42531.1Skamil	}
42541.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42551.1Skamil
42561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42581.1Skamil
42591.1Skamil	validate_status_stopped(status, sigval);
42601.1Skamil
42611.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42631.1Skamil
42641.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
42651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42661.1Skamil
42671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42681.1Skamil	    "without signal to be sent\n");
42691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42701.1Skamil
42711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42731.1Skamil
42741.1Skamil	validate_status_exited(status, exitval);
42751.1Skamil
42761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42781.1Skamil}
42791.1Skamil#endif
42801.1Skamil
42811.1Skamil#if defined(HAVE_FPREGS)
42821.1SkamilATF_TC(fpregs1);
42831.1SkamilATF_TC_HEAD(fpregs1, tc)
42841.1Skamil{
42851.1Skamil	atf_tc_set_md_var(tc, "descr",
42861.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
42871.1Skamil}
42881.1Skamil
42891.1SkamilATF_TC_BODY(fpregs1, tc)
42901.1Skamil{
42911.1Skamil	const int exitval = 5;
42921.1Skamil	const int sigval = SIGSTOP;
42931.1Skamil	pid_t child, wpid;
42941.1Skamil#if defined(TWAIT_HAVE_STATUS)
42951.1Skamil	int status;
42961.1Skamil#endif
42971.1Skamil	struct fpreg r;
42981.1Skamil
42991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43011.1Skamil	if (child == 0) {
43021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43041.1Skamil
43051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43071.1Skamil
43081.13Schristos		DPRINTF("Before exiting of the child process\n");
43091.1Skamil		_exit(exitval);
43101.1Skamil	}
43111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43121.1Skamil
43131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43151.1Skamil
43161.1Skamil	validate_status_stopped(status, sigval);
43171.1Skamil
43181.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43201.1Skamil
43211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43221.1Skamil	    "without signal to be sent\n");
43231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43241.1Skamil
43251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43271.1Skamil
43281.1Skamil	validate_status_exited(status, exitval);
43291.1Skamil
43301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43321.1Skamil}
43331.1Skamil#endif
43341.1Skamil
43351.1Skamil#if defined(HAVE_FPREGS)
43361.1SkamilATF_TC(fpregs2);
43371.1SkamilATF_TC_HEAD(fpregs2, tc)
43381.1Skamil{
43391.1Skamil	atf_tc_set_md_var(tc, "descr",
43401.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
43411.1Skamil	    "regs");
43421.1Skamil}
43431.1Skamil
43441.1SkamilATF_TC_BODY(fpregs2, tc)
43451.1Skamil{
43461.1Skamil	const int exitval = 5;
43471.1Skamil	const int sigval = SIGSTOP;
43481.1Skamil	pid_t child, wpid;
43491.1Skamil#if defined(TWAIT_HAVE_STATUS)
43501.1Skamil	int status;
43511.1Skamil#endif
43521.1Skamil	struct fpreg r;
43531.1Skamil
43541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43561.1Skamil	if (child == 0) {
43571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43591.1Skamil
43601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43621.1Skamil
43631.13Schristos		DPRINTF("Before exiting of the child process\n");
43641.1Skamil		_exit(exitval);
43651.1Skamil	}
43661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43671.1Skamil
43681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43701.1Skamil
43711.1Skamil	validate_status_stopped(status, sigval);
43721.1Skamil
43731.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43751.1Skamil
43761.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
43771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
43781.1Skamil
43791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43801.1Skamil	    "without signal to be sent\n");
43811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43821.1Skamil
43831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43851.1Skamil
43861.1Skamil	validate_status_exited(status, exitval);
43871.1Skamil
43881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43891.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43901.1Skamil}
43911.1Skamil#endif
43921.1Skamil
43931.1Skamil#if defined(PT_STEP)
43941.1Skamilstatic void
43951.2Skamilptrace_step(int N, int setstep)
43961.1Skamil{
43971.1Skamil	const int exitval = 5;
43981.1Skamil	const int sigval = SIGSTOP;
43991.1Skamil	pid_t child, wpid;
44001.1Skamil#if defined(TWAIT_HAVE_STATUS)
44011.1Skamil	int status;
44021.1Skamil#endif
44031.1Skamil	int happy;
44041.1Skamil
44051.1Skamil#if defined(__arm__)
44061.1Skamil	/* PT_STEP not supported on arm 32-bit */
44071.1Skamil	atf_tc_expect_fail("PR kern/52119");
44081.1Skamil#endif
44091.1Skamil
44101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44121.1Skamil	if (child == 0) {
44131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44151.1Skamil
44161.1Skamil		happy = check_happy(999);
44171.1Skamil
44181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44201.1Skamil
44211.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
44221.1Skamil
44231.13Schristos		DPRINTF("Before exiting of the child process\n");
44241.1Skamil		_exit(exitval);
44251.1Skamil	}
44261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44271.1Skamil
44281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44301.1Skamil
44311.1Skamil	validate_status_stopped(status, sigval);
44321.1Skamil
44331.1Skamil	while (N --> 0) {
44341.2Skamil		if (setstep) {
44351.13Schristos			DPRINTF("Before resuming the child process where it "
44361.2Skamil			    "left off and without signal to be sent (use "
44371.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
44381.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
44391.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
44401.2Skamil			    != -1);
44411.2Skamil		} else {
44421.13Schristos			DPRINTF("Before resuming the child process where it "
44431.2Skamil			    "left off and without signal to be sent (use "
44441.2Skamil			    "PT_STEP)\n");
44451.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
44461.2Skamil			    != -1);
44471.2Skamil		}
44481.1Skamil
44491.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44501.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
44511.1Skamil		    child);
44521.1Skamil
44531.1Skamil		validate_status_stopped(status, SIGTRAP);
44541.2Skamil
44551.2Skamil		if (setstep) {
44561.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
44571.2Skamil		}
44581.1Skamil	}
44591.1Skamil
44601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44611.1Skamil	    "without signal to be sent\n");
44621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44631.1Skamil
44641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44661.1Skamil
44671.1Skamil	validate_status_exited(status, exitval);
44681.1Skamil
44691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44711.1Skamil}
44721.1Skamil#endif
44731.1Skamil
44741.1Skamil#if defined(PT_STEP)
44751.1SkamilATF_TC(step1);
44761.1SkamilATF_TC_HEAD(step1, tc)
44771.1Skamil{
44781.1Skamil	atf_tc_set_md_var(tc, "descr",
44791.1Skamil	    "Verify single PT_STEP call");
44801.1Skamil}
44811.1Skamil
44821.1SkamilATF_TC_BODY(step1, tc)
44831.1Skamil{
44841.2Skamil	ptrace_step(1, 0);
44851.1Skamil}
44861.1Skamil#endif
44871.1Skamil
44881.1Skamil#if defined(PT_STEP)
44891.1SkamilATF_TC(step2);
44901.1SkamilATF_TC_HEAD(step2, tc)
44911.1Skamil{
44921.1Skamil	atf_tc_set_md_var(tc, "descr",
44931.1Skamil	    "Verify PT_STEP called twice");
44941.1Skamil}
44951.1Skamil
44961.1SkamilATF_TC_BODY(step2, tc)
44971.1Skamil{
44981.2Skamil	ptrace_step(2, 0);
44991.1Skamil}
45001.1Skamil#endif
45011.1Skamil
45021.1Skamil#if defined(PT_STEP)
45031.1SkamilATF_TC(step3);
45041.1SkamilATF_TC_HEAD(step3, tc)
45051.1Skamil{
45061.1Skamil	atf_tc_set_md_var(tc, "descr",
45071.1Skamil	    "Verify PT_STEP called three times");
45081.1Skamil}
45091.1Skamil
45101.1SkamilATF_TC_BODY(step3, tc)
45111.1Skamil{
45121.2Skamil	ptrace_step(3, 0);
45131.1Skamil}
45141.1Skamil#endif
45151.1Skamil
45161.1Skamil#if defined(PT_STEP)
45171.1SkamilATF_TC(step4);
45181.1SkamilATF_TC_HEAD(step4, tc)
45191.1Skamil{
45201.1Skamil	atf_tc_set_md_var(tc, "descr",
45211.1Skamil	    "Verify PT_STEP called four times");
45221.1Skamil}
45231.1Skamil
45241.1SkamilATF_TC_BODY(step4, tc)
45251.1Skamil{
45261.2Skamil	ptrace_step(4, 0);
45271.2Skamil}
45281.2Skamil#endif
45291.2Skamil
45301.2Skamil#if defined(PT_STEP)
45311.2SkamilATF_TC(setstep1);
45321.2SkamilATF_TC_HEAD(setstep1, tc)
45331.2Skamil{
45341.2Skamil	atf_tc_set_md_var(tc, "descr",
45351.2Skamil	    "Verify single PT_SETSTEP call");
45361.2Skamil}
45371.2Skamil
45381.2SkamilATF_TC_BODY(setstep1, tc)
45391.2Skamil{
45401.2Skamil	ptrace_step(1, 1);
45411.2Skamil}
45421.2Skamil#endif
45431.2Skamil
45441.2Skamil#if defined(PT_STEP)
45451.2SkamilATF_TC(setstep2);
45461.2SkamilATF_TC_HEAD(setstep2, tc)
45471.2Skamil{
45481.2Skamil	atf_tc_set_md_var(tc, "descr",
45491.2Skamil	    "Verify PT_SETSTEP called twice");
45501.2Skamil}
45511.2Skamil
45521.2SkamilATF_TC_BODY(setstep2, tc)
45531.2Skamil{
45541.2Skamil	ptrace_step(2, 1);
45551.2Skamil}
45561.2Skamil#endif
45571.2Skamil
45581.2Skamil#if defined(PT_STEP)
45591.2SkamilATF_TC(setstep3);
45601.2SkamilATF_TC_HEAD(setstep3, tc)
45611.2Skamil{
45621.2Skamil	atf_tc_set_md_var(tc, "descr",
45631.2Skamil	    "Verify PT_SETSTEP called three times");
45641.2Skamil}
45651.2Skamil
45661.2SkamilATF_TC_BODY(setstep3, tc)
45671.2Skamil{
45681.2Skamil	ptrace_step(3, 1);
45691.2Skamil}
45701.2Skamil#endif
45711.2Skamil
45721.2Skamil#if defined(PT_STEP)
45731.2SkamilATF_TC(setstep4);
45741.2SkamilATF_TC_HEAD(setstep4, tc)
45751.2Skamil{
45761.2Skamil	atf_tc_set_md_var(tc, "descr",
45771.2Skamil	    "Verify PT_SETSTEP called four times");
45781.2Skamil}
45791.2Skamil
45801.2SkamilATF_TC_BODY(setstep4, tc)
45811.2Skamil{
45821.2Skamil	ptrace_step(4, 1);
45831.1Skamil}
45841.1Skamil#endif
45851.1Skamil
45861.1SkamilATF_TC(kill1);
45871.1SkamilATF_TC_HEAD(kill1, tc)
45881.1Skamil{
45891.1Skamil	atf_tc_set_md_var(tc, "descr",
45901.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
45911.1Skamil}
45921.1Skamil
45931.1SkamilATF_TC_BODY(kill1, tc)
45941.1Skamil{
45951.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
45961.1Skamil	pid_t child, wpid;
45971.1Skamil#if defined(TWAIT_HAVE_STATUS)
45981.1Skamil	int status;
45991.1Skamil#endif
46001.1Skamil
46011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46031.1Skamil	if (child == 0) {
46041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46061.1Skamil
46071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46091.1Skamil
46101.1Skamil		/* NOTREACHED */
46111.1Skamil		FORKEE_ASSERTX(0 &&
46121.1Skamil		    "Child should be terminated by a signal from its parent");
46131.1Skamil	}
46141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46151.1Skamil
46161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46181.1Skamil
46191.1Skamil	validate_status_stopped(status, sigval);
46201.1Skamil
46211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46221.1Skamil	    "without signal to be sent\n");
46231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
46241.1Skamil
46251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46271.1Skamil
46281.1Skamil	validate_status_signaled(status, sigsent, 0);
46291.1Skamil
46301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46321.1Skamil}
46331.1Skamil
46341.1SkamilATF_TC(kill2);
46351.1SkamilATF_TC_HEAD(kill2, tc)
46361.1Skamil{
46371.1Skamil	atf_tc_set_md_var(tc, "descr",
46381.1Skamil	    "Verify that PT_KILL terminates child");
46391.1Skamil}
46401.1Skamil
46411.1SkamilATF_TC_BODY(kill2, tc)
46421.1Skamil{
46431.1Skamil	const int sigval = SIGSTOP;
46441.1Skamil	pid_t child, wpid;
46451.1Skamil#if defined(TWAIT_HAVE_STATUS)
46461.1Skamil	int status;
46471.1Skamil#endif
46481.1Skamil
46491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46511.1Skamil	if (child == 0) {
46521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46541.1Skamil
46551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46571.1Skamil
46581.1Skamil		/* NOTREACHED */
46591.1Skamil		FORKEE_ASSERTX(0 &&
46601.1Skamil		    "Child should be terminated by a signal from its parent");
46611.1Skamil	}
46621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46631.1Skamil
46641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46661.1Skamil
46671.1Skamil	validate_status_stopped(status, sigval);
46681.1Skamil
46691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46701.1Skamil	    "without signal to be sent\n");
46711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
46721.1Skamil
46731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46751.1Skamil
46761.1Skamil	validate_status_signaled(status, SIGKILL, 0);
46771.1Skamil
46781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46801.1Skamil}
46811.1Skamil
46821.1SkamilATF_TC(lwpinfo1);
46831.1SkamilATF_TC_HEAD(lwpinfo1, tc)
46841.1Skamil{
46851.1Skamil	atf_tc_set_md_var(tc, "descr",
46861.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
46871.1Skamil}
46881.1Skamil
46891.1SkamilATF_TC_BODY(lwpinfo1, tc)
46901.1Skamil{
46911.1Skamil	const int exitval = 5;
46921.1Skamil	const int sigval = SIGSTOP;
46931.1Skamil	pid_t child, wpid;
46941.1Skamil#if defined(TWAIT_HAVE_STATUS)
46951.1Skamil	int status;
46961.1Skamil#endif
46971.1Skamil	struct ptrace_lwpinfo info = {0, 0};
46981.1Skamil
46991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47011.1Skamil	if (child == 0) {
47021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47041.1Skamil
47051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47071.1Skamil
47081.13Schristos		DPRINTF("Before exiting of the child process\n");
47091.1Skamil		_exit(exitval);
47101.1Skamil	}
47111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47121.1Skamil
47131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47151.1Skamil
47161.1Skamil	validate_status_stopped(status, sigval);
47171.1Skamil
47181.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47201.1Skamil
47211.13Schristos	DPRINTF("Assert that there exists a thread\n");
47221.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
47231.1Skamil
47241.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
47251.1Skamil	    info.pl_lwpid);
47261.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
47271.1Skamil	    "Received event %d != expected event %d",
47281.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
47291.1Skamil
47301.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47321.1Skamil
47331.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
47341.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
47351.1Skamil
47361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47371.1Skamil	    "without signal to be sent\n");
47381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47391.1Skamil
47401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47421.1Skamil
47431.1Skamil	validate_status_exited(status, exitval);
47441.1Skamil
47451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47471.1Skamil}
47481.1Skamil
47491.1Skamil#if defined(TWAIT_HAVE_PID)
47501.1SkamilATF_TC(lwpinfo2);
47511.1SkamilATF_TC_HEAD(lwpinfo2, tc)
47521.1Skamil{
47531.1Skamil	atf_tc_set_md_var(tc, "descr",
47541.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
47551.1Skamil	    "tracer)");
47561.1Skamil}
47571.1Skamil
47581.1SkamilATF_TC_BODY(lwpinfo2, tc)
47591.1Skamil{
47601.1Skamil	struct msg_fds parent_tracee, parent_tracer;
47611.1Skamil	const int exitval_tracee = 5;
47621.1Skamil	const int exitval_tracer = 10;
47631.1Skamil	pid_t tracee, tracer, wpid;
47641.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
47651.1Skamil#if defined(TWAIT_HAVE_STATUS)
47661.1Skamil	int status;
47671.1Skamil#endif
47681.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47691.1Skamil
47701.13Schristos	DPRINTF("Spawn tracee\n");
47711.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
47721.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
47731.1Skamil	tracee = atf_utils_fork();
47741.1Skamil	if (tracee == 0) {
47751.1Skamil
47761.1Skamil		/* Wait for message from the parent */
47771.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
47781.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
47791.1Skamil
47801.1Skamil		_exit(exitval_tracee);
47811.1Skamil	}
47821.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
47831.1Skamil
47841.13Schristos	DPRINTF("Spawn debugger\n");
47851.1Skamil	tracer = atf_utils_fork();
47861.1Skamil	if (tracer == 0) {
47871.1Skamil		/* No IPC to communicate with the child */
47881.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
47891.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
47901.1Skamil
47911.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
47921.1Skamil		FORKEE_REQUIRE_SUCCESS(
47931.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
47941.1Skamil
47951.1Skamil		forkee_status_stopped(status, SIGSTOP);
47961.1Skamil
47971.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47981.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
47991.1Skamil		    != -1);
48001.1Skamil
48011.13Schristos		DPRINTF("Assert that there exists a thread\n");
48021.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
48031.1Skamil
48041.13Schristos		DPRINTF("Assert that lwp thread %d received event "
48051.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
48061.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
48071.1Skamil
48081.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48091.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48101.1Skamil		    != -1);
48111.1Skamil
48121.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
48131.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
48141.1Skamil
48151.1Skamil		/* Resume tracee with PT_CONTINUE */
48161.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
48171.1Skamil
48181.1Skamil		/* Inform parent that tracer has attached to tracee */
48191.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
48201.1Skamil		/* Wait for parent */
48211.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
48221.1Skamil
48231.1Skamil		/* Wait for tracee and assert that it exited */
48241.1Skamil		FORKEE_REQUIRE_SUCCESS(
48251.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48261.1Skamil
48271.1Skamil		forkee_status_exited(status, exitval_tracee);
48281.1Skamil
48291.13Schristos		DPRINTF("Before exiting of the tracer process\n");
48301.1Skamil		_exit(exitval_tracer);
48311.1Skamil	}
48321.1Skamil
48331.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
48341.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
48351.1Skamil
48361.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
48371.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
48381.1Skamil
48391.13Schristos	DPRINTF("Detect that tracee is zombie\n");
48401.1Skamil	await_zombie(tracee);
48411.1Skamil
48421.13Schristos	DPRINTF("Assert that there is no status about tracee - "
48431.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
48441.1Skamil	TWAIT_REQUIRE_SUCCESS(
48451.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
48461.1Skamil
48471.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
48481.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
48491.1Skamil
48501.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
48511.1Skamil	    TWAIT_FNAME);
48521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
48531.1Skamil	    tracer);
48541.1Skamil
48551.1Skamil	validate_status_exited(status, exitval_tracer);
48561.1Skamil
48571.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
48581.1Skamil	    TWAIT_FNAME);
48591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
48601.1Skamil	    tracee);
48611.1Skamil
48621.1Skamil	validate_status_exited(status, exitval_tracee);
48631.1Skamil
48641.1Skamil	msg_close(&parent_tracer);
48651.1Skamil	msg_close(&parent_tracee);
48661.1Skamil}
48671.1Skamil#endif
48681.1Skamil
48691.1SkamilATF_TC(siginfo1);
48701.1SkamilATF_TC_HEAD(siginfo1, tc)
48711.1Skamil{
48721.1Skamil	atf_tc_set_md_var(tc, "descr",
48731.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
48741.1Skamil}
48751.1Skamil
48761.1SkamilATF_TC_BODY(siginfo1, tc)
48771.1Skamil{
48781.1Skamil	const int exitval = 5;
48791.1Skamil	const int sigval = SIGTRAP;
48801.1Skamil	pid_t child, wpid;
48811.1Skamil#if defined(TWAIT_HAVE_STATUS)
48821.1Skamil	int status;
48831.1Skamil#endif
48841.1Skamil	struct ptrace_siginfo info;
48851.1Skamil	memset(&info, 0, sizeof(info));
48861.1Skamil
48871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48891.1Skamil	if (child == 0) {
48901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48921.1Skamil
48931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
48941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
48951.1Skamil
48961.13Schristos		DPRINTF("Before exiting of the child process\n");
48971.1Skamil		_exit(exitval);
48981.1Skamil	}
48991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49001.1Skamil
49011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49031.1Skamil
49041.1Skamil	validate_status_stopped(status, sigval);
49051.1Skamil
49061.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49081.1Skamil
49091.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49101.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49111.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49121.1Skamil	    info.psi_siginfo.si_errno);
49131.1Skamil
49141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49151.1Skamil	    "without signal to be sent\n");
49161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49171.1Skamil
49181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49201.1Skamil
49211.1Skamil	validate_status_exited(status, exitval);
49221.1Skamil
49231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49251.1Skamil}
49261.1Skamil
49271.1SkamilATF_TC(siginfo2);
49281.1SkamilATF_TC_HEAD(siginfo2, tc)
49291.1Skamil{
49301.1Skamil	atf_tc_set_md_var(tc, "descr",
49311.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
49321.1Skamil	    "modification of SIGINT from tracee");
49331.1Skamil}
49341.1Skamil
49351.1Skamilstatic int siginfo2_caught = 0;
49361.1Skamil
49371.1Skamilstatic void
49381.1Skamilsiginfo2_sighandler(int sig)
49391.1Skamil{
49401.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
49411.1Skamil
49421.1Skamil	++siginfo2_caught;
49431.1Skamil}
49441.1Skamil
49451.1SkamilATF_TC_BODY(siginfo2, tc)
49461.1Skamil{
49471.1Skamil	const int exitval = 5;
49481.1Skamil	const int sigval = SIGINT;
49491.1Skamil	pid_t child, wpid;
49501.1Skamil	struct sigaction sa;
49511.1Skamil#if defined(TWAIT_HAVE_STATUS)
49521.1Skamil	int status;
49531.1Skamil#endif
49541.1Skamil	struct ptrace_siginfo info;
49551.1Skamil	memset(&info, 0, sizeof(info));
49561.1Skamil
49571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49591.1Skamil	if (child == 0) {
49601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49621.1Skamil
49631.1Skamil		sa.sa_handler = siginfo2_sighandler;
49641.1Skamil		sa.sa_flags = SA_SIGINFO;
49651.1Skamil		sigemptyset(&sa.sa_mask);
49661.1Skamil
49671.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
49681.1Skamil
49691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49711.1Skamil
49721.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
49731.1Skamil
49741.13Schristos		DPRINTF("Before exiting of the child process\n");
49751.1Skamil		_exit(exitval);
49761.1Skamil	}
49771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49781.1Skamil
49791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49811.1Skamil
49821.1Skamil	validate_status_stopped(status, sigval);
49831.1Skamil
49841.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49861.1Skamil
49871.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49881.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49891.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49901.1Skamil	    info.psi_siginfo.si_errno);
49911.1Skamil
49921.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
49931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
49941.1Skamil
49951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49961.1Skamil	    "without signal to be sent\n");
49971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
49981.1Skamil
49991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50011.1Skamil
50021.1Skamil	validate_status_exited(status, exitval);
50031.1Skamil
50041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50061.1Skamil}
50071.1Skamil
50081.1SkamilATF_TC(siginfo3);
50091.1SkamilATF_TC_HEAD(siginfo3, tc)
50101.1Skamil{
50111.1Skamil	atf_tc_set_md_var(tc, "descr",
50121.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
50131.1Skamil	    "setting signal to new value");
50141.1Skamil}
50151.1Skamil
50161.1Skamilstatic int siginfo3_caught = 0;
50171.1Skamil
50181.1Skamilstatic void
50191.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
50201.1Skamil{
50211.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
50221.1Skamil
50231.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
50241.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
50251.1Skamil
50261.1Skamil	++siginfo3_caught;
50271.1Skamil}
50281.1Skamil
50291.1SkamilATF_TC_BODY(siginfo3, tc)
50301.1Skamil{
50311.1Skamil	const int exitval = 5;
50321.1Skamil	const int sigval = SIGINT;
50331.1Skamil	const int sigfaked = SIGTRAP;
50341.1Skamil	const int sicodefaked = TRAP_BRKPT;
50351.1Skamil	pid_t child, wpid;
50361.1Skamil	struct sigaction sa;
50371.1Skamil#if defined(TWAIT_HAVE_STATUS)
50381.1Skamil	int status;
50391.1Skamil#endif
50401.1Skamil	struct ptrace_siginfo info;
50411.1Skamil	memset(&info, 0, sizeof(info));
50421.1Skamil
50431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50451.1Skamil	if (child == 0) {
50461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50481.1Skamil
50491.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
50501.1Skamil		sa.sa_flags = SA_SIGINFO;
50511.1Skamil		sigemptyset(&sa.sa_mask);
50521.1Skamil
50531.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
50541.1Skamil
50551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50571.1Skamil
50581.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
50591.1Skamil
50601.13Schristos		DPRINTF("Before exiting of the child process\n");
50611.1Skamil		_exit(exitval);
50621.1Skamil	}
50631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50641.1Skamil
50651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50671.1Skamil
50681.1Skamil	validate_status_stopped(status, sigval);
50691.1Skamil
50701.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50721.1Skamil
50731.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50741.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50751.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50761.1Skamil	    info.psi_siginfo.si_errno);
50771.1Skamil
50781.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
50791.1Skamil	    sigfaked, sicodefaked);
50801.1Skamil	info.psi_siginfo.si_signo = sigfaked;
50811.1Skamil	info.psi_siginfo.si_code = sicodefaked;
50821.1Skamil
50831.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50851.1Skamil
50861.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50881.1Skamil
50891.13Schristos	DPRINTF("Before checking siginfo_t\n");
50901.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
50911.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
50921.1Skamil
50931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50941.1Skamil	    "without signal to be sent\n");
50951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
50961.1Skamil
50971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50991.1Skamil
51001.1Skamil	validate_status_exited(status, exitval);
51011.1Skamil
51021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51041.1Skamil}
51051.1Skamil
51061.1SkamilATF_TC(siginfo4);
51071.1SkamilATF_TC_HEAD(siginfo4, tc)
51081.1Skamil{
51091.1Skamil	atf_tc_set_md_var(tc, "descr",
51101.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
51111.1Skamil}
51121.1Skamil
51131.1SkamilATF_TC_BODY(siginfo4, tc)
51141.1Skamil{
51151.1Skamil	const int sigval = SIGTRAP;
51161.1Skamil	pid_t child, wpid;
51171.1Skamil#if defined(TWAIT_HAVE_STATUS)
51181.1Skamil	int status;
51191.1Skamil#endif
51201.1Skamil
51211.1Skamil	struct ptrace_siginfo info;
51221.1Skamil	memset(&info, 0, sizeof(info));
51231.1Skamil
51241.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51251.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51261.1Skamil	if (child == 0) {
51271.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51281.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51291.1Skamil
51301.13Schristos		DPRINTF("Before calling execve(2) from child\n");
51311.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
51321.1Skamil
51331.1Skamil		FORKEE_ASSERT(0 && "Not reached");
51341.1Skamil	}
51351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51361.1Skamil
51371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51391.1Skamil
51401.1Skamil	validate_status_stopped(status, sigval);
51411.1Skamil
51421.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51441.1Skamil
51451.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51461.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51471.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51481.1Skamil	    info.psi_siginfo.si_errno);
51491.1Skamil
51501.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51511.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
51521.1Skamil
51531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51541.1Skamil	    "without signal to be sent\n");
51551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51561.1Skamil
51571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51591.1Skamil
51601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51621.1Skamil}
51631.1Skamil
51641.1Skamil#if defined(TWAIT_HAVE_PID)
51651.1SkamilATF_TC(siginfo5);
51661.1SkamilATF_TC_HEAD(siginfo5, tc)
51671.1Skamil{
51681.1Skamil	atf_tc_set_md_var(tc, "descr",
51691.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
51701.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
51711.1Skamil}
51721.1Skamil
51731.1SkamilATF_TC_BODY(siginfo5, tc)
51741.1Skamil{
51751.1Skamil	const int exitval = 5;
51761.1Skamil	const int exitval2 = 15;
51771.1Skamil	const int sigval = SIGSTOP;
51781.1Skamil	pid_t child, child2, wpid;
51791.1Skamil#if defined(TWAIT_HAVE_STATUS)
51801.1Skamil	int status;
51811.1Skamil#endif
51821.1Skamil	ptrace_state_t state;
51831.1Skamil	const int slen = sizeof(state);
51841.1Skamil	ptrace_event_t event;
51851.1Skamil	const int elen = sizeof(event);
51861.1Skamil	struct ptrace_siginfo info;
51871.1Skamil
51881.1Skamil	memset(&info, 0, sizeof(info));
51891.1Skamil
51901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51921.1Skamil	if (child == 0) {
51931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51951.1Skamil
51961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
51971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
51981.1Skamil
51991.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
52001.1Skamil
52011.1Skamil		if (child2 == 0)
52021.1Skamil			_exit(exitval2);
52031.1Skamil
52041.1Skamil		FORKEE_REQUIRE_SUCCESS
52051.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
52061.1Skamil
52071.1Skamil		forkee_status_exited(status, exitval2);
52081.1Skamil
52091.13Schristos		DPRINTF("Before exiting of the child process\n");
52101.1Skamil		_exit(exitval);
52111.1Skamil	}
52121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52131.1Skamil
52141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52161.1Skamil
52171.1Skamil	validate_status_stopped(status, sigval);
52181.1Skamil
52191.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52211.1Skamil
52221.13Schristos	DPRINTF("Before checking siginfo_t\n");
52231.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
52241.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
52251.1Skamil
52261.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
52271.1Skamil	event.pe_set_event = PTRACE_FORK;
52281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52291.1Skamil
52301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52311.1Skamil	    "without signal to be sent\n");
52321.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
52331.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
52341.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
52351.1Skamil                "state.pe_other_pid=child)\n", child);
52361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52371.1Skamil
52381.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
52391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52401.1Skamil
52411.1Skamil	validate_status_stopped(status, SIGTRAP);
52421.1Skamil
52431.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52451.1Skamil
52461.13Schristos	DPRINTF("Before checking siginfo_t\n");
52471.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52481.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52491.1Skamil
52501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52511.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52521.1Skamil
52531.1Skamil	child2 = state.pe_other_pid;
52541.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
52551.1Skamil
52561.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
52571.1Skamil	    TWAIT_FNAME, child2, child);
52581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52591.1Skamil	    child2);
52601.1Skamil
52611.1Skamil	validate_status_stopped(status, SIGTRAP);
52621.1Skamil
52631.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52651.1Skamil
52661.13Schristos	DPRINTF("Before checking siginfo_t\n");
52671.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52681.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52691.1Skamil
52701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
52711.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52721.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
52731.1Skamil
52741.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
52751.1Skamil	    "without signal to be sent\n");
52761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
52771.1Skamil
52781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52791.1Skamil	    "without signal to be sent\n");
52801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52811.1Skamil
52821.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
52831.1Skamil	    TWAIT_FNAME);
52841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52851.1Skamil	    child2);
52861.1Skamil
52871.1Skamil	validate_status_exited(status, exitval2);
52881.1Skamil
52891.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
52901.1Skamil	    TWAIT_FNAME);
52911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
52921.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
52931.1Skamil
52941.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
52951.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
52961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52971.1Skamil
52981.1Skamil	validate_status_stopped(status, SIGCHLD);
52991.1Skamil
53001.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53021.1Skamil
53031.13Schristos	DPRINTF("Before checking siginfo_t\n");
53041.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
53051.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
53061.1Skamil
53071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53081.1Skamil	    "without signal to be sent\n");
53091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53101.1Skamil
53111.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53121.1Skamil	    TWAIT_FNAME);
53131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53141.1Skamil
53151.1Skamil	validate_status_exited(status, exitval);
53161.1Skamil
53171.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53181.1Skamil	    TWAIT_FNAME);
53191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53201.1Skamil}
53211.1Skamil#endif
53221.1Skamil
53231.1Skamil#if defined(PT_STEP)
53241.1SkamilATF_TC(siginfo6);
53251.1SkamilATF_TC_HEAD(siginfo6, tc)
53261.1Skamil{
53271.1Skamil	atf_tc_set_md_var(tc, "descr",
53281.1Skamil	    "Verify single PT_STEP call with signal information check");
53291.1Skamil}
53301.1Skamil
53311.1SkamilATF_TC_BODY(siginfo6, tc)
53321.1Skamil{
53331.1Skamil	const int exitval = 5;
53341.1Skamil	const int sigval = SIGSTOP;
53351.1Skamil	pid_t child, wpid;
53361.1Skamil#if defined(TWAIT_HAVE_STATUS)
53371.1Skamil	int status;
53381.1Skamil#endif
53391.1Skamil	int happy;
53401.1Skamil	struct ptrace_siginfo info;
53411.1Skamil
53421.1Skamil#if defined(__arm__)
53431.1Skamil	/* PT_STEP not supported on arm 32-bit */
53441.1Skamil	atf_tc_expect_fail("PR kern/52119");
53451.1Skamil#endif
53461.1Skamil
53471.1Skamil	memset(&info, 0, sizeof(info));
53481.1Skamil
53491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53511.1Skamil	if (child == 0) {
53521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53541.1Skamil
53551.1Skamil		happy = check_happy(100);
53561.1Skamil
53571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53591.1Skamil
53601.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
53611.1Skamil
53621.13Schristos		DPRINTF("Before exiting of the child process\n");
53631.1Skamil		_exit(exitval);
53641.1Skamil	}
53651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53661.1Skamil
53671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53691.1Skamil
53701.1Skamil	validate_status_stopped(status, sigval);
53711.1Skamil
53721.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53741.1Skamil
53751.13Schristos	DPRINTF("Before checking siginfo_t\n");
53761.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
53771.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
53781.1Skamil
53791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53801.1Skamil	    "without signal to be sent (use PT_STEP)\n");
53811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
53821.1Skamil
53831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53851.1Skamil
53861.1Skamil	validate_status_stopped(status, SIGTRAP);
53871.1Skamil
53881.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53901.1Skamil
53911.13Schristos	DPRINTF("Before checking siginfo_t\n");
53921.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
53931.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
53941.1Skamil
53951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53961.1Skamil	    "without signal to be sent\n");
53971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53981.1Skamil
53991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54011.1Skamil
54021.1Skamil	validate_status_exited(status, exitval);
54031.1Skamil
54041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54061.1Skamil}
54071.1Skamil#endif
54081.1Skamil
54091.1Skamilvolatile lwpid_t the_lwp_id = 0;
54101.1Skamil
54111.1Skamilstatic void
54121.1Skamillwp_main_func(void *arg)
54131.1Skamil{
54141.1Skamil	the_lwp_id = _lwp_self();
54151.1Skamil	_lwp_exit();
54161.1Skamil}
54171.1Skamil
54181.1SkamilATF_TC(lwp_create1);
54191.1SkamilATF_TC_HEAD(lwp_create1, tc)
54201.1Skamil{
54211.1Skamil	atf_tc_set_md_var(tc, "descr",
54221.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
54231.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
54241.1Skamil}
54251.1Skamil
54261.1SkamilATF_TC_BODY(lwp_create1, tc)
54271.1Skamil{
54281.1Skamil	const int exitval = 5;
54291.1Skamil	const int sigval = SIGSTOP;
54301.1Skamil	pid_t child, wpid;
54311.1Skamil#if defined(TWAIT_HAVE_STATUS)
54321.1Skamil	int status;
54331.1Skamil#endif
54341.1Skamil	ptrace_state_t state;
54351.1Skamil	const int slen = sizeof(state);
54361.1Skamil	ptrace_event_t event;
54371.1Skamil	const int elen = sizeof(event);
54381.1Skamil	ucontext_t uc;
54391.1Skamil	lwpid_t lid;
54401.1Skamil	static const size_t ssize = 16*1024;
54411.1Skamil	void *stack;
54421.1Skamil
54431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54451.1Skamil	if (child == 0) {
54461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54481.1Skamil
54491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54511.1Skamil
54521.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
54531.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
54541.1Skamil
54551.13Schristos		DPRINTF("Before making context for new lwp in child\n");
54561.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
54571.1Skamil
54581.13Schristos		DPRINTF("Before creating new in child\n");
54591.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
54601.1Skamil
54611.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
54621.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
54631.1Skamil
54641.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
54651.1Skamil		    "are the same\n", lid, the_lwp_id);
54661.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
54671.1Skamil
54681.13Schristos		DPRINTF("Before exiting of the child process\n");
54691.1Skamil		_exit(exitval);
54701.1Skamil	}
54711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54721.1Skamil
54731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54751.1Skamil
54761.1Skamil	validate_status_stopped(status, sigval);
54771.1Skamil
54781.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
54791.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
54801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
54811.1Skamil
54821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54831.1Skamil	    "without signal to be sent\n");
54841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54851.1Skamil
54861.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
54871.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
54881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54891.1Skamil
54901.1Skamil	validate_status_stopped(status, SIGTRAP);
54911.1Skamil
54921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
54931.1Skamil
54941.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
54951.1Skamil
54961.1Skamil	lid = state.pe_lwp;
54971.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
54981.1Skamil
54991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55001.1Skamil	    "without signal to be sent\n");
55011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55021.1Skamil
55031.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
55041.1Skamil	    TWAIT_FNAME);
55051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55061.1Skamil
55071.1Skamil	validate_status_exited(status, exitval);
55081.1Skamil
55091.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
55101.1Skamil	    TWAIT_FNAME);
55111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55121.1Skamil}
55131.1Skamil
55141.1SkamilATF_TC(lwp_exit1);
55151.1SkamilATF_TC_HEAD(lwp_exit1, tc)
55161.1Skamil{
55171.1Skamil	atf_tc_set_md_var(tc, "descr",
55181.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
55191.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
55201.1Skamil}
55211.1Skamil
55221.1SkamilATF_TC_BODY(lwp_exit1, tc)
55231.1Skamil{
55241.1Skamil	const int exitval = 5;
55251.1Skamil	const int sigval = SIGSTOP;
55261.1Skamil	pid_t child, wpid;
55271.1Skamil#if defined(TWAIT_HAVE_STATUS)
55281.1Skamil	int status;
55291.1Skamil#endif
55301.1Skamil	ptrace_state_t state;
55311.1Skamil	const int slen = sizeof(state);
55321.1Skamil	ptrace_event_t event;
55331.1Skamil	const int elen = sizeof(event);
55341.1Skamil	ucontext_t uc;
55351.1Skamil	lwpid_t lid;
55361.1Skamil	static const size_t ssize = 16*1024;
55371.1Skamil	void *stack;
55381.1Skamil
55391.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55401.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55411.1Skamil	if (child == 0) {
55421.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55431.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55441.1Skamil
55451.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55461.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55471.1Skamil
55481.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
55491.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
55501.1Skamil
55511.13Schristos		DPRINTF("Before making context for new lwp in child\n");
55521.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
55531.1Skamil
55541.13Schristos		DPRINTF("Before creating new in child\n");
55551.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
55561.1Skamil
55571.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
55581.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
55591.1Skamil
55601.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
55611.1Skamil		    "are the same\n", lid, the_lwp_id);
55621.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
55631.1Skamil
55641.13Schristos		DPRINTF("Before exiting of the child process\n");
55651.1Skamil		_exit(exitval);
55661.1Skamil	}
55671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55681.1Skamil
55691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55711.1Skamil
55721.1Skamil	validate_status_stopped(status, sigval);
55731.1Skamil
55741.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55751.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
55761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55771.1Skamil
55781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55791.1Skamil	    "without signal to be sent\n");
55801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55811.1Skamil
55821.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55831.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55851.1Skamil
55861.1Skamil	validate_status_stopped(status, SIGTRAP);
55871.1Skamil
55881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55891.1Skamil
55901.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
55911.1Skamil
55921.1Skamil	lid = state.pe_lwp;
55931.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
55941.1Skamil
55951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55961.1Skamil	    "without signal to be sent\n");
55971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55981.1Skamil
55991.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
56001.1Skamil	    TWAIT_FNAME);
56011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56021.1Skamil
56031.1Skamil	validate_status_exited(status, exitval);
56041.1Skamil
56051.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
56061.1Skamil	    TWAIT_FNAME);
56071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56081.1Skamil}
56091.1Skamil
56101.1SkamilATF_TC(signal1);
56111.1SkamilATF_TC_HEAD(signal1, tc)
56121.1Skamil{
56131.1Skamil	atf_tc_set_md_var(tc, "descr",
56141.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
56151.1Skamil	    "from catching other signals");
56161.1Skamil}
56171.1Skamil
56181.1SkamilATF_TC_BODY(signal1, tc)
56191.1Skamil{
56201.1Skamil	const int exitval = 5;
56211.1Skamil	const int sigval = SIGSTOP;
56221.1Skamil	const int sigmasked = SIGTRAP;
56231.1Skamil	const int signotmasked = SIGINT;
56241.1Skamil	pid_t child, wpid;
56251.1Skamil#if defined(TWAIT_HAVE_STATUS)
56261.1Skamil	int status;
56271.1Skamil#endif
56281.1Skamil	sigset_t intmask;
56291.1Skamil
56301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56321.1Skamil	if (child == 0) {
56331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56351.1Skamil
56361.1Skamil		sigemptyset(&intmask);
56371.1Skamil		sigaddset(&intmask, sigmasked);
56381.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56391.1Skamil
56401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56421.1Skamil
56431.13Schristos		DPRINTF("Before raising %s from child\n",
56441.1Skamil		    strsignal(signotmasked));
56451.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
56461.1Skamil
56471.13Schristos		DPRINTF("Before exiting of the child process\n");
56481.1Skamil		_exit(exitval);
56491.1Skamil	}
56501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56511.1Skamil
56521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56541.1Skamil
56551.1Skamil	validate_status_stopped(status, sigval);
56561.1Skamil
56571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56581.1Skamil	    "without signal to be sent\n");
56591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56601.1Skamil
56611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56631.1Skamil
56641.1Skamil	validate_status_stopped(status, signotmasked);
56651.1Skamil
56661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56671.1Skamil	    "without signal to be sent\n");
56681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56691.1Skamil
56701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56721.1Skamil
56731.1Skamil	validate_status_exited(status, exitval);
56741.1Skamil
56751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56771.1Skamil}
56781.1Skamil
56791.1SkamilATF_TC(signal2);
56801.1SkamilATF_TC_HEAD(signal2, tc)
56811.1Skamil{
56821.1Skamil	atf_tc_set_md_var(tc, "descr",
56831.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
56841.1Skamil	    "catching this raised signal");
56851.1Skamil}
56861.1Skamil
56871.1SkamilATF_TC_BODY(signal2, tc)
56881.1Skamil{
56891.1Skamil	const int exitval = 5;
56901.1Skamil	const int sigval = SIGSTOP;
56911.1Skamil	const int sigmasked = SIGTRAP;
56921.1Skamil	pid_t child, wpid;
56931.1Skamil#if defined(TWAIT_HAVE_STATUS)
56941.1Skamil	int status;
56951.1Skamil#endif
56961.1Skamil	sigset_t intmask;
56971.1Skamil
56981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57001.1Skamil	if (child == 0) {
57011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57031.1Skamil
57041.1Skamil		sigemptyset(&intmask);
57051.1Skamil		sigaddset(&intmask, sigmasked);
57061.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57071.1Skamil
57081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57101.1Skamil
57111.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
57121.1Skamil		    strsignal(sigmasked));
57131.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
57141.1Skamil
57151.13Schristos		DPRINTF("Before exiting of the child process\n");
57161.1Skamil		_exit(exitval);
57171.1Skamil	}
57181.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57191.1Skamil
57201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57221.1Skamil
57231.1Skamil	validate_status_stopped(status, sigval);
57241.1Skamil
57251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57261.1Skamil	    "without signal to be sent\n");
57271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57281.1Skamil
57291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57311.1Skamil
57321.1Skamil	validate_status_exited(status, exitval);
57331.1Skamil
57341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57361.1Skamil}
57371.1Skamil
57381.1SkamilATF_TC(signal3);
57391.1SkamilATF_TC_HEAD(signal3, tc)
57401.1Skamil{
57411.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57421.1Skamil	atf_tc_set_md_var(tc, "descr",
57431.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57441.1Skamil	    "catching software breakpoints");
57451.1Skamil}
57461.1Skamil
57471.1SkamilATF_TC_BODY(signal3, tc)
57481.1Skamil{
57491.1Skamil	const int exitval = 5;
57501.1Skamil	const int sigval = SIGSTOP;
57511.1Skamil	const int sigmasked = SIGTRAP;
57521.1Skamil	pid_t child, wpid;
57531.1Skamil#if defined(TWAIT_HAVE_STATUS)
57541.1Skamil	int status;
57551.1Skamil#endif
57561.1Skamil	sigset_t intmask;
57571.1Skamil
57581.20Skamil	atf_tc_expect_fail("PR kern/51918");
57591.20Skamil
57601.20Skamil	// This test breaks now on some ports, temporarily disable it
57611.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
57621.20Skamil
57631.10Smartin#if defined(__sparc__)
57641.7Skamil	atf_tc_expect_timeout("PR kern/52167");
57651.7Skamil
57661.7Skamil	// timeout wins, failure still valid
57671.7Skamil	// atf_tc_expect_fail("PR kern/51918");
57681.7Skamil#endif
57691.1Skamil
57701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57721.1Skamil	if (child == 0) {
57731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57751.1Skamil
57761.1Skamil		sigemptyset(&intmask);
57771.1Skamil		sigaddset(&intmask, sigmasked);
57781.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57791.1Skamil
57801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57821.1Skamil
57831.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
57841.4Skamil
57851.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
57861.4Skamil		PTRACE_BREAKPOINT_ASM;
57871.1Skamil#else
57881.4Skamil		/* port me */
57891.1Skamil#endif
57901.1Skamil
57911.13Schristos		DPRINTF("Before exiting of the child process\n");
57921.1Skamil		_exit(exitval);
57931.1Skamil	}
57941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57951.1Skamil
57961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57981.1Skamil
57991.1Skamil	validate_status_stopped(status, sigval);
58001.1Skamil
58011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58021.1Skamil	    "without signal to be sent\n");
58031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58041.1Skamil
58051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58071.1Skamil
58081.1Skamil	validate_status_stopped(status, sigmasked);
58091.1Skamil
58101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58111.1Skamil	    "without signal to be sent\n");
58121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58131.1Skamil
58141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58161.1Skamil
58171.1Skamil	validate_status_exited(status, exitval);
58181.1Skamil
58191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58211.1Skamil}
58221.1Skamil
58231.1Skamil#if defined(PT_STEP)
58241.1SkamilATF_TC(signal4);
58251.1SkamilATF_TC_HEAD(signal4, tc)
58261.1Skamil{
58271.1Skamil	atf_tc_set_md_var(tc, "descr",
58281.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58291.1Skamil	    "catching single step trap");
58301.1Skamil}
58311.1Skamil
58321.1SkamilATF_TC_BODY(signal4, tc)
58331.1Skamil{
58341.1Skamil	const int exitval = 5;
58351.1Skamil	const int sigval = SIGSTOP;
58361.1Skamil	const int sigmasked = SIGTRAP;
58371.1Skamil	pid_t child, wpid;
58381.1Skamil#if defined(TWAIT_HAVE_STATUS)
58391.1Skamil	int status;
58401.1Skamil#endif
58411.1Skamil	sigset_t intmask;
58421.1Skamil	int happy;
58431.1Skamil
58441.1Skamil#if defined(__arm__)
58451.5Skamil	/* PT_STEP not supported on arm 32-bit */
58461.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
58471.1Skamil#endif
58481.1Skamil
58491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58511.1Skamil	if (child == 0) {
58521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58541.1Skamil
58551.1Skamil		happy = check_happy(100);
58561.1Skamil
58571.1Skamil		sigemptyset(&intmask);
58581.1Skamil		sigaddset(&intmask, sigmasked);
58591.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58601.1Skamil
58611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58631.1Skamil
58641.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
58651.1Skamil
58661.13Schristos		DPRINTF("Before exiting of the child process\n");
58671.1Skamil		_exit(exitval);
58681.1Skamil	}
58691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58701.1Skamil
58711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58731.1Skamil
58741.1Skamil	validate_status_stopped(status, sigval);
58751.1Skamil
58761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58771.1Skamil	    "without signal to be sent\n");
58781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
58791.1Skamil
58801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58821.1Skamil
58831.1Skamil	validate_status_stopped(status, sigmasked);
58841.1Skamil
58851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58861.1Skamil	    "without signal to be sent\n");
58871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58881.1Skamil
58891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58911.1Skamil
58921.1Skamil	validate_status_exited(status, exitval);
58931.1Skamil
58941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58961.1Skamil}
58971.1Skamil#endif
58981.1Skamil
58991.1SkamilATF_TC(signal5);
59001.1SkamilATF_TC_HEAD(signal5, tc)
59011.1Skamil{
59021.1Skamil	atf_tc_set_md_var(tc, "descr",
59031.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59041.1Skamil	    "catching exec() breakpoint");
59051.1Skamil}
59061.1Skamil
59071.1SkamilATF_TC_BODY(signal5, tc)
59081.1Skamil{
59091.1Skamil	const int exitval = 5;
59101.1Skamil	const int sigval = SIGSTOP;
59111.1Skamil	const int sigmasked = SIGTRAP;
59121.1Skamil	pid_t child, wpid;
59131.1Skamil#if defined(TWAIT_HAVE_STATUS)
59141.1Skamil	int status;
59151.1Skamil#endif
59161.1Skamil	sigset_t intmask;
59171.1Skamil
59181.14Schristos	atf_tc_expect_fail("wrong signal");
59191.14Schristos
59201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59221.1Skamil	if (child == 0) {
59231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59251.1Skamil
59261.1Skamil		sigemptyset(&intmask);
59271.1Skamil		sigaddset(&intmask, sigmasked);
59281.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59291.1Skamil
59301.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59311.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59321.1Skamil
59331.13Schristos		DPRINTF("Before calling execve(2) from child\n");
59341.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
59351.1Skamil
59361.13Schristos		DPRINTF("Before exiting of the child process\n");
59371.1Skamil		_exit(exitval);
59381.1Skamil	}
59391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59401.1Skamil
59411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59431.1Skamil
59441.1Skamil	validate_status_stopped(status, sigval);
59451.1Skamil
59461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59471.1Skamil	    "without signal to be sent\n");
59481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59491.1Skamil
59501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59521.1Skamil
59531.1Skamil	validate_status_stopped(status, sigmasked);
59541.1Skamil
59551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59561.1Skamil	    "without signal to be sent\n");
59571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59581.1Skamil
59591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59611.1Skamil
59621.1Skamil	validate_status_exited(status, exitval);
59631.1Skamil
59641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59661.1Skamil}
59671.1Skamil
59681.1Skamil#if defined(TWAIT_HAVE_PID)
59691.1SkamilATF_TC(signal6);
59701.1SkamilATF_TC_HEAD(signal6, tc)
59711.1Skamil{
59721.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
59731.1Skamil	atf_tc_set_md_var(tc, "descr",
59741.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59751.1Skamil	    "catching PTRACE_FORK breakpoint");
59761.1Skamil}
59771.1Skamil
59781.1SkamilATF_TC_BODY(signal6, tc)
59791.1Skamil{
59801.1Skamil	const int exitval = 5;
59811.1Skamil	const int exitval2 = 15;
59821.1Skamil	const int sigval = SIGSTOP;
59831.1Skamil	const int sigmasked = SIGTRAP;
59841.1Skamil	pid_t child, child2, wpid;
59851.1Skamil#if defined(TWAIT_HAVE_STATUS)
59861.1Skamil	int status;
59871.1Skamil#endif
59881.1Skamil	sigset_t intmask;
59891.1Skamil	ptrace_state_t state;
59901.1Skamil	const int slen = sizeof(state);
59911.1Skamil	ptrace_event_t event;
59921.1Skamil	const int elen = sizeof(event);
59931.1Skamil
59941.38Skamil	atf_tc_expect_fail("PR kern/51918");
59951.14Schristos
59961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59981.1Skamil	if (child == 0) {
59991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60011.1Skamil
60021.1Skamil		sigemptyset(&intmask);
60031.1Skamil		sigaddset(&intmask, sigmasked);
60041.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60051.1Skamil
60061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60081.1Skamil
60091.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
60101.1Skamil
60111.1Skamil		if (child2 == 0)
60121.1Skamil			_exit(exitval2);
60131.1Skamil
60141.1Skamil		FORKEE_REQUIRE_SUCCESS
60151.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60161.1Skamil
60171.1Skamil		forkee_status_exited(status, exitval2);
60181.1Skamil
60191.13Schristos		DPRINTF("Before exiting of the child process\n");
60201.1Skamil		_exit(exitval);
60211.1Skamil	}
60221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60231.1Skamil
60241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60261.1Skamil
60271.1Skamil	validate_status_stopped(status, sigval);
60281.1Skamil
60291.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
60301.1Skamil	event.pe_set_event = PTRACE_FORK;
60311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60321.1Skamil
60331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60341.1Skamil	    "without signal to be sent\n");
60351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60361.1Skamil
60371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60391.1Skamil
60401.1Skamil	validate_status_stopped(status, sigmasked);
60411.1Skamil
60421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60431.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60441.1Skamil
60451.1Skamil	child2 = state.pe_other_pid;
60461.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
60471.1Skamil
60481.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
60491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60501.1Skamil	    child2);
60511.1Skamil
60521.1Skamil	validate_status_stopped(status, SIGTRAP);
60531.1Skamil
60541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
60551.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60561.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
60571.1Skamil
60581.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
60591.1Skamil	    "without signal to be sent\n");
60601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
60611.1Skamil
60621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60631.1Skamil	    "without signal to be sent\n");
60641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60651.1Skamil
60661.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60671.1Skamil	    TWAIT_FNAME);
60681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60691.1Skamil	    child2);
60701.1Skamil
60711.1Skamil	validate_status_exited(status, exitval2);
60721.1Skamil
60731.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
60741.1Skamil	    TWAIT_FNAME);
60751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
60761.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
60771.1Skamil
60781.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60791.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
60801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60811.1Skamil
60821.1Skamil	validate_status_stopped(status, SIGCHLD);
60831.1Skamil
60841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60851.1Skamil	    "without signal to be sent\n");
60861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60871.1Skamil
60881.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60891.1Skamil	    TWAIT_FNAME);
60901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60911.1Skamil
60921.1Skamil	validate_status_exited(status, exitval);
60931.1Skamil
60941.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60951.1Skamil	    TWAIT_FNAME);
60961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60971.1Skamil}
60981.1Skamil#endif
60991.1Skamil
61001.1Skamil#if defined(TWAIT_HAVE_PID)
61011.1SkamilATF_TC(signal7);
61021.1SkamilATF_TC_HEAD(signal7, tc)
61031.1Skamil{
61041.1Skamil	atf_tc_set_md_var(tc, "descr",
61051.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61061.1Skamil	    "catching PTRACE_VFORK breakpoint");
61071.1Skamil}
61081.1Skamil
61091.1SkamilATF_TC_BODY(signal7, tc)
61101.1Skamil{
61111.1Skamil	const int exitval = 5;
61121.1Skamil	const int exitval2 = 15;
61131.1Skamil	const int sigval = SIGSTOP;
61141.1Skamil	const int sigmasked = SIGTRAP;
61151.1Skamil	pid_t child, child2, wpid;
61161.1Skamil#if defined(TWAIT_HAVE_STATUS)
61171.1Skamil	int status;
61181.1Skamil#endif
61191.1Skamil	sigset_t intmask;
61201.1Skamil	ptrace_state_t state;
61211.1Skamil	const int slen = sizeof(state);
61221.1Skamil	ptrace_event_t event;
61231.1Skamil	const int elen = sizeof(event);
61241.1Skamil
61251.38Skamil	atf_tc_expect_fail("PR kern/51918");
61261.14Schristos
61271.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61281.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61291.1Skamil	if (child == 0) {
61301.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61311.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61321.1Skamil
61331.1Skamil		sigemptyset(&intmask);
61341.1Skamil		sigaddset(&intmask, sigmasked);
61351.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61361.1Skamil
61371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61391.1Skamil
61401.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
61411.1Skamil
61421.1Skamil		if (child2 == 0)
61431.1Skamil			_exit(exitval2);
61441.1Skamil
61451.1Skamil		FORKEE_REQUIRE_SUCCESS
61461.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
61471.1Skamil
61481.1Skamil		forkee_status_exited(status, exitval2);
61491.1Skamil
61501.13Schristos		DPRINTF("Before exiting of the child process\n");
61511.1Skamil		_exit(exitval);
61521.1Skamil	}
61531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61541.1Skamil
61551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61571.1Skamil
61581.1Skamil	validate_status_stopped(status, sigval);
61591.1Skamil
61601.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
61611.1Skamil	event.pe_set_event = PTRACE_VFORK;
61621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
61631.1Skamil
61641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61651.1Skamil	    "without signal to be sent\n");
61661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61671.1Skamil
61681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61701.1Skamil
61711.1Skamil	validate_status_stopped(status, sigmasked);
61721.1Skamil
61731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61741.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61751.1Skamil
61761.1Skamil	child2 = state.pe_other_pid;
61771.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
61781.1Skamil
61791.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
61801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
61811.1Skamil	    child2);
61821.1Skamil
61831.1Skamil	validate_status_stopped(status, SIGTRAP);
61841.1Skamil
61851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
61861.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61871.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
61881.1Skamil
61891.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
61901.1Skamil	    "without signal to be sent\n");
61911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
61921.1Skamil
61931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61941.1Skamil	    "without signal to be sent\n");
61951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61961.1Skamil
61971.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
61981.1Skamil	    TWAIT_FNAME);
61991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62001.1Skamil	    child2);
62011.1Skamil
62021.1Skamil	validate_status_exited(status, exitval2);
62031.1Skamil
62041.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
62051.1Skamil	    TWAIT_FNAME);
62061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
62071.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
62081.1Skamil
62091.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62101.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
62111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62121.1Skamil
62131.1Skamil	validate_status_stopped(status, SIGCHLD);
62141.1Skamil
62151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62161.1Skamil	    "without signal to be sent\n");
62171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62181.1Skamil
62191.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62201.1Skamil	    TWAIT_FNAME);
62211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62221.1Skamil
62231.1Skamil	validate_status_exited(status, exitval);
62241.1Skamil
62251.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62261.1Skamil	    TWAIT_FNAME);
62271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62281.1Skamil}
62291.1Skamil#endif
62301.1Skamil
62311.1SkamilATF_TC(signal8);
62321.1SkamilATF_TC_HEAD(signal8, tc)
62331.1Skamil{
62341.1Skamil	atf_tc_set_md_var(tc, "descr",
62351.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62361.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
62371.1Skamil}
62381.1Skamil
62391.1SkamilATF_TC_BODY(signal8, tc)
62401.1Skamil{
62411.1Skamil	const int exitval = 5;
62421.1Skamil	const int exitval2 = 15;
62431.1Skamil	const int sigval = SIGSTOP;
62441.1Skamil	const int sigmasked = SIGTRAP;
62451.1Skamil	pid_t child, child2, wpid;
62461.1Skamil#if defined(TWAIT_HAVE_STATUS)
62471.1Skamil	int status;
62481.1Skamil#endif
62491.1Skamil	sigset_t intmask;
62501.1Skamil	ptrace_state_t state;
62511.1Skamil	const int slen = sizeof(state);
62521.1Skamil	ptrace_event_t event;
62531.1Skamil	const int elen = sizeof(event);
62541.1Skamil
62551.14Schristos	atf_tc_expect_fail("PR kern/51918");
62561.14Schristos
62571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62591.1Skamil	if (child == 0) {
62601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62621.1Skamil
62631.1Skamil		sigemptyset(&intmask);
62641.1Skamil		sigaddset(&intmask, sigmasked);
62651.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62661.1Skamil
62671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62691.1Skamil
62701.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
62711.1Skamil
62721.1Skamil		if (child2 == 0)
62731.1Skamil			_exit(exitval2);
62741.1Skamil
62751.1Skamil		FORKEE_REQUIRE_SUCCESS
62761.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
62771.1Skamil
62781.1Skamil		forkee_status_exited(status, exitval2);
62791.1Skamil
62801.13Schristos		DPRINTF("Before exiting of the child process\n");
62811.1Skamil		_exit(exitval);
62821.1Skamil	}
62831.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62841.1Skamil
62851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62871.1Skamil
62881.1Skamil	validate_status_stopped(status, sigval);
62891.1Skamil
62901.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
62911.1Skamil	    child);
62921.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
62931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
62941.1Skamil
62951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62961.1Skamil	    "without signal to be sent\n");
62971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62981.1Skamil
62991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63011.1Skamil
63021.1Skamil	validate_status_stopped(status, sigmasked);
63031.1Skamil
63041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63051.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
63061.1Skamil
63071.1Skamil	child2 = state.pe_other_pid;
63081.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
63091.1Skamil
63101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63111.1Skamil	    "without signal to be sent\n");
63121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63131.1Skamil
63141.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63151.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
63161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63171.1Skamil
63181.1Skamil	validate_status_stopped(status, SIGCHLD);
63191.1Skamil
63201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63211.1Skamil	    "without signal to be sent\n");
63221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63231.1Skamil
63241.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63251.1Skamil	    TWAIT_FNAME);
63261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63271.1Skamil
63281.1Skamil	validate_status_exited(status, exitval);
63291.1Skamil
63301.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63311.1Skamil	    TWAIT_FNAME);
63321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63331.1Skamil}
63341.1Skamil
63351.1SkamilATF_TC(signal9);
63361.1SkamilATF_TC_HEAD(signal9, tc)
63371.1Skamil{
63381.1Skamil	atf_tc_set_md_var(tc, "descr",
63391.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
63401.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
63411.1Skamil}
63421.1Skamil
63431.1SkamilATF_TC_BODY(signal9, tc)
63441.1Skamil{
63451.1Skamil	const int exitval = 5;
63461.1Skamil	const int sigval = SIGSTOP;
63471.1Skamil	const int sigmasked = SIGTRAP;
63481.1Skamil	pid_t child, wpid;
63491.1Skamil#if defined(TWAIT_HAVE_STATUS)
63501.1Skamil	int status;
63511.1Skamil#endif
63521.1Skamil	sigset_t intmask;
63531.1Skamil	ptrace_state_t state;
63541.1Skamil	const int slen = sizeof(state);
63551.1Skamil	ptrace_event_t event;
63561.1Skamil	const int elen = sizeof(event);
63571.1Skamil	ucontext_t uc;
63581.1Skamil	lwpid_t lid;
63591.1Skamil	static const size_t ssize = 16*1024;
63601.1Skamil	void *stack;
63611.1Skamil
63621.14Schristos	atf_tc_expect_fail("PR kern/51918");
63631.14Schristos
63641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63661.1Skamil	if (child == 0) {
63671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63691.1Skamil
63701.1Skamil		sigemptyset(&intmask);
63711.1Skamil		sigaddset(&intmask, sigmasked);
63721.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
63731.1Skamil
63741.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63751.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63761.1Skamil
63771.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63781.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
63791.1Skamil
63801.13Schristos		DPRINTF("Before making context for new lwp in child\n");
63811.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
63821.1Skamil
63831.13Schristos		DPRINTF("Before creating new in child\n");
63841.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
63851.1Skamil
63861.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
63871.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
63881.1Skamil
63891.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
63901.1Skamil		    "are the same\n", lid, the_lwp_id);
63911.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
63921.1Skamil
63931.13Schristos		DPRINTF("Before exiting of the child process\n");
63941.1Skamil		_exit(exitval);
63951.1Skamil	}
63961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63971.1Skamil
63981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64001.1Skamil
64011.1Skamil	validate_status_stopped(status, sigval);
64021.1Skamil
64031.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
64041.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
64051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
64061.1Skamil
64071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64081.1Skamil	    "without signal to be sent\n");
64091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64101.1Skamil
64111.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64121.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64141.1Skamil
64151.1Skamil	validate_status_stopped(status, sigmasked);
64161.1Skamil
64171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
64181.1Skamil
64191.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
64201.1Skamil
64211.1Skamil	lid = state.pe_lwp;
64221.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
64231.1Skamil
64241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64251.1Skamil	    "without signal to be sent\n");
64261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64271.1Skamil
64281.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64291.1Skamil	    TWAIT_FNAME);
64301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64311.1Skamil
64321.1Skamil	validate_status_exited(status, exitval);
64331.1Skamil
64341.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64351.1Skamil	    TWAIT_FNAME);
64361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64371.1Skamil}
64381.1Skamil
64391.1SkamilATF_TC(signal10);
64401.1SkamilATF_TC_HEAD(signal10, tc)
64411.1Skamil{
64421.1Skamil	atf_tc_set_md_var(tc, "descr",
64431.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
64441.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
64451.1Skamil}
64461.1Skamil
64471.1SkamilATF_TC_BODY(signal10, tc)
64481.1Skamil{
64491.1Skamil	const int exitval = 5;
64501.1Skamil	const int sigval = SIGSTOP;
64511.1Skamil	const int sigmasked = SIGTRAP;
64521.1Skamil	pid_t child, wpid;
64531.1Skamil#if defined(TWAIT_HAVE_STATUS)
64541.1Skamil	int status;
64551.1Skamil#endif
64561.1Skamil	sigset_t intmask;
64571.1Skamil	ptrace_state_t state;
64581.1Skamil	const int slen = sizeof(state);
64591.1Skamil	ptrace_event_t event;
64601.1Skamil	const int elen = sizeof(event);
64611.1Skamil	ucontext_t uc;
64621.1Skamil	lwpid_t lid;
64631.1Skamil	static const size_t ssize = 16*1024;
64641.1Skamil	void *stack;
64651.1Skamil
64661.14Schristos	atf_tc_expect_fail("PR kern/51918");
64671.14Schristos
64681.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64691.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64701.1Skamil	if (child == 0) {
64711.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64721.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64731.1Skamil
64741.1Skamil		sigemptyset(&intmask);
64751.1Skamil		sigaddset(&intmask, sigmasked);
64761.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
64771.1Skamil
64781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64801.1Skamil
64811.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64821.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64831.1Skamil
64841.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64851.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
64861.1Skamil
64871.13Schristos		DPRINTF("Before creating new in child\n");
64881.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64891.1Skamil
64901.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64911.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64921.1Skamil
64931.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64941.1Skamil		    "are the same\n", lid, the_lwp_id);
64951.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64961.1Skamil
64971.13Schristos		DPRINTF("Before exiting of the child process\n");
64981.1Skamil		_exit(exitval);
64991.1Skamil	}
65001.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65011.1Skamil
65021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65041.1Skamil
65051.1Skamil	validate_status_stopped(status, sigval);
65061.1Skamil
65071.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
65081.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
65091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
65101.1Skamil
65111.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65121.1Skamil	    "without signal to be sent\n");
65131.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65141.1Skamil
65151.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65161.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65181.1Skamil
65191.1Skamil	validate_status_stopped(status, sigmasked);
65201.1Skamil
65211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
65221.1Skamil
65231.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
65241.1Skamil
65251.1Skamil	lid = state.pe_lwp;
65261.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
65271.1Skamil
65281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65291.1Skamil	    "without signal to be sent\n");
65301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65311.1Skamil
65321.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65331.1Skamil	    TWAIT_FNAME);
65341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65351.1Skamil
65361.1Skamil	validate_status_exited(status, exitval);
65371.1Skamil
65381.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65391.1Skamil	    TWAIT_FNAME);
65401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65411.1Skamil}
65421.1Skamil
65431.1Skamilstatic void
65441.1Skamillwp_main_stop(void *arg)
65451.1Skamil{
65461.1Skamil	the_lwp_id = _lwp_self();
65471.1Skamil
65481.1Skamil	raise(SIGTRAP);
65491.1Skamil
65501.1Skamil	_lwp_exit();
65511.1Skamil}
65521.1Skamil
65531.1SkamilATF_TC(suspend1);
65541.1SkamilATF_TC_HEAD(suspend1, tc)
65551.1Skamil{
65561.1Skamil	atf_tc_set_md_var(tc, "descr",
65571.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
65581.1Skamil	    "resumed by a tracee");
65591.1Skamil}
65601.1Skamil
65611.1SkamilATF_TC_BODY(suspend1, tc)
65621.1Skamil{
65631.1Skamil	const int exitval = 5;
65641.1Skamil	const int sigval = SIGSTOP;
65651.1Skamil	pid_t child, wpid;
65661.1Skamil#if defined(TWAIT_HAVE_STATUS)
65671.1Skamil	int status;
65681.1Skamil#endif
65691.1Skamil	ucontext_t uc;
65701.1Skamil	lwpid_t lid;
65711.1Skamil	static const size_t ssize = 16*1024;
65721.1Skamil	void *stack;
65731.1Skamil	struct ptrace_lwpinfo pl;
65741.1Skamil	struct ptrace_siginfo psi;
65751.1Skamil	volatile int go = 0;
65761.1Skamil
65771.17Skamil	// Feature pending for refactoring
65781.17Skamil	atf_tc_expect_fail("PR kern/51995");
65791.17Skamil
65801.16Skamil	// Hangs with qemu
65811.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
65821.16Skamil
65831.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65841.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65851.1Skamil	if (child == 0) {
65861.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65871.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65881.1Skamil
65891.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65901.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65911.1Skamil
65921.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
65931.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
65941.1Skamil
65951.13Schristos		DPRINTF("Before making context for new lwp in child\n");
65961.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
65971.1Skamil
65981.13Schristos		DPRINTF("Before creating new in child\n");
65991.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
66001.1Skamil
66011.1Skamil		while (go == 0)
66021.1Skamil			continue;
66031.1Skamil
66041.1Skamil		raise(SIGINT);
66051.1Skamil
66061.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
66071.1Skamil
66081.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
66091.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
66101.1Skamil
66111.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
66121.1Skamil		    "are the same\n", lid, the_lwp_id);
66131.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
66141.1Skamil
66151.13Schristos		DPRINTF("Before exiting of the child process\n");
66161.1Skamil		_exit(exitval);
66171.1Skamil	}
66181.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66191.1Skamil
66201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66221.1Skamil
66231.1Skamil	validate_status_stopped(status, sigval);
66241.1Skamil
66251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66261.1Skamil	    "without signal to be sent\n");
66271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66281.1Skamil
66291.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66301.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
66311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66321.1Skamil
66331.1Skamil	validate_status_stopped(status, SIGTRAP);
66341.1Skamil
66351.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
66361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
66371.1Skamil
66381.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
66391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
66401.1Skamil
66411.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
66421.1Skamil	    child, getpid());
66431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
66441.1Skamil
66451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66461.1Skamil	    "without signal to be sent\n");
66471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66481.1Skamil
66491.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66501.1Skamil	    "SIGINT\n", TWAIT_FNAME);
66511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66521.1Skamil
66531.1Skamil	validate_status_stopped(status, SIGINT);
66541.1Skamil
66551.1Skamil	pl.pl_lwpid = 0;
66561.1Skamil
66571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66581.1Skamil	while (pl.pl_lwpid != 0) {
66591.1Skamil
66601.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66611.1Skamil		switch (pl.pl_lwpid) {
66621.1Skamil		case 1:
66631.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
66641.1Skamil			break;
66651.1Skamil		case 2:
66661.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
66671.1Skamil			break;
66681.1Skamil		}
66691.1Skamil	}
66701.1Skamil
66711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66721.1Skamil	    "without signal to be sent\n");
66731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66741.1Skamil
66751.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
66761.1Skamil	    TWAIT_FNAME);
66771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66781.1Skamil
66791.1Skamil	validate_status_exited(status, exitval);
66801.1Skamil
66811.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
66821.1Skamil	    TWAIT_FNAME);
66831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66841.1Skamil}
66851.1Skamil
66861.1SkamilATF_TC(suspend2);
66871.1SkamilATF_TC_HEAD(suspend2, tc)
66881.1Skamil{
66891.1Skamil	atf_tc_set_md_var(tc, "descr",
66901.1Skamil	    "Verify that the while the only thread within a process is "
66911.1Skamil	    "suspended, the whole process cannot be unstopped");
66921.1Skamil}
66931.1Skamil
66941.1SkamilATF_TC_BODY(suspend2, tc)
66951.1Skamil{
66961.1Skamil	const int exitval = 5;
66971.1Skamil	const int sigval = SIGSTOP;
66981.1Skamil	pid_t child, wpid;
66991.1Skamil#if defined(TWAIT_HAVE_STATUS)
67001.1Skamil	int status;
67011.1Skamil#endif
67021.1Skamil	struct ptrace_siginfo psi;
67031.1Skamil
67041.17Skamil	// Feature pending for refactoring
67051.17Skamil	atf_tc_expect_fail("PR kern/51995");
67061.17Skamil
67071.16Skamil	// Hangs with qemu
67081.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
67091.16Skamil
67101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67121.1Skamil	if (child == 0) {
67131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67151.1Skamil
67161.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67171.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67181.1Skamil
67191.13Schristos		DPRINTF("Before exiting of the child process\n");
67201.1Skamil		_exit(exitval);
67211.1Skamil	}
67221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67231.1Skamil
67241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67261.1Skamil
67271.1Skamil	validate_status_stopped(status, sigval);
67281.1Skamil
67291.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
67301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
67311.1Skamil
67321.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
67331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
67341.1Skamil
67351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67361.1Skamil	    "without signal to be sent\n");
67371.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
67381.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
67391.1Skamil
67401.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
67411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
67421.1Skamil
67431.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67441.1Skamil	    "without signal to be sent\n");
67451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67461.1Skamil
67471.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
67481.1Skamil	    TWAIT_FNAME);
67491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67501.1Skamil
67511.1Skamil	validate_status_exited(status, exitval);
67521.1Skamil
67531.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
67541.1Skamil	    TWAIT_FNAME);
67551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67561.1Skamil}
67571.1Skamil
67581.1SkamilATF_TC(resume1);
67591.1SkamilATF_TC_HEAD(resume1, tc)
67601.1Skamil{
67611.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
67621.1Skamil	atf_tc_set_md_var(tc, "descr",
67631.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
67641.1Skamil	    "resumed by the debugger");
67651.1Skamil}
67661.1Skamil
67671.1SkamilATF_TC_BODY(resume1, tc)
67681.1Skamil{
67691.1Skamil	struct msg_fds fds;
67701.1Skamil	const int exitval = 5;
67711.1Skamil	const int sigval = SIGSTOP;
67721.1Skamil	pid_t child, wpid;
67731.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
67741.1Skamil#if defined(TWAIT_HAVE_STATUS)
67751.1Skamil	int status;
67761.1Skamil#endif
67771.1Skamil	ucontext_t uc;
67781.1Skamil	lwpid_t lid;
67791.1Skamil	static const size_t ssize = 16*1024;
67801.1Skamil	void *stack;
67811.1Skamil	struct ptrace_lwpinfo pl;
67821.1Skamil	struct ptrace_siginfo psi;
67831.1Skamil
67841.17Skamil	// Feature pending for refactoring
67851.17Skamil	atf_tc_expect_fail("PR kern/51995");
67861.17Skamil
67871.15Schristos	// Hangs with qemu
67881.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
67891.1Skamil
67901.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
67911.1Skamil
67921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67941.1Skamil	if (child == 0) {
67951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67971.1Skamil
67981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68001.1Skamil
68011.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
68021.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
68031.1Skamil
68041.13Schristos		DPRINTF("Before making context for new lwp in child\n");
68051.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
68061.1Skamil
68071.13Schristos		DPRINTF("Before creating new in child\n");
68081.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
68091.1Skamil
68101.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
68111.1Skamil
68121.1Skamil		raise(SIGINT);
68131.1Skamil
68141.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
68151.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
68161.1Skamil
68171.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
68181.1Skamil		    "are the same\n", lid, the_lwp_id);
68191.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
68201.1Skamil
68211.13Schristos		DPRINTF("Before exiting of the child process\n");
68221.1Skamil		_exit(exitval);
68231.1Skamil	}
68241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68251.1Skamil
68261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68281.1Skamil
68291.1Skamil	validate_status_stopped(status, sigval);
68301.1Skamil
68311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68321.1Skamil	    "without signal to be sent\n");
68331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68341.1Skamil
68351.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68361.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
68371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68381.1Skamil
68391.1Skamil	validate_status_stopped(status, SIGTRAP);
68401.1Skamil
68411.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
68421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
68431.1Skamil
68441.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
68451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
68461.1Skamil
68471.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
68481.1Skamil
68491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68501.1Skamil	    "without signal to be sent\n");
68511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68521.1Skamil
68531.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68541.1Skamil	    "SIGINT\n", TWAIT_FNAME);
68551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68561.1Skamil
68571.1Skamil	validate_status_stopped(status, SIGINT);
68581.1Skamil
68591.1Skamil	pl.pl_lwpid = 0;
68601.1Skamil
68611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68621.1Skamil	while (pl.pl_lwpid != 0) {
68631.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68641.1Skamil		switch (pl.pl_lwpid) {
68651.1Skamil		case 1:
68661.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
68671.1Skamil			break;
68681.1Skamil		case 2:
68691.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
68701.1Skamil			break;
68711.1Skamil		}
68721.1Skamil	}
68731.1Skamil
68741.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
68751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
68761.1Skamil
68771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68781.1Skamil	    "without signal to be sent\n");
68791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68801.1Skamil
68811.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
68821.1Skamil	    TWAIT_FNAME);
68831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68841.1Skamil
68851.1Skamil	validate_status_exited(status, exitval);
68861.1Skamil
68871.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
68881.1Skamil	    TWAIT_FNAME);
68891.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
68901.1Skamil
68911.1Skamil	msg_close(&fds);
68921.1Skamil
68931.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
68941.1Skamil	sleep(10);
68951.1Skamil}
68961.1Skamil
68971.1SkamilATF_TC(syscall1);
68981.1SkamilATF_TC_HEAD(syscall1, tc)
68991.1Skamil{
69001.1Skamil	atf_tc_set_md_var(tc, "descr",
69011.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
69021.1Skamil}
69031.1Skamil
69041.1SkamilATF_TC_BODY(syscall1, tc)
69051.1Skamil{
69061.1Skamil	const int exitval = 5;
69071.1Skamil	const int sigval = SIGSTOP;
69081.1Skamil	pid_t child, wpid;
69091.1Skamil#if defined(TWAIT_HAVE_STATUS)
69101.1Skamil	int status;
69111.1Skamil#endif
69121.1Skamil	struct ptrace_siginfo info;
69131.1Skamil	memset(&info, 0, sizeof(info));
69141.1Skamil
69151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69171.1Skamil	if (child == 0) {
69181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69201.1Skamil
69211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
69231.1Skamil
69241.1Skamil		syscall(SYS_getpid);
69251.1Skamil
69261.13Schristos		DPRINTF("Before exiting of the child process\n");
69271.1Skamil		_exit(exitval);
69281.1Skamil	}
69291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
69301.1Skamil
69311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69331.1Skamil
69341.1Skamil	validate_status_stopped(status, sigval);
69351.1Skamil
69361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69371.1Skamil	    "without signal to be sent\n");
69381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69391.1Skamil
69401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69421.1Skamil
69431.1Skamil	validate_status_stopped(status, SIGTRAP);
69441.1Skamil
69451.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69471.1Skamil
69481.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
69491.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
69501.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69511.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
69521.1Skamil
69531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69541.1Skamil	    "without signal to be sent\n");
69551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69561.1Skamil
69571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69591.1Skamil
69601.1Skamil	validate_status_stopped(status, SIGTRAP);
69611.1Skamil
69621.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69641.1Skamil
69651.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
69661.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
69671.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69681.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
69691.1Skamil
69701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69711.1Skamil	    "without signal to be sent\n");
69721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69731.1Skamil
69741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69761.1Skamil
69771.1Skamil	validate_status_exited(status, exitval);
69781.1Skamil
69791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69811.1Skamil}
69821.1Skamil
69831.1SkamilATF_TC(syscallemu1);
69841.1SkamilATF_TC_HEAD(syscallemu1, tc)
69851.1Skamil{
69861.1Skamil	atf_tc_set_md_var(tc, "descr",
69871.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
69881.1Skamil}
69891.1Skamil
69901.1SkamilATF_TC_BODY(syscallemu1, tc)
69911.1Skamil{
69921.1Skamil	const int exitval = 5;
69931.1Skamil	const int sigval = SIGSTOP;
69941.1Skamil	pid_t child, wpid;
69951.1Skamil#if defined(TWAIT_HAVE_STATUS)
69961.1Skamil	int status;
69971.1Skamil#endif
69981.1Skamil
69991.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
70001.6Skamil	/* syscallemu does not work on sparc (32-bit) */
70011.6Skamil	atf_tc_expect_fail("PR kern/52166");
70021.6Skamil#endif
70031.6Skamil
70041.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
70051.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
70061.1Skamil	if (child == 0) {
70071.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
70081.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
70091.1Skamil
70101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70121.1Skamil
70131.1Skamil		syscall(SYS_exit, 100);
70141.1Skamil
70151.13Schristos		DPRINTF("Before exiting of the child process\n");
70161.1Skamil		_exit(exitval);
70171.1Skamil	}
70181.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70191.1Skamil
70201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70221.1Skamil
70231.1Skamil	validate_status_stopped(status, sigval);
70241.1Skamil
70251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70261.1Skamil	    "without signal to be sent\n");
70271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70281.1Skamil
70291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70311.1Skamil
70321.1Skamil	validate_status_stopped(status, SIGTRAP);
70331.1Skamil
70341.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
70351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
70361.1Skamil
70371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70381.1Skamil	    "without signal to be sent\n");
70391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70401.1Skamil
70411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70431.1Skamil
70441.1Skamil	validate_status_stopped(status, SIGTRAP);
70451.1Skamil
70461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70471.1Skamil	    "without signal to be sent\n");
70481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70491.1Skamil
70501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70521.1Skamil
70531.1Skamil	validate_status_exited(status, exitval);
70541.1Skamil
70551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70561.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70571.1Skamil}
70581.1Skamil
70591.26Skamil#if defined(TWAIT_HAVE_PID)
70601.26SkamilATF_TC(race1);
70611.26SkamilATF_TC_HEAD(race1, tc)
70621.26Skamil{
70631.26Skamil	atf_tc_set_md_var(tc, "descr",
70641.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
70651.26Skamil	    "process and no other error is reported");
70661.26Skamil}
70671.26Skamil
70681.26SkamilATF_TC_BODY(race1, tc)
70691.26Skamil{
70701.26Skamil	time_t start, end;
70711.26Skamil	double diff;
70721.26Skamil	unsigned long N = 0;
70731.26Skamil
70741.26Skamil	/* Reuse this test with attach1 */
70751.26Skamil
70761.26Skamil	start = time(NULL);
70771.26Skamil	while (true) {
70781.26Skamil		DPRINTF("Step: %lu\n", N);
70791.26Skamil		attach1_raw(true);
70801.26Skamil		end = time(NULL);
70811.26Skamil		diff = difftime(end, start);
70821.26Skamil		if (diff >= 5.0)
70831.26Skamil			break;
70841.26Skamil		++N;
70851.26Skamil	}
70861.26Skamil	DPRINTF("Iterations: %lu\n", N);
70871.26Skamil}
70881.26Skamil#endif
70891.26Skamil
70901.1Skamil#include "t_ptrace_amd64_wait.h"
70911.1Skamil#include "t_ptrace_i386_wait.h"
70921.1Skamil#include "t_ptrace_x86_wait.h"
70931.1Skamil
70941.1SkamilATF_TP_ADD_TCS(tp)
70951.1Skamil{
70961.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
70971.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
70981.33Skamil
70991.36Skamil	ATF_TP_ADD_TC(tp, traceme_raise1);
71001.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
71011.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
71021.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
71031.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
71041.33Skamil
71051.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
71061.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
71071.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
71081.34Skamil
71091.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler1);
71101.35Skamil//	ATF_TP_ADD_TC(tp, traceme_signal_nohandler2); // not yet
71111.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler3);
71121.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler4);
71131.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);
71141.1Skamil
71151.37Skamil	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
71161.37Skamil
71171.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
71181.46Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
71191.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
71201.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
71211.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
71221.40Skamil
71231.41Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_breakpoint);
71241.41Skamil
71251.43Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
71261.43Skamil
71271.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
71281.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
71291.1Skamil	ATF_TP_ADD_TC(tp, attach3);
71301.1Skamil	ATF_TP_ADD_TC(tp, attach4);
71311.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
71321.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
71331.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
71341.1Skamil
71351.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
71361.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
71371.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
71381.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
71391.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
71401.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
71411.1Skamil
71421.31Skamil	ATF_TP_ADD_TC(tp, fork1);
71431.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
71441.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
71451.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
71461.31Skamil	ATF_TP_ADD_TC(tp, fork5);
71471.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
71481.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
71491.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
71501.31Skamil
71511.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
71521.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
71531.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
71541.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
71551.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
71561.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
71571.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
71581.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
71591.1Skamil
71601.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
71611.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
71621.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
71631.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
71641.1Skamil
71651.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
71661.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
71671.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
71681.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
71691.1Skamil
71701.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
71711.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
71721.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
71731.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
71741.1Skamil
71751.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
71761.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
71771.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
71781.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
71791.1Skamil
71801.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
71811.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
71821.1Skamil
71831.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
71841.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
71851.1Skamil
71861.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
71871.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
71881.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
71891.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
71901.1Skamil
71911.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
71921.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
71931.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
71941.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
71951.1Skamil
71961.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
71971.1Skamil
71981.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
71991.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
72001.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
72011.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
72021.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
72031.1Skamil
72041.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
72051.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
72061.1Skamil
72071.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
72081.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
72091.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
72101.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
72111.1Skamil
72121.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
72131.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
72141.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
72151.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
72161.2Skamil
72171.1Skamil	ATF_TP_ADD_TC(tp, kill1);
72181.1Skamil	ATF_TP_ADD_TC(tp, kill2);
72191.1Skamil
72201.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
72211.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
72221.1Skamil
72231.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
72241.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
72251.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
72261.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
72271.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
72281.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
72291.1Skamil
72301.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
72311.1Skamil
72321.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
72331.1Skamil
72341.1Skamil	ATF_TP_ADD_TC(tp, signal1);
72351.1Skamil	ATF_TP_ADD_TC(tp, signal2);
72361.1Skamil	ATF_TP_ADD_TC(tp, signal3);
72371.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
72381.1Skamil	ATF_TP_ADD_TC(tp, signal5);
72391.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
72401.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
72411.1Skamil	ATF_TP_ADD_TC(tp, signal8);
72421.1Skamil	ATF_TP_ADD_TC(tp, signal9);
72431.1Skamil	ATF_TP_ADD_TC(tp, signal10);
72441.1Skamil
72451.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
72461.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
72471.1Skamil
72481.1Skamil	ATF_TP_ADD_TC(tp, resume1);
72491.1Skamil
72501.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
72511.1Skamil
72521.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
72531.1Skamil
72541.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
72551.26Skamil
72561.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
72571.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
72581.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
72591.1Skamil
72601.1Skamil	return atf_no_error();
72611.1Skamil}
7262