t_ptrace_wait.c revision 1.51
11.51Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.51 2018/05/23 01:29:43 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.51Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.51 2018/05/23 01:29:43 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.50Skamiltraceme_sendsignal_handle(int sigsent, void (*sah)(int a), 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.50Skamil#define TRACEME_SENDSIGNAL_HANDLE(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.50Skamil	traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught);	\
2681.34Skamil}
2691.34Skamil
2701.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered.
2711.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */
2721.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP)  /* hangup */
2731.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */
2741.34Skamil
2751.34Skamil/// ----------------------------------------------------------------------------
2761.34Skamil
2771.35Skamilstatic void
2781.50Skamiltraceme_sendsignal_masked(int sigsent)
2791.50Skamil{
2801.50Skamil	const int exitval = 5;
2811.50Skamil	const int sigval = SIGSTOP;
2821.50Skamil	pid_t child, wpid;
2831.50Skamil	sigset_t set;
2841.50Skamil#if defined(TWAIT_HAVE_STATUS)
2851.50Skamil	int status;
2861.50Skamil#endif
2871.50Skamil
2881.50Skamil	struct ptrace_siginfo info;
2891.50Skamil	memset(&info, 0, sizeof(info));
2901.50Skamil
2911.50Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
2921.50Skamil	SYSCALL_REQUIRE((child = fork()) != -1);
2931.50Skamil	if (child == 0) {
2941.50Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2951.50Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2961.50Skamil
2971.50Skamil		sigemptyset(&set);
2981.50Skamil		sigaddset(&set, sigsent);
2991.50Skamil		FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
3001.50Skamil
3011.50Skamil		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3021.50Skamil		FORKEE_ASSERT(raise(sigval) == 0);
3031.50Skamil
3041.50Skamil		_exit(exitval);
3051.50Skamil	}
3061.50Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3071.50Skamil
3081.50Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3091.50Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3101.50Skamil
3111.50Skamil	validate_status_stopped(status, sigval);
3121.50Skamil
3131.50Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3141.50Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
3151.50Skamil	                != -1);
3161.50Skamil
3171.50Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3181.50Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3191.50Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3201.50Skamil	    info.psi_siginfo.si_errno);
3211.50Skamil
3221.50Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3231.50Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3241.50Skamil
3251.50Skamil	DPRINTF("Before resuming the child process where it left off and with "
3261.50Skamil	    "signal %s to be sent\n", strsignal(sigsent));
3271.50Skamil	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
3281.50Skamil
3291.50Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3301.50Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3311.50Skamil
3321.50Skamil	validate_status_exited(status, exitval);
3331.50Skamil
3341.50Skamil	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
3351.50Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3361.50Skamil}
3371.50Skamil
3381.50Skamil#define TRACEME_SENDSIGNAL_MASKED(test, sig)					\
3391.50SkamilATF_TC(test);									\
3401.50SkamilATF_TC_HEAD(test, tc)								\
3411.50Skamil{										\
3421.50Skamil	atf_tc_set_md_var(tc, "descr",						\
3431.50Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
3441.50Skamil	    "handled correctly and the signal is masked by SIG_BLOCK");		\
3451.50Skamil}										\
3461.50Skamil										\
3471.50SkamilATF_TC_BODY(test, tc)								\
3481.50Skamil{										\
3491.50Skamil										\
3501.50Skamil	traceme_sendsignal_masked(sig);						\
3511.50Skamil}
3521.50Skamil
3531.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be masked.
3541.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */
3551.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP)  /* hangup */
3561.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */
3571.50Skamil
3581.50Skamil/// ----------------------------------------------------------------------------
3591.50Skamil
3601.50Skamilstatic void
3611.50Skamiltraceme_sendsignal_ignored(int sigsent)
3621.50Skamil{
3631.50Skamil	const int exitval = 5;
3641.50Skamil	const int sigval = SIGSTOP;
3651.50Skamil	pid_t child, wpid;
3661.50Skamil	struct sigaction sa;
3671.50Skamil#if defined(TWAIT_HAVE_STATUS)
3681.50Skamil	int status;
3691.50Skamil#endif
3701.50Skamil
3711.50Skamil	struct ptrace_siginfo info;
3721.50Skamil	memset(&info, 0, sizeof(info));
3731.50Skamil
3741.50Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
3751.50Skamil	SYSCALL_REQUIRE((child = fork()) != -1);
3761.50Skamil	if (child == 0) {
3771.50Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3781.50Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3791.50Skamil
3801.50Skamil		memset(&sa, 0, sizeof(sa));
3811.50Skamil		sa.sa_handler = SIG_IGN;
3821.50Skamil		sigemptyset(&sa.sa_mask);
3831.50Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
3841.50Skamil
3851.50Skamil		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3861.50Skamil		FORKEE_ASSERT(raise(sigval) == 0);
3871.50Skamil
3881.50Skamil		_exit(exitval);
3891.50Skamil	}
3901.50Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3911.50Skamil
3921.50Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3931.50Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3941.50Skamil
3951.50Skamil	validate_status_stopped(status, sigval);
3961.50Skamil
3971.50Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3981.50Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
3991.50Skamil	                != -1);
4001.50Skamil
4011.50Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4021.50Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4031.50Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4041.50Skamil	    info.psi_siginfo.si_errno);
4051.50Skamil
4061.50Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4071.50Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4081.50Skamil
4091.50Skamil	DPRINTF("Before resuming the child process where it left off and with "
4101.50Skamil	    "signal %s to be sent\n", strsignal(sigsent));
4111.50Skamil	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
4121.50Skamil
4131.50Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4141.50Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4151.50Skamil
4161.50Skamil	validate_status_exited(status, exitval);
4171.50Skamil
4181.50Skamil	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
4191.50Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4201.50Skamil}
4211.50Skamil
4221.50Skamil#define TRACEME_SENDSIGNAL_IGNORED(test, sig)					\
4231.50SkamilATF_TC(test);									\
4241.50SkamilATF_TC_HEAD(test, tc)								\
4251.50Skamil{										\
4261.50Skamil	atf_tc_set_md_var(tc, "descr",						\
4271.50Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
4281.50Skamil	    "handled correctly and the signal is masked by SIG_IGN");		\
4291.50Skamil}										\
4301.50Skamil										\
4311.50SkamilATF_TC_BODY(test, tc)								\
4321.50Skamil{										\
4331.50Skamil										\
4341.50Skamil	traceme_sendsignal_ignored(sig);					\
4351.50Skamil}
4361.50Skamil
4371.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be ignored.
4381.50SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort trap */
4391.50SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP)  /* hangup */
4401.50SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued? */
4411.50Skamil
4421.50Skamil/// ----------------------------------------------------------------------------
4431.50Skamil
4441.50Skamilstatic void
4451.50Skamiltraceme_sendsignal_simple(int sigsent)
4461.1Skamil{
4471.35Skamil	const int sigval = SIGSTOP;
4481.35Skamil	int exitval = 0;
4491.1Skamil	pid_t child, wpid;
4501.1Skamil#if defined(TWAIT_HAVE_STATUS)
4511.1Skamil	int status;
4521.35Skamil	int expect_core = (sigsent == SIGABRT) ? 1 : 0;
4531.1Skamil#endif
4541.1Skamil
4551.45Skamil	struct ptrace_siginfo info;
4561.45Skamil	memset(&info, 0, sizeof(info));
4571.45Skamil
4581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
4591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
4601.1Skamil	if (child == 0) {
4611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4631.1Skamil
4641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
4661.1Skamil
4671.35Skamil		switch (sigsent) {
4681.35Skamil		case SIGCONT:
4691.48Skamil		case SIGSTOP:
4701.35Skamil			_exit(exitval);
4711.35Skamil		default:
4721.35Skamil			/* NOTREACHED */
4731.35Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
4741.35Skamil		}
4751.1Skamil	}
4761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4771.1Skamil
4781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4801.1Skamil
4811.1Skamil	validate_status_stopped(status, sigval);
4821.1Skamil
4831.45Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4841.45Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
4851.45Skamil	                != -1);
4861.45Skamil
4871.45Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4881.45Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4891.45Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4901.45Skamil	    info.psi_siginfo.si_errno);
4911.45Skamil
4921.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4931.45Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4941.45Skamil
4951.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
4961.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
4971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
4981.1Skamil
4991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5011.1Skamil
5021.35Skamil	switch (sigsent) {
5031.48Skamil	case SIGSTOP:
5041.48Skamil		validate_status_stopped(status, sigsent);
5051.48Skamil		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5061.48Skamil		        "child\n");
5071.48Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
5081.48Skamil		                       sizeof(info)) != -1);
5091.48Skamil
5101.48Skamil		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5111.48Skamil		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5121.48Skamil		        "si_errno=%#x\n",
5131.48Skamil			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5141.48Skamil		        info.psi_siginfo.si_errno);
5151.48Skamil
5161.48Skamil		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5171.48Skamil		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5181.48Skamil
5191.48Skamil		DPRINTF("Before resuming the child process where it left off "
5201.48Skamil		        "and with signal %s to be sent\n", strsignal(sigsent));
5211.48Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5221.48Skamil
5231.48Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5241.48Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
5251.48Skamil		                      child);
5261.48Skamil		/* FALLTHROUGH */
5271.35Skamil	case SIGCONT:
5281.35Skamil		validate_status_exited(status, exitval);
5291.35Skamil		break;
5301.35Skamil	default:
5311.35Skamil		validate_status_signaled(status, sigsent, expect_core);
5321.35Skamil		break;
5331.35Skamil	}
5341.1Skamil
5351.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
5361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5371.1Skamil}
5381.1Skamil
5391.50Skamil#define TRACEME_SENDSIGNAL_SIMPLE(test, sig)					\
5401.35SkamilATF_TC(test);									\
5411.35SkamilATF_TC_HEAD(test, tc)								\
5421.35Skamil{										\
5431.35Skamil	atf_tc_set_md_var(tc, "descr",						\
5441.35Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
5451.35Skamil	    "handled correctly in a child without a signal handler");		\
5461.35Skamil}										\
5471.35Skamil										\
5481.35SkamilATF_TC_BODY(test, tc)								\
5491.35Skamil{										\
5501.35Skamil										\
5511.50Skamil	traceme_sendsignal_simple(sig);						\
5521.35Skamil}
5531.35Skamil
5541.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable */
5551.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable */
5561.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */
5571.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP)  /* hangup */
5581.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */
5591.35Skamil
5601.35Skamil/// ----------------------------------------------------------------------------
5611.35Skamil
5621.37SkamilATF_TC(traceme_pid1_parent);
5631.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc)
5641.37Skamil{
5651.37Skamil	atf_tc_set_md_var(tc, "descr",
5661.37Skamil	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
5671.37Skamil}
5681.37Skamil
5691.37SkamilATF_TC_BODY(traceme_pid1_parent, tc)
5701.37Skamil{
5711.37Skamil	struct msg_fds parent_child;
5721.37Skamil	int exitval_child1 = 1, exitval_child2 = 2;
5731.37Skamil	pid_t child1, child2, wpid;
5741.37Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5751.37Skamil#if defined(TWAIT_HAVE_STATUS)
5761.37Skamil	int status;
5771.37Skamil#endif
5781.37Skamil
5791.37Skamil	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
5801.37Skamil
5811.37Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
5821.37Skamil	SYSCALL_REQUIRE((child1 = fork()) != -1);
5831.37Skamil	if (child1 == 0) {
5841.37Skamil		DPRINTF("Before forking process PID=%d\n", getpid());
5851.37Skamil		SYSCALL_REQUIRE((child2 = fork()) != -1);
5861.37Skamil		if (child2 != 0) {
5871.37Skamil			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
5881.37Skamil			        getpid(), child2);
5891.37Skamil			_exit(exitval_child1);
5901.37Skamil		}
5911.37Skamil		CHILD_FROM_PARENT("exit child1", parent_child, msg);
5921.37Skamil
5931.37Skamil		DPRINTF("Assert that our parent is PID1 (initproc)\n");
5941.37Skamil		FORKEE_ASSERT_EQ(getppid(), 1);
5951.37Skamil
5961.37Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5971.37Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
5981.37Skamil		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
5991.37Skamil
6001.37Skamil		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
6011.37Skamil
6021.37Skamil		_exit(exitval_child2);
6031.37Skamil	}
6041.37Skamil	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
6051.37Skamil
6061.37Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6071.37Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child1, &status, WEXITED),
6081.37Skamil	                      child1);
6091.37Skamil
6101.37Skamil	validate_status_exited(status, exitval_child1);
6111.37Skamil
6121.37Skamil	DPRINTF("Notify that child1 is dead\n");
6131.37Skamil	PARENT_TO_CHILD("exit child1", parent_child, msg);
6141.37Skamil
6151.37Skamil	DPRINTF("Wait for exiting of child2\n");
6161.37Skamil	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
6171.37Skamil}
6181.37Skamil
6191.37Skamil/// ----------------------------------------------------------------------------
6201.37Skamil
6211.40Skamilstatic void
6221.40Skamiltraceme_vfork_raise(int sigval)
6231.40Skamil{
6241.46Skamil	const int exitval = 5, exitval_watcher = 10;
6251.46Skamil	pid_t child, parent, watcher, wpid;
6261.46Skamil	int rv;
6271.40Skamil#if defined(TWAIT_HAVE_STATUS)
6281.40Skamil	int status;
6291.40Skamil	int expect_core = (sigval == SIGABRT) ? 1 : 0;
6301.40Skamil#endif
6311.40Skamil
6321.46Skamil	/*
6331.46Skamil	 * Spawn a dedicated thread to watch for a stopped child and emit
6341.46Skamil	 * the SIGKILL signal to it.
6351.46Skamil	 *
6361.46Skamil	 * vfork(2) might clobber watcher, this means that it's safer and
6371.46Skamil	 * simpler to reparent this process to initproc and forget about it.
6381.46Skamil	 */
6391.46Skamil	if (sigval == SIGSTOP) {
6401.46Skamil		parent = getpid();
6411.46Skamil
6421.46Skamil		watcher = fork();
6431.46Skamil		ATF_REQUIRE(watcher != 1);
6441.46Skamil		if (watcher == 0) {
6451.46Skamil			/* Double fork(2) trick to reparent to initproc */
6461.46Skamil			watcher = fork();
6471.46Skamil			FORKEE_ASSERT_NEQ(watcher, -1);
6481.46Skamil			if (watcher != 0)
6491.46Skamil				_exit(exitval_watcher);
6501.46Skamil
6511.46Skamil			child = await_stopped_child(parent);
6521.46Skamil
6531.46Skamil			errno = 0;
6541.46Skamil			rv = kill(child, SIGKILL);
6551.46Skamil			FORKEE_ASSERT_EQ(rv, 0);
6561.46Skamil			FORKEE_ASSERT_EQ(errno, 0);
6571.46Skamil
6581.46Skamil			/* This exit value will be collected by initproc */
6591.46Skamil			_exit(0);
6601.46Skamil		}
6611.46Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6621.46Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
6631.46Skamil		                      watcher);
6641.46Skamil
6651.46Skamil		validate_status_exited(status, exitval_watcher);
6661.46Skamil
6671.46Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6681.46Skamil		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(watcher,
6691.46Skamil		                                                   &status, 0));
6701.46Skamil	}
6711.46Skamil
6721.40Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
6731.40Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
6741.40Skamil	if (child == 0) {
6751.40Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6761.40Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6771.40Skamil
6781.40Skamil		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6791.40Skamil		FORKEE_ASSERT(raise(sigval) == 0);
6801.40Skamil
6811.40Skamil		switch (sigval) {
6821.46Skamil		case SIGSTOP:
6831.40Skamil		case SIGKILL:
6841.40Skamil		case SIGABRT:
6851.40Skamil		case SIGHUP:
6861.40Skamil			/* NOTREACHED */
6871.40Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
6881.40Skamil		default:
6891.40Skamil			DPRINTF("Before exiting of the child process\n");
6901.40Skamil			_exit(exitval);
6911.40Skamil		}
6921.40Skamil	}
6931.40Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6941.40Skamil
6951.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6961.40Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6971.40Skamil
6981.40Skamil	switch (sigval) {
6991.40Skamil	case SIGKILL:
7001.40Skamil	case SIGABRT:
7011.40Skamil	case SIGHUP:
7021.40Skamil		validate_status_signaled(status, sigval, expect_core);
7031.40Skamil		break;
7041.40Skamil	case SIGSTOP:
7051.46Skamil		validate_status_signaled(status, SIGKILL, 0);
7061.46Skamil		break;
7071.40Skamil	case SIGCONT:
7081.47Skamil	case SIGTSTP:
7091.47Skamil	case SIGTTIN:
7101.47Skamil	case SIGTTOU:
7111.40Skamil		validate_status_exited(status, exitval);
7121.40Skamil		break;
7131.40Skamil	default:
7141.40Skamil		/* NOTREACHED */
7151.40Skamil		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
7161.40Skamil		break;
7171.40Skamil	}
7181.40Skamil
7191.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7201.40Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7211.40Skamil}
7221.40Skamil
7231.40Skamil#define TRACEME_VFORK_RAISE(test, sig)						\
7241.40SkamilATF_TC(test);									\
7251.40SkamilATF_TC_HEAD(test, tc)								\
7261.40Skamil{										\
7271.40Skamil	atf_tc_set_md_var(tc, "descr",						\
7281.42Skamil	    "Verify PT_TRACE_ME followed by raise of " #sig " in a vfork(2)ed "	\
7291.42Skamil	    "child");								\
7301.40Skamil}										\
7311.40Skamil										\
7321.40SkamilATF_TC_BODY(test, tc)								\
7331.40Skamil{										\
7341.40Skamil										\
7351.40Skamil	traceme_vfork_raise(sig);						\
7361.40Skamil}
7371.40Skamil
7381.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
7391.46SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
7401.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
7411.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
7421.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
7431.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
7441.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
7451.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
7461.40Skamil
7471.40Skamil/// ----------------------------------------------------------------------------
7481.40Skamil
7491.41SkamilATF_TC(traceme_vfork_breakpoint);
7501.41SkamilATF_TC_HEAD(traceme_vfork_breakpoint, tc)
7511.41Skamil{
7521.41Skamil	atf_tc_set_md_var(tc, "descr",
7531.44Skamil	    "Verify PT_TRACE_ME followed by a software breakpoint in a "
7541.44Skamil	    "vfork(2)ed child");
7551.41Skamil}
7561.41Skamil
7571.41SkamilATF_TC_BODY(traceme_vfork_breakpoint, tc)
7581.41Skamil{
7591.41Skamil	pid_t child, wpid;
7601.41Skamil#if defined(TWAIT_HAVE_STATUS)
7611.41Skamil	int status;
7621.41Skamil#endif
7631.41Skamil
7641.41Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
7651.41Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
7661.41Skamil	if (child == 0) {
7671.41Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7681.41Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7691.41Skamil
7701.41Skamil		DPRINTF("Before executing a software breakpoint\n");
7711.41Skamil#ifdef PTRACE_BREAKPOINT_ASM
7721.41Skamil		PTRACE_BREAKPOINT_ASM;
7731.41Skamil#else
7741.41Skamil		/* port me */
7751.41Skamil#endif
7761.41Skamil
7771.41Skamil		/* NOTREACHED */
7781.41Skamil		FORKEE_ASSERTX(0 && "This shall not be reached");
7791.41Skamil	}
7801.41Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7811.41Skamil
7821.41Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7831.41Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7841.41Skamil
7851.41Skamil	validate_status_signaled(status, SIGTRAP, 1);
7861.41Skamil
7871.41Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7881.41Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7891.41Skamil}
7901.41Skamil
7911.41Skamil/// ----------------------------------------------------------------------------
7921.41Skamil
7931.43SkamilATF_TC(traceme_vfork_exec);
7941.43SkamilATF_TC_HEAD(traceme_vfork_exec, tc)
7951.43Skamil{
7961.43Skamil	atf_tc_set_md_var(tc, "descr",
7971.43Skamil	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child");
7981.43Skamil}
7991.43Skamil
8001.43SkamilATF_TC_BODY(traceme_vfork_exec, tc)
8011.43Skamil{
8021.43Skamil	const int sigval = SIGTRAP;
8031.43Skamil	pid_t child, wpid;
8041.43Skamil#if defined(TWAIT_HAVE_STATUS)
8051.43Skamil	int status;
8061.43Skamil#endif
8071.43Skamil
8081.43Skamil	struct ptrace_siginfo info;
8091.43Skamil	memset(&info, 0, sizeof(info));
8101.43Skamil
8111.43Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
8121.43Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
8131.43Skamil	if (child == 0) {
8141.43Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
8151.43Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
8161.43Skamil
8171.43Skamil		DPRINTF("Before calling execve(2) from child\n");
8181.43Skamil		execlp("/bin/echo", "/bin/echo", NULL);
8191.43Skamil
8201.43Skamil		/* NOTREACHED */
8211.43Skamil		FORKEE_ASSERTX(0 && "Not reached");
8221.43Skamil	}
8231.43Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
8241.43Skamil
8251.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8261.43Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
8271.43Skamil
8281.43Skamil	validate_status_stopped(status, sigval);
8291.43Skamil
8301.43Skamil	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
8311.43Skamil	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
8321.43Skamil
8331.43Skamil	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
8341.43Skamil	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
8351.43Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
8361.43Skamil	    info.psi_siginfo.si_errno);
8371.43Skamil
8381.43Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
8391.43Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
8401.43Skamil
8411.43Skamil	DPRINTF("Before resuming the child process where it left off and "
8421.43Skamil	    "without signal to be sent\n");
8431.43Skamil	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
8441.43Skamil
8451.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8461.43Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
8471.43Skamil
8481.43Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8491.43Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
8501.43Skamil}
8511.43Skamil
8521.43Skamil/// ----------------------------------------------------------------------------
8531.43Skamil
8541.1Skamil#if defined(TWAIT_HAVE_PID)
8551.51Skamilstatic void
8561.51Skamiltracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated)
8571.1Skamil{
8581.51Skamil	/*
8591.51Skamil	 * notimeout - disable timeout in await zombie function
8601.51Skamil	 * unrelated - attach from unrelated tracer reparented to initproc
8611.51Skamil	 */
8621.1Skamil
8631.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8641.1Skamil	const int exitval_tracee = 5;
8651.1Skamil	const int exitval_tracer = 10;
8661.1Skamil	pid_t tracee, tracer, wpid;
8671.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8681.1Skamil#if defined(TWAIT_HAVE_STATUS)
8691.1Skamil	int status;
8701.1Skamil#endif
8711.1Skamil
8721.13Schristos	DPRINTF("Spawn tracee\n");
8731.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8741.1Skamil	tracee = atf_utils_fork();
8751.1Skamil	if (tracee == 0) {
8761.1Skamil		// Wait for parent to let us exit
8771.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
8781.1Skamil		_exit(exitval_tracee);
8791.1Skamil	}
8801.1Skamil
8811.13Schristos	DPRINTF("Spawn debugger\n");
8821.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8831.1Skamil	tracer = atf_utils_fork();
8841.1Skamil	if (tracer == 0) {
8851.51Skamil		if(unrelated) {
8861.51Skamil			/* Fork again and drop parent to reattach to PID 1 */
8871.51Skamil			tracer = atf_utils_fork();
8881.51Skamil			if (tracer != 0)
8891.51Skamil				_exit(exitval_tracer);
8901.51Skamil		}
8911.51Skamil
8921.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8931.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8941.1Skamil
8951.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8961.1Skamil		FORKEE_REQUIRE_SUCCESS(
8971.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8981.1Skamil
8991.1Skamil		forkee_status_stopped(status, SIGSTOP);
9001.1Skamil
9011.1Skamil		/* Resume tracee with PT_CONTINUE */
9021.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9031.1Skamil
9041.1Skamil		/* Inform parent that tracer has attached to tracee */
9051.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9061.1Skamil
9071.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9081.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9091.1Skamil
9101.1Skamil		/* Wait for tracee and assert that it exited */
9111.1Skamil		FORKEE_REQUIRE_SUCCESS(
9121.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9131.1Skamil
9141.1Skamil		forkee_status_exited(status, exitval_tracee);
9151.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
9161.1Skamil
9171.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9181.51Skamil		_exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer);
9191.51Skamil	}
9201.51Skamil
9211.51Skamil	if (unrelated) {
9221.51Skamil		DPRINTF("Wait for the tracer process (direct child) to exit "
9231.51Skamil		    "calling %s()\n", TWAIT_FNAME);
9241.51Skamil		TWAIT_REQUIRE_SUCCESS(
9251.51Skamil		    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
9261.51Skamil
9271.51Skamil		validate_status_exited(status, exitval_tracer);
9281.51Skamil
9291.51Skamil		DPRINTF("Wait for the non-exited tracee process with %s()\n",
9301.51Skamil		    TWAIT_FNAME);
9311.51Skamil		TWAIT_REQUIRE_SUCCESS(
9321.51Skamil		    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
9331.1Skamil	}
9341.1Skamil
9351.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9361.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9371.1Skamil
9381.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9391.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
9401.1Skamil
9411.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9421.51Skamil	if (notimeout)
9431.26Skamil		await_zombie_raw(tracee, 0);
9441.26Skamil	else
9451.26Skamil		await_zombie(tracee);
9461.1Skamil
9471.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
9481.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
9491.1Skamil	    TWAIT_FNAME);
9501.1Skamil	TWAIT_REQUIRE_SUCCESS(
9511.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9521.1Skamil
9531.51Skamil	if (unrelated) {
9541.51Skamil		DPRINTF("Resume the tracer and let it detect exited tracee\n");
9551.51Skamil		PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9561.51Skamil	} else {
9571.51Skamil		DPRINTF("Tell the tracer child should have exited\n");
9581.51Skamil		PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
9591.51Skamil		DPRINTF("Wait for tracer to finish its job and exit - calling "
9601.51Skamil		        "%s()\n", TWAIT_FNAME);
9611.51Skamil
9621.51Skamil		DPRINTF("Wait from tracer child to complete waiting for "
9631.51Skamil		        "tracee\n");
9641.51Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9651.51Skamil		    tracer);
9661.1Skamil
9671.51Skamil		validate_status_exited(status, exitval_tracer);
9681.51Skamil	}
9691.1Skamil
9701.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9711.1Skamil	    TWAIT_FNAME);
9721.51Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9731.1Skamil
9741.1Skamil	validate_status_exited(status, exitval_tracee);
9751.1Skamil
9761.1Skamil	msg_close(&parent_tracer);
9771.1Skamil	msg_close(&parent_tracee);
9781.1Skamil}
9791.26Skamil
9801.51SkamilATF_TC(tracer_sees_terminaton_before_the_parent);
9811.51SkamilATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc)
9821.51Skamil{
9831.51Skamil	atf_tc_set_md_var(tc, "descr",
9841.51Skamil	    "Assert that tracer sees process termination before the parent");
9851.51Skamil}
9861.51Skamil
9871.51SkamilATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc)
9881.26Skamil{
9891.26Skamil
9901.51Skamil	tracer_sees_terminaton_before_the_parent_raw(false, false);
9911.26Skamil}
9921.26Skamil
9931.51SkamilATF_TC(tracer_sysctl_lookup_without_duplicates);
9941.51SkamilATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc)
9951.1Skamil{
9961.1Skamil	atf_tc_set_md_var(tc, "descr",
9971.51Skamil	    "Assert that await_zombie() in attach1 always finds a single "
9981.51Skamil	    "process and no other error is reported");
9991.1Skamil}
10001.1Skamil
10011.51SkamilATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc)
10021.1Skamil{
10031.51Skamil	time_t start, end;
10041.51Skamil	double diff;
10051.51Skamil	unsigned long N = 0;
10061.1Skamil
10071.51Skamil	/*
10081.51Skamil	 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw().
10091.51Skamil	 * This test body isn't specific to this race, however it's just good
10101.51Skamil	 * enough for this purposes, no need to invent a dedicated code flow.
10111.51Skamil	 */
10121.1Skamil
10131.51Skamil	start = time(NULL);
10141.51Skamil	while (true) {
10151.51Skamil		DPRINTF("Step: %lu\n", N);
10161.51Skamil		tracer_sees_terminaton_before_the_parent_raw(true, false);
10171.51Skamil		end = time(NULL);
10181.51Skamil		diff = difftime(end, start);
10191.51Skamil		if (diff >= 5.0)
10201.51Skamil			break;
10211.51Skamil		++N;
10221.1Skamil	}
10231.51Skamil	DPRINTF("Iterations: %lu\n", N);
10241.51Skamil}
10251.1Skamil
10261.51SkamilATF_TC(unrelated_tracer_sees_terminaton_before_the_parent);
10271.51SkamilATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc)
10281.51Skamil{
10291.51Skamil	atf_tc_set_md_var(tc, "descr",
10301.51Skamil	    "Assert that tracer sees process termination before the parent");
10311.51Skamil}
10321.1Skamil
10331.51SkamilATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc)
10341.51Skamil{
10351.1Skamil
10361.51Skamil	tracer_sees_terminaton_before_the_parent_raw(false, true);
10371.1Skamil}
10381.1Skamil#endif
10391.1Skamil
10401.51Skamil/// ----------------------------------------------------------------------------
10411.51Skamil
10421.51SkamilATF_TC(parent_attach_to_its_child);
10431.51SkamilATF_TC_HEAD(parent_attach_to_its_child, tc)
10441.1Skamil{
10451.1Skamil	atf_tc_set_md_var(tc, "descr",
10461.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
10471.1Skamil}
10481.1Skamil
10491.51SkamilATF_TC_BODY(parent_attach_to_its_child, tc)
10501.1Skamil{
10511.1Skamil	struct msg_fds parent_tracee;
10521.1Skamil	const int exitval_tracee = 5;
10531.1Skamil	pid_t tracee, wpid;
10541.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
10551.1Skamil#if defined(TWAIT_HAVE_STATUS)
10561.1Skamil	int status;
10571.1Skamil#endif
10581.1Skamil
10591.13Schristos	DPRINTF("Spawn tracee\n");
10601.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
10611.1Skamil	tracee = atf_utils_fork();
10621.1Skamil	if (tracee == 0) {
10631.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
10641.13Schristos		DPRINTF("Parent should now attach to tracee\n");
10651.1Skamil
10661.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
10671.1Skamil		/* Wait for message from the parent */
10681.1Skamil		_exit(exitval_tracee);
10691.1Skamil	}
10701.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
10711.1Skamil
10721.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
10731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
10741.1Skamil
10751.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
10761.1Skamil	    TWAIT_FNAME);
10771.1Skamil	TWAIT_REQUIRE_SUCCESS(
10781.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10791.1Skamil
10801.1Skamil	validate_status_stopped(status, SIGSTOP);
10811.1Skamil
10821.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
10831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
10841.1Skamil
10851.13Schristos	DPRINTF("Let the tracee exit now\n");
10861.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
10871.1Skamil
10881.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
10891.1Skamil	TWAIT_REQUIRE_SUCCESS(
10901.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10911.1Skamil
10921.1Skamil	validate_status_exited(status, exitval_tracee);
10931.1Skamil
10941.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
10951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
10961.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
10971.1Skamil
10981.1Skamil	msg_close(&parent_tracee);
10991.1Skamil}
11001.1Skamil
11011.51Skamil/// ----------------------------------------------------------------------------
11021.51Skamil
11031.51SkamilATF_TC(child_attach_to_its_parent);
11041.51SkamilATF_TC_HEAD(child_attach_to_its_parent, tc)
11051.1Skamil{
11061.1Skamil	atf_tc_set_md_var(tc, "descr",
11071.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
11081.1Skamil}
11091.1Skamil
11101.51SkamilATF_TC_BODY(child_attach_to_its_parent, tc)
11111.1Skamil{
11121.1Skamil	struct msg_fds parent_tracee;
11131.1Skamil	const int exitval_tracer = 5;
11141.1Skamil	pid_t tracer, wpid;
11151.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
11161.1Skamil#if defined(TWAIT_HAVE_STATUS)
11171.1Skamil	int status;
11181.1Skamil#endif
11191.1Skamil
11201.13Schristos	DPRINTF("Spawn tracer\n");
11211.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
11221.1Skamil	tracer = atf_utils_fork();
11231.1Skamil	if (tracer == 0) {
11241.1Skamil
11251.1Skamil		/* Wait for message from the parent */
11261.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
11271.1Skamil
11281.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
11291.1Skamil		    getppid());
11301.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
11311.1Skamil
11321.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
11331.1Skamil		    TWAIT_FNAME);
11341.1Skamil		FORKEE_REQUIRE_SUCCESS(
11351.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
11361.1Skamil
11371.1Skamil		forkee_status_stopped(status, SIGSTOP);
11381.1Skamil
11391.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
11401.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
11411.1Skamil		    != -1);
11421.1Skamil
11431.1Skamil		/* Tell parent we are ready */
11441.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
11451.1Skamil
11461.1Skamil		_exit(exitval_tracer);
11471.1Skamil	}
11481.1Skamil
11491.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
11501.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
11511.13Schristos	DPRINTF("Allow the tracer to exit now\n");
11521.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
11531.1Skamil
11541.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
11551.1Skamil	TWAIT_REQUIRE_SUCCESS(
11561.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
11571.1Skamil
11581.1Skamil	validate_status_exited(status, exitval_tracer);
11591.1Skamil
11601.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
11611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
11621.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
11631.1Skamil
11641.1Skamil	msg_close(&parent_tracee);
11651.1Skamil}
11661.1Skamil
11671.51Skamil/// ----------------------------------------------------------------------------
11681.51Skamil
11691.1Skamil#if defined(TWAIT_HAVE_PID)
11701.1Skamil
11711.51Skamilenum tracee_sees_its_original_parent_type {
11721.51Skamil	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
11731.51Skamil	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
11741.51Skamil	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS
11751.51Skamil};
11761.51Skamil
11771.51Skamilstatic void
11781.51Skamiltracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type)
11791.1Skamil{
11801.1Skamil	struct msg_fds parent_tracer, parent_tracee;
11811.1Skamil	const int exitval_tracee = 5;
11821.1Skamil	const int exitval_tracer = 10;
11831.1Skamil	pid_t parent, tracee, tracer, wpid;
11841.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
11851.1Skamil#if defined(TWAIT_HAVE_STATUS)
11861.1Skamil	int status;
11871.1Skamil#endif
11881.51Skamil	/* sysctl(3) - kinfo_proc2 */
11891.51Skamil	int name[CTL_MAXNAME];
11901.51Skamil	struct kinfo_proc2 kp;
11911.51Skamil	size_t len = sizeof(kp);
11921.51Skamil	unsigned int namelen;
11931.51Skamil
11941.51Skamil	/* procfs - status  */
11951.51Skamil	FILE *fp;
11961.51Skamil	struct stat st;
11971.51Skamil	const char *fname = "/proc/curproc/status";
11981.51Skamil	char s_executable[MAXPATHLEN];
11991.51Skamil	int s_pid, s_ppid;
12001.51Skamil	int rv;
12011.51Skamil
12021.51Skamil	if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) {
12031.51Skamil		SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 ||
12041.51Skamil		                (errno == ENOENT));
12051.51Skamil		if (rv != 0) {
12061.51Skamil			atf_tc_skip("/proc/curproc/status not found");
12071.51Skamil		}
12081.51Skamil	}
12091.1Skamil
12101.13Schristos	DPRINTF("Spawn tracee\n");
12111.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
12121.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
12131.1Skamil	tracee = atf_utils_fork();
12141.1Skamil	if (tracee == 0) {
12151.1Skamil		parent = getppid();
12161.1Skamil
12171.1Skamil		/* Emit message to the parent */
12181.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
12191.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
12201.1Skamil
12211.51Skamil		switch (type) {
12221.51Skamil		case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID:
12231.51Skamil			FORKEE_ASSERT_EQ(parent, getppid());
12241.51Skamil			break;
12251.51Skamil		case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2:
12261.51Skamil			namelen = 0;
12271.51Skamil			name[namelen++] = CTL_KERN;
12281.51Skamil			name[namelen++] = KERN_PROC2;
12291.51Skamil			name[namelen++] = KERN_PROC_PID;
12301.51Skamil			name[namelen++] = getpid();
12311.51Skamil			name[namelen++] = len;
12321.51Skamil			name[namelen++] = 1;
12331.51Skamil
12341.51Skamil			FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL,
12351.51Skamil			                        0),
12361.51Skamil			                 0);
12371.51Skamil			FORKEE_ASSERT_EQ(parent, kp.p_ppid);
12381.51Skamil			break;
12391.51Skamil		case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS:
12401.51Skamil			/*
12411.51Skamil			 * Format:
12421.51Skamil			 *  EXECUTABLE PID PPID ...
12431.51Skamil			 */
12441.51Skamil			FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
12451.51Skamil			fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
12461.51Skamil			FORKEE_ASSERT_EQ(fclose(fp), 0);
12471.51Skamil			FORKEE_ASSERT_EQ(parent, s_ppid);
12481.51Skamil			break;
12491.51Skamil		}
12501.1Skamil
12511.1Skamil		_exit(exitval_tracee);
12521.1Skamil	}
12531.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
12541.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
12551.1Skamil
12561.13Schristos	DPRINTF("Spawn debugger\n");
12571.1Skamil	tracer = atf_utils_fork();
12581.1Skamil	if (tracer == 0) {
12591.1Skamil		/* No IPC to communicate with the child */
12601.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
12611.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
12621.1Skamil
12631.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
12641.1Skamil		FORKEE_REQUIRE_SUCCESS(
12651.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
12661.1Skamil
12671.1Skamil		forkee_status_stopped(status, SIGSTOP);
12681.1Skamil
12691.1Skamil		/* Resume tracee with PT_CONTINUE */
12701.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
12711.1Skamil
12721.1Skamil		/* Inform parent that tracer has attached to tracee */
12731.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
12741.1Skamil
12751.1Skamil		/* Wait for parent to tell use that tracee should have exited */
12761.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
12771.1Skamil
12781.1Skamil		/* Wait for tracee and assert that it exited */
12791.1Skamil		FORKEE_REQUIRE_SUCCESS(
12801.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
12811.1Skamil
12821.1Skamil		forkee_status_exited(status, exitval_tracee);
12831.1Skamil
12841.13Schristos		DPRINTF("Before exiting of the tracer process\n");
12851.1Skamil		_exit(exitval_tracer);
12861.1Skamil	}
12871.1Skamil
12881.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
12891.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
12901.1Skamil
12911.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
12921.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
12931.1Skamil
12941.13Schristos	DPRINTF("Detect that tracee is zombie\n");
12951.1Skamil	await_zombie(tracee);
12961.1Skamil
12971.13Schristos	DPRINTF("Assert that there is no status about tracee - "
12981.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
12991.1Skamil	TWAIT_REQUIRE_SUCCESS(
13001.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
13011.1Skamil
13021.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
13031.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
13041.1Skamil
13051.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
13061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
13071.1Skamil	    tracer);
13081.1Skamil
13091.1Skamil	validate_status_exited(status, exitval_tracer);
13101.1Skamil
13111.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
13121.1Skamil	    TWAIT_FNAME);
13131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
13141.1Skamil	    tracee);
13151.1Skamil
13161.1Skamil	validate_status_exited(status, exitval_tracee);
13171.1Skamil
13181.1Skamil	msg_close(&parent_tracer);
13191.1Skamil	msg_close(&parent_tracee);
13201.1Skamil}
13211.1Skamil
13221.51Skamil#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr)			\
13231.51SkamilATF_TC(test);									\
13241.51SkamilATF_TC_HEAD(test, tc)								\
13251.51Skamil{										\
13261.51Skamil	atf_tc_set_md_var(tc, "descr",						\
13271.51Skamil	    "Assert that tracee sees its original parent when being traced "	\
13281.51Skamil	    "(check " descr ")");						\
13291.51Skamil}										\
13301.51Skamil										\
13311.51SkamilATF_TC_BODY(test, tc)								\
13321.51Skamil{										\
13331.51Skamil										\
13341.51Skamil	tracee_sees_its_original_parent(type);					\
13351.1Skamil}
13361.1Skamil
13371.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT(
13381.51Skamil	tracee_sees_its_original_parent_getppid,
13391.51Skamil	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
13401.51Skamil	"getppid(2)");
13411.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT(
13421.51Skamil	tracee_sees_its_original_parent_sysctl_kinfo_proc2,
13431.51Skamil	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
13441.51Skamil	"sysctl(3) and kinfo_proc2");
13451.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT(
13461.51Skamil	tracee_sees_its_original_parent_procfs_status,
13471.51Skamil	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS,
13481.51Skamil	"the status file in procfs");
13491.1Skamil#endif
13501.1Skamil
13511.51Skamil/// ----------------------------------------------------------------------------
13521.1Skamil
13531.1SkamilATF_TC(eventmask1);
13541.1SkamilATF_TC_HEAD(eventmask1, tc)
13551.1Skamil{
13561.1Skamil	atf_tc_set_md_var(tc, "descr",
13571.1Skamil	    "Verify that empty EVENT_MASK is preserved");
13581.1Skamil}
13591.1Skamil
13601.1SkamilATF_TC_BODY(eventmask1, tc)
13611.1Skamil{
13621.1Skamil	const int exitval = 5;
13631.1Skamil	const int sigval = SIGSTOP;
13641.1Skamil	pid_t child, wpid;
13651.1Skamil#if defined(TWAIT_HAVE_STATUS)
13661.1Skamil	int status;
13671.1Skamil#endif
13681.1Skamil	ptrace_event_t set_event, get_event;
13691.1Skamil	const int len = sizeof(ptrace_event_t);
13701.1Skamil
13711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13731.1Skamil	if (child == 0) {
13741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13761.1Skamil
13771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13791.1Skamil
13801.13Schristos		DPRINTF("Before exiting of the child process\n");
13811.1Skamil		_exit(exitval);
13821.1Skamil	}
13831.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
13891.1Skamil
13901.1Skamil	set_event.pe_set_event = 0;
13911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13931.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13941.1Skamil
13951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13961.1Skamil	    "without signal to be sent\n");
13971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13981.1Skamil
13991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14011.1Skamil
14021.1Skamil	validate_status_exited(status, exitval);
14031.1Skamil
14041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14061.1Skamil}
14071.1Skamil
14081.1SkamilATF_TC(eventmask2);
14091.1SkamilATF_TC_HEAD(eventmask2, tc)
14101.1Skamil{
14111.1Skamil	atf_tc_set_md_var(tc, "descr",
14121.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
14131.1Skamil}
14141.1Skamil
14151.1SkamilATF_TC_BODY(eventmask2, tc)
14161.1Skamil{
14171.1Skamil	const int exitval = 5;
14181.1Skamil	const int sigval = SIGSTOP;
14191.1Skamil	pid_t child, wpid;
14201.1Skamil#if defined(TWAIT_HAVE_STATUS)
14211.1Skamil	int status;
14221.1Skamil#endif
14231.1Skamil	ptrace_event_t set_event, get_event;
14241.1Skamil	const int len = sizeof(ptrace_event_t);
14251.1Skamil
14261.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14271.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14281.1Skamil	if (child == 0) {
14291.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14301.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14311.1Skamil
14321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14341.1Skamil
14351.13Schristos		DPRINTF("Before exiting of the child process\n");
14361.1Skamil		_exit(exitval);
14371.1Skamil	}
14381.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
14441.1Skamil
14451.1Skamil	set_event.pe_set_event = PTRACE_FORK;
14461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
14471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
14481.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
14491.1Skamil
14501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14511.1Skamil	    "without signal to be sent\n");
14521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14531.1Skamil
14541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14561.1Skamil
14571.1Skamil	validate_status_exited(status, exitval);
14581.1Skamil
14591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14611.1Skamil}
14621.1Skamil
14631.1SkamilATF_TC(eventmask3);
14641.1SkamilATF_TC_HEAD(eventmask3, tc)
14651.1Skamil{
14661.1Skamil	atf_tc_set_md_var(tc, "descr",
14671.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
14681.1Skamil}
14691.1Skamil
14701.1SkamilATF_TC_BODY(eventmask3, tc)
14711.1Skamil{
14721.1Skamil	const int exitval = 5;
14731.1Skamil	const int sigval = SIGSTOP;
14741.1Skamil	pid_t child, wpid;
14751.1Skamil#if defined(TWAIT_HAVE_STATUS)
14761.1Skamil	int status;
14771.1Skamil#endif
14781.1Skamil	ptrace_event_t set_event, get_event;
14791.1Skamil	const int len = sizeof(ptrace_event_t);
14801.1Skamil
14811.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14821.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14831.1Skamil	if (child == 0) {
14841.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14851.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14861.1Skamil
14871.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14881.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14891.1Skamil
14901.13Schristos		DPRINTF("Before exiting of the child process\n");
14911.1Skamil		_exit(exitval);
14921.1Skamil	}
14931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
14991.1Skamil
15001.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
15011.38Skamil	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
15021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
15031.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
15041.1Skamil
15051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15061.1Skamil	    "without signal to be sent\n");
15071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15081.1Skamil
15091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15111.1Skamil
15121.1Skamil	validate_status_exited(status, exitval);
15131.1Skamil
15141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15161.1Skamil}
15171.1Skamil
15181.1SkamilATF_TC(eventmask4);
15191.1SkamilATF_TC_HEAD(eventmask4, tc)
15201.1Skamil{
15211.1Skamil	atf_tc_set_md_var(tc, "descr",
15221.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
15231.1Skamil}
15241.1Skamil
15251.1SkamilATF_TC_BODY(eventmask4, tc)
15261.1Skamil{
15271.1Skamil	const int exitval = 5;
15281.1Skamil	const int sigval = SIGSTOP;
15291.1Skamil	pid_t child, wpid;
15301.1Skamil#if defined(TWAIT_HAVE_STATUS)
15311.1Skamil	int status;
15321.1Skamil#endif
15331.1Skamil	ptrace_event_t set_event, get_event;
15341.1Skamil	const int len = sizeof(ptrace_event_t);
15351.1Skamil
15361.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15371.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15381.1Skamil	if (child == 0) {
15391.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15401.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15411.1Skamil
15421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15441.1Skamil
15451.13Schristos		DPRINTF("Before exiting of the child process\n");
15461.1Skamil		_exit(exitval);
15471.1Skamil	}
15481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
15541.1Skamil
15551.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
15561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
15571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
15581.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
15591.1Skamil
15601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15611.1Skamil	    "without signal to be sent\n");
15621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15631.1Skamil
15641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15661.1Skamil
15671.1Skamil	validate_status_exited(status, exitval);
15681.1Skamil
15691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15711.1Skamil}
15721.1Skamil
15731.1SkamilATF_TC(eventmask5);
15741.1SkamilATF_TC_HEAD(eventmask5, tc)
15751.1Skamil{
15761.1Skamil	atf_tc_set_md_var(tc, "descr",
15771.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
15781.1Skamil}
15791.1Skamil
15801.1SkamilATF_TC_BODY(eventmask5, tc)
15811.1Skamil{
15821.1Skamil	const int exitval = 5;
15831.1Skamil	const int sigval = SIGSTOP;
15841.1Skamil	pid_t child, wpid;
15851.1Skamil#if defined(TWAIT_HAVE_STATUS)
15861.1Skamil	int status;
15871.1Skamil#endif
15881.1Skamil	ptrace_event_t set_event, get_event;
15891.1Skamil	const int len = sizeof(ptrace_event_t);
15901.1Skamil
15911.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15921.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15931.1Skamil	if (child == 0) {
15941.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15951.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15961.1Skamil
15971.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15981.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15991.1Skamil
16001.13Schristos		DPRINTF("Before exiting of the child process\n");
16011.1Skamil		_exit(exitval);
16021.1Skamil	}
16031.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
16091.1Skamil
16101.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
16111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
16121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
16131.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
16141.1Skamil
16151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16161.1Skamil	    "without signal to be sent\n");
16171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16181.1Skamil
16191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16211.1Skamil
16221.1Skamil	validate_status_exited(status, exitval);
16231.1Skamil
16241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16261.1Skamil}
16271.1Skamil
16281.1SkamilATF_TC(eventmask6);
16291.1SkamilATF_TC_HEAD(eventmask6, tc)
16301.1Skamil{
16311.1Skamil	atf_tc_set_md_var(tc, "descr",
16321.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
16331.1Skamil}
16341.1Skamil
16351.1SkamilATF_TC_BODY(eventmask6, tc)
16361.1Skamil{
16371.1Skamil	const int exitval = 5;
16381.1Skamil	const int sigval = SIGSTOP;
16391.1Skamil	pid_t child, wpid;
16401.1Skamil#if defined(TWAIT_HAVE_STATUS)
16411.1Skamil	int status;
16421.1Skamil#endif
16431.1Skamil	ptrace_event_t set_event, get_event;
16441.1Skamil	const int len = sizeof(ptrace_event_t);
16451.1Skamil
16461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16481.1Skamil	if (child == 0) {
16491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16511.1Skamil
16521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16541.1Skamil
16551.13Schristos		DPRINTF("Before exiting of the child process\n");
16561.1Skamil		_exit(exitval);
16571.1Skamil	}
16581.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
16641.1Skamil
16651.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
16661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
16671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
16681.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
16691.1Skamil
16701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16711.1Skamil	    "without signal to be sent\n");
16721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16731.1Skamil
16741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16761.1Skamil
16771.1Skamil	validate_status_exited(status, exitval);
16781.1Skamil
16791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16811.1Skamil}
16821.1Skamil
16831.28Skamilstatic void
16841.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
16851.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
16861.1Skamil{
16871.1Skamil	const int exitval = 5;
16881.1Skamil	const int exitval2 = 15;
16891.1Skamil	const int sigval = SIGSTOP;
16901.31Skamil	pid_t child, child2 = 0, wpid;
16911.1Skamil#if defined(TWAIT_HAVE_STATUS)
16921.1Skamil	int status;
16931.1Skamil#endif
16941.1Skamil	ptrace_state_t state;
16951.1Skamil	const int slen = sizeof(state);
16961.1Skamil	ptrace_event_t event;
16971.1Skamil	const int elen = sizeof(event);
16981.1Skamil
16991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17011.1Skamil	if (child == 0) {
17021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17041.1Skamil
17051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17071.1Skamil
17081.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
17091.1Skamil
17101.1Skamil		if (child2 == 0)
17111.1Skamil			_exit(exitval2);
17121.1Skamil
17131.1Skamil		FORKEE_REQUIRE_SUCCESS
17141.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
17151.1Skamil
17161.1Skamil		forkee_status_exited(status, exitval2);
17171.1Skamil
17181.13Schristos		DPRINTF("Before exiting of the child process\n");
17191.1Skamil		_exit(exitval);
17201.1Skamil	}
17211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17221.1Skamil
17231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17251.1Skamil
17261.1Skamil	validate_status_stopped(status, sigval);
17271.1Skamil
17281.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
17291.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
17301.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
17311.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
17321.30Skamil	event.pe_set_event = 0;
17331.30Skamil	if (trackfork)
17341.30Skamil		event.pe_set_event |= PTRACE_FORK;
17351.30Skamil	if (trackvfork)
17361.30Skamil		event.pe_set_event |= PTRACE_VFORK;
17371.30Skamil	if (trackvforkdone)
17381.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
17391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17401.1Skamil
17411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17421.1Skamil	    "without signal to be sent\n");
17431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17441.1Skamil
17451.29Skamil#if defined(TWAIT_HAVE_PID)
17461.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
17471.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
17481.29Skamil		        child);
17491.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
17501.29Skamil		                      child);
17511.1Skamil
17521.29Skamil		validate_status_stopped(status, SIGTRAP);
17531.1Skamil
17541.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
17551.29Skamil		                       slen) != -1);
17561.31Skamil		if (trackfork && fn == fork) {
17571.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
17581.30Skamil			       PTRACE_FORK);
17591.30Skamil		}
17601.31Skamil		if (trackvfork && fn == vfork) {
17611.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
17621.30Skamil			       PTRACE_VFORK);
17631.30Skamil		}
17641.29Skamil
17651.29Skamil		child2 = state.pe_other_pid;
17661.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
17671.29Skamil
17681.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
17691.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
17701.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
17711.29Skamil		    child2);
17721.1Skamil
17731.29Skamil		validate_status_stopped(status, SIGTRAP);
17741.1Skamil
17751.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
17761.29Skamil		                       slen) != -1);
17771.31Skamil		if (trackfork && fn == fork) {
17781.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
17791.30Skamil			       PTRACE_FORK);
17801.30Skamil		}
17811.31Skamil		if (trackvfork && fn == vfork) {
17821.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
17831.30Skamil			       PTRACE_VFORK);
17841.30Skamil		}
17851.30Skamil
17861.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
17871.29Skamil
17881.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
17891.29Skamil		    "and without signal to be sent\n");
17901.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
17911.29Skamil		                != -1);
17921.29Skamil
17931.29Skamil		DPRINTF("Before resuming the child process where it left off "
17941.29Skamil		        "and without signal to be sent\n");
17951.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17961.30Skamil	}
17971.30Skamil#endif
17981.30Skamil
17991.31Skamil	if (trackvforkdone && fn == vfork) {
18001.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
18011.30Skamil		        child);
18021.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
18031.30Skamil		                      child);
18041.30Skamil
18051.30Skamil		validate_status_stopped(status, SIGTRAP);
18061.30Skamil
18071.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
18081.30Skamil		                       slen) != -1);
18091.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
18101.30Skamil
18111.30Skamil		child2 = state.pe_other_pid;
18121.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
18131.30Skamil		        child2);
18141.30Skamil
18151.30Skamil		DPRINTF("Before resuming the child process where it left off "
18161.30Skamil		        "and without signal to be sent\n");
18171.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18181.30Skamil	}
18191.29Skamil
18201.30Skamil#if defined(TWAIT_HAVE_PID)
18211.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
18221.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
18231.29Skamil		        "\n", TWAIT_FNAME);
18241.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
18251.29Skamil		    child2);
18261.29Skamil
18271.29Skamil		validate_status_exited(status, exitval2);
18281.29Skamil
18291.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
18301.29Skamil		        "process\n", TWAIT_FNAME);
18311.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
18321.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
18331.29Skamil	}
18341.29Skamil#endif
18351.1Skamil
18361.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18371.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18391.1Skamil
18401.1Skamil	validate_status_stopped(status, SIGCHLD);
18411.1Skamil
18421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18431.1Skamil	    "without signal to be sent\n");
18441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18451.1Skamil
18461.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
18471.1Skamil	    TWAIT_FNAME);
18481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18491.1Skamil
18501.1Skamil	validate_status_exited(status, exitval);
18511.1Skamil
18521.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
18531.1Skamil	    TWAIT_FNAME);
18541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18551.1Skamil}
18561.28Skamil
18571.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
18581.32SkamilATF_TC(name);									\
18591.32SkamilATF_TC_HEAD(name, tc)								\
18601.32Skamil{										\
18611.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
18621.32Skamil}										\
18631.32Skamil										\
18641.32SkamilATF_TC_BODY(name, tc)								\
18651.32Skamil{										\
18661.32Skamil										\
18671.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
18681.32Skamil}
18691.32Skamil
18701.32Skamil#define F false
18711.32Skamil#define T true
18721.32Skamil
18731.32Skamil#define F_IF__0(x)
18741.32Skamil#define F_IF__1(x) x
18751.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
18761.32Skamil#define F_IF_(x,y) F_IF__(x,y)
18771.32Skamil#define F_IF(x,y) F_IF_(x,y)
18781.32Skamil
18791.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
18801.32Skamil        "Verify " #function "(2) called with 0"					\
18811.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
18821.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
18831.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
18841.32Skamil        " in EVENT_MASK."							\
18851.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
18861.32Skamil        F_IF(dparentbit," Detach parent in this test.")
18871.1Skamil
18881.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
18891.31Skamil#if defined(TWAIT_HAVE_PID)
18901.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
18911.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
18921.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
18931.31Skamil#endif
18941.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
18951.31Skamil#if defined(TWAIT_HAVE_PID)
18961.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
18971.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
18981.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
18991.31Skamil#endif
19001.1Skamil
19011.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
19021.31Skamil#if defined(TWAIT_HAVE_PID)
19031.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
19041.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
19051.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
19061.31Skamil#endif
19071.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
19081.31Skamil#if defined(TWAIT_HAVE_PID)
19091.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
19101.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
19111.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
19121.31Skamil#endif
19131.31Skamil
19141.31Skamil
19151.31Skamil
19161.1Skamil
19171.1SkamilATF_TC(io_read_d1);
19181.1SkamilATF_TC_HEAD(io_read_d1, tc)
19191.1Skamil{
19201.1Skamil	atf_tc_set_md_var(tc, "descr",
19211.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
19221.1Skamil}
19231.1Skamil
19241.1SkamilATF_TC_BODY(io_read_d1, tc)
19251.1Skamil{
19261.1Skamil	const int exitval = 5;
19271.1Skamil	const int sigval = SIGSTOP;
19281.1Skamil	pid_t child, wpid;
19291.1Skamil	uint8_t lookup_me = 0;
19301.1Skamil	const uint8_t magic = 0xab;
19311.1Skamil	struct ptrace_io_desc io = {
19321.1Skamil		.piod_op = PIOD_READ_D,
19331.1Skamil		.piod_offs = &lookup_me,
19341.1Skamil		.piod_addr = &lookup_me,
19351.1Skamil		.piod_len = sizeof(lookup_me)
19361.1Skamil	};
19371.1Skamil#if defined(TWAIT_HAVE_STATUS)
19381.1Skamil	int status;
19391.1Skamil#endif
19401.1Skamil
19411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19431.1Skamil	if (child == 0) {
19441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19461.1Skamil
19471.1Skamil		lookup_me = magic;
19481.1Skamil
19491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19511.1Skamil
19521.13Schristos		DPRINTF("Before exiting of the child process\n");
19531.1Skamil		_exit(exitval);
19541.1Skamil	}
19551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19561.1Skamil
19571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19591.1Skamil
19601.1Skamil	validate_status_stopped(status, sigval);
19611.1Skamil
19621.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19631.1Skamil	    child, getpid());
19641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19651.1Skamil
19661.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19671.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
19681.1Skamil
19691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19701.1Skamil	    "without signal to be sent\n");
19711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19721.1Skamil
19731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19751.1Skamil
19761.1Skamil	validate_status_exited(status, exitval);
19771.1Skamil
19781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19801.1Skamil}
19811.1Skamil
19821.1SkamilATF_TC(io_read_d2);
19831.1SkamilATF_TC_HEAD(io_read_d2, tc)
19841.1Skamil{
19851.1Skamil	atf_tc_set_md_var(tc, "descr",
19861.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
19871.1Skamil}
19881.1Skamil
19891.1SkamilATF_TC_BODY(io_read_d2, tc)
19901.1Skamil{
19911.1Skamil	const int exitval = 5;
19921.1Skamil	const int sigval = SIGSTOP;
19931.1Skamil	pid_t child, wpid;
19941.1Skamil	uint16_t lookup_me = 0;
19951.1Skamil	const uint16_t magic = 0x1234;
19961.1Skamil	struct ptrace_io_desc io = {
19971.1Skamil		.piod_op = PIOD_READ_D,
19981.1Skamil		.piod_offs = &lookup_me,
19991.1Skamil		.piod_addr = &lookup_me,
20001.1Skamil		.piod_len = sizeof(lookup_me)
20011.1Skamil	};
20021.1Skamil#if defined(TWAIT_HAVE_STATUS)
20031.1Skamil	int status;
20041.1Skamil#endif
20051.1Skamil
20061.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20071.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20081.1Skamil	if (child == 0) {
20091.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20101.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20111.1Skamil
20121.1Skamil		lookup_me = magic;
20131.1Skamil
20141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20161.1Skamil
20171.13Schristos		DPRINTF("Before exiting of the child process\n");
20181.1Skamil		_exit(exitval);
20191.1Skamil	}
20201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20211.1Skamil
20221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20241.1Skamil
20251.1Skamil	validate_status_stopped(status, sigval);
20261.1Skamil
20271.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20281.1Skamil	    child, getpid());
20291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20301.1Skamil
20311.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20321.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
20331.1Skamil
20341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20351.1Skamil	    "without signal to be sent\n");
20361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20371.1Skamil
20381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20401.1Skamil
20411.1Skamil	validate_status_exited(status, exitval);
20421.1Skamil
20431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20451.1Skamil}
20461.1Skamil
20471.1SkamilATF_TC(io_read_d3);
20481.1SkamilATF_TC_HEAD(io_read_d3, tc)
20491.1Skamil{
20501.1Skamil	atf_tc_set_md_var(tc, "descr",
20511.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
20521.1Skamil}
20531.1Skamil
20541.1SkamilATF_TC_BODY(io_read_d3, tc)
20551.1Skamil{
20561.1Skamil	const int exitval = 5;
20571.1Skamil	const int sigval = SIGSTOP;
20581.1Skamil	pid_t child, wpid;
20591.1Skamil	uint32_t lookup_me = 0;
20601.1Skamil	const uint32_t magic = 0x1234abcd;
20611.1Skamil	struct ptrace_io_desc io = {
20621.1Skamil		.piod_op = PIOD_READ_D,
20631.1Skamil		.piod_offs = &lookup_me,
20641.1Skamil		.piod_addr = &lookup_me,
20651.1Skamil		.piod_len = sizeof(lookup_me)
20661.1Skamil	};
20671.1Skamil#if defined(TWAIT_HAVE_STATUS)
20681.1Skamil	int status;
20691.1Skamil#endif
20701.1Skamil
20711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20731.1Skamil	if (child == 0) {
20741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20761.1Skamil
20771.1Skamil		lookup_me = magic;
20781.1Skamil
20791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20811.1Skamil
20821.13Schristos		DPRINTF("Before exiting of the child process\n");
20831.1Skamil		_exit(exitval);
20841.1Skamil	}
20851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20861.1Skamil
20871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20891.1Skamil
20901.1Skamil	validate_status_stopped(status, sigval);
20911.1Skamil
20921.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20931.1Skamil	    child, getpid());
20941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20951.1Skamil
20961.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20971.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
20981.1Skamil
20991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21001.1Skamil	    "without signal to be sent\n");
21011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21021.1Skamil
21031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21051.1Skamil
21061.1Skamil	validate_status_exited(status, exitval);
21071.1Skamil
21081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21101.1Skamil}
21111.1Skamil
21121.1SkamilATF_TC(io_read_d4);
21131.1SkamilATF_TC_HEAD(io_read_d4, tc)
21141.1Skamil{
21151.1Skamil	atf_tc_set_md_var(tc, "descr",
21161.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
21171.1Skamil}
21181.1Skamil
21191.1SkamilATF_TC_BODY(io_read_d4, tc)
21201.1Skamil{
21211.1Skamil	const int exitval = 5;
21221.1Skamil	const int sigval = SIGSTOP;
21231.1Skamil	pid_t child, wpid;
21241.1Skamil	uint64_t lookup_me = 0;
21251.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
21261.1Skamil	struct ptrace_io_desc io = {
21271.1Skamil		.piod_op = PIOD_READ_D,
21281.1Skamil		.piod_offs = &lookup_me,
21291.1Skamil		.piod_addr = &lookup_me,
21301.1Skamil		.piod_len = sizeof(lookup_me)
21311.1Skamil	};
21321.1Skamil#if defined(TWAIT_HAVE_STATUS)
21331.1Skamil	int status;
21341.1Skamil#endif
21351.1Skamil
21361.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21371.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21381.1Skamil	if (child == 0) {
21391.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21401.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21411.1Skamil
21421.1Skamil		lookup_me = magic;
21431.1Skamil
21441.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21451.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21461.1Skamil
21471.13Schristos		DPRINTF("Before exiting of the child process\n");
21481.1Skamil		_exit(exitval);
21491.1Skamil	}
21501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21511.1Skamil
21521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21541.1Skamil
21551.1Skamil	validate_status_stopped(status, sigval);
21561.1Skamil
21571.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21581.1Skamil	    child, getpid());
21591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21601.1Skamil
21611.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21621.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
21631.1Skamil
21641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21651.1Skamil	    "without signal to be sent\n");
21661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21671.1Skamil
21681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21701.1Skamil
21711.1Skamil	validate_status_exited(status, exitval);
21721.1Skamil
21731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21751.1Skamil}
21761.1Skamil
21771.1SkamilATF_TC(io_write_d1);
21781.1SkamilATF_TC_HEAD(io_write_d1, tc)
21791.1Skamil{
21801.1Skamil	atf_tc_set_md_var(tc, "descr",
21811.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
21821.1Skamil}
21831.1Skamil
21841.1SkamilATF_TC_BODY(io_write_d1, tc)
21851.1Skamil{
21861.1Skamil	const int exitval = 5;
21871.1Skamil	const int sigval = SIGSTOP;
21881.1Skamil	pid_t child, wpid;
21891.1Skamil	uint8_t lookup_me = 0;
21901.1Skamil	const uint8_t magic = 0xab;
21911.1Skamil	struct ptrace_io_desc io = {
21921.1Skamil		.piod_op = PIOD_WRITE_D,
21931.1Skamil		.piod_offs = &lookup_me,
21941.1Skamil		.piod_addr = &lookup_me,
21951.1Skamil		.piod_len = sizeof(lookup_me)
21961.1Skamil	};
21971.1Skamil#if defined(TWAIT_HAVE_STATUS)
21981.1Skamil	int status;
21991.1Skamil#endif
22001.1Skamil
22011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22031.1Skamil	if (child == 0) {
22041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22061.1Skamil
22071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22091.1Skamil
22101.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22111.1Skamil
22121.13Schristos		DPRINTF("Before exiting of the child process\n");
22131.1Skamil		_exit(exitval);
22141.1Skamil	}
22151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22161.1Skamil
22171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22191.1Skamil
22201.1Skamil	validate_status_stopped(status, sigval);
22211.1Skamil
22221.1Skamil	lookup_me = magic;
22231.1Skamil
22241.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22251.1Skamil	    child, getpid());
22261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22271.1Skamil
22281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22291.1Skamil	    "without signal to be sent\n");
22301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22311.1Skamil
22321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22341.1Skamil
22351.1Skamil	validate_status_exited(status, exitval);
22361.1Skamil
22371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22391.1Skamil}
22401.1Skamil
22411.1SkamilATF_TC(io_write_d2);
22421.1SkamilATF_TC_HEAD(io_write_d2, tc)
22431.1Skamil{
22441.1Skamil	atf_tc_set_md_var(tc, "descr",
22451.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
22461.1Skamil}
22471.1Skamil
22481.1SkamilATF_TC_BODY(io_write_d2, tc)
22491.1Skamil{
22501.1Skamil	const int exitval = 5;
22511.1Skamil	const int sigval = SIGSTOP;
22521.1Skamil	pid_t child, wpid;
22531.1Skamil	uint16_t lookup_me = 0;
22541.1Skamil	const uint16_t magic = 0xab12;
22551.1Skamil	struct ptrace_io_desc io = {
22561.1Skamil		.piod_op = PIOD_WRITE_D,
22571.1Skamil		.piod_offs = &lookup_me,
22581.1Skamil		.piod_addr = &lookup_me,
22591.1Skamil		.piod_len = sizeof(lookup_me)
22601.1Skamil	};
22611.1Skamil#if defined(TWAIT_HAVE_STATUS)
22621.1Skamil	int status;
22631.1Skamil#endif
22641.1Skamil
22651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22671.1Skamil	if (child == 0) {
22681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22701.1Skamil
22711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22731.1Skamil
22741.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22751.1Skamil
22761.13Schristos		DPRINTF("Before exiting of the child process\n");
22771.1Skamil		_exit(exitval);
22781.1Skamil	}
22791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22801.1Skamil
22811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22831.1Skamil
22841.1Skamil	validate_status_stopped(status, sigval);
22851.1Skamil
22861.1Skamil	lookup_me = magic;
22871.1Skamil
22881.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22891.1Skamil	    child, getpid());
22901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22911.1Skamil
22921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22931.1Skamil	    "without signal to be sent\n");
22941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22951.1Skamil
22961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22981.1Skamil
22991.1Skamil	validate_status_exited(status, exitval);
23001.1Skamil
23011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23021.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23031.1Skamil}
23041.1Skamil
23051.1SkamilATF_TC(io_write_d3);
23061.1SkamilATF_TC_HEAD(io_write_d3, tc)
23071.1Skamil{
23081.1Skamil	atf_tc_set_md_var(tc, "descr",
23091.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
23101.1Skamil}
23111.1Skamil
23121.1SkamilATF_TC_BODY(io_write_d3, tc)
23131.1Skamil{
23141.1Skamil	const int exitval = 5;
23151.1Skamil	const int sigval = SIGSTOP;
23161.1Skamil	pid_t child, wpid;
23171.1Skamil	uint32_t lookup_me = 0;
23181.1Skamil	const uint32_t magic = 0xab127643;
23191.1Skamil	struct ptrace_io_desc io = {
23201.1Skamil		.piod_op = PIOD_WRITE_D,
23211.1Skamil		.piod_offs = &lookup_me,
23221.1Skamil		.piod_addr = &lookup_me,
23231.1Skamil		.piod_len = sizeof(lookup_me)
23241.1Skamil	};
23251.1Skamil#if defined(TWAIT_HAVE_STATUS)
23261.1Skamil	int status;
23271.1Skamil#endif
23281.1Skamil
23291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23311.1Skamil	if (child == 0) {
23321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23341.1Skamil
23351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23371.1Skamil
23381.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23391.1Skamil
23401.13Schristos		DPRINTF("Before exiting of the child process\n");
23411.1Skamil		_exit(exitval);
23421.1Skamil	}
23431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23441.1Skamil
23451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23471.1Skamil
23481.1Skamil	validate_status_stopped(status, sigval);
23491.1Skamil
23501.1Skamil	lookup_me = magic;
23511.1Skamil
23521.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23531.1Skamil	    child, getpid());
23541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23551.1Skamil
23561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23571.1Skamil	    "without signal to be sent\n");
23581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23591.1Skamil
23601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23621.1Skamil
23631.1Skamil	validate_status_exited(status, exitval);
23641.1Skamil
23651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23671.1Skamil}
23681.1Skamil
23691.1SkamilATF_TC(io_write_d4);
23701.1SkamilATF_TC_HEAD(io_write_d4, tc)
23711.1Skamil{
23721.1Skamil	atf_tc_set_md_var(tc, "descr",
23731.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
23741.1Skamil}
23751.1Skamil
23761.1SkamilATF_TC_BODY(io_write_d4, tc)
23771.1Skamil{
23781.1Skamil	const int exitval = 5;
23791.1Skamil	const int sigval = SIGSTOP;
23801.1Skamil	pid_t child, wpid;
23811.1Skamil	uint64_t lookup_me = 0;
23821.1Skamil	const uint64_t magic = 0xab12764376490123;
23831.1Skamil	struct ptrace_io_desc io = {
23841.1Skamil		.piod_op = PIOD_WRITE_D,
23851.1Skamil		.piod_offs = &lookup_me,
23861.1Skamil		.piod_addr = &lookup_me,
23871.1Skamil		.piod_len = sizeof(lookup_me)
23881.1Skamil	};
23891.1Skamil#if defined(TWAIT_HAVE_STATUS)
23901.1Skamil	int status;
23911.1Skamil#endif
23921.1Skamil
23931.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23941.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23951.1Skamil	if (child == 0) {
23961.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23971.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23981.1Skamil
23991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24011.1Skamil
24021.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
24031.1Skamil
24041.13Schristos		DPRINTF("Before exiting of the child process\n");
24051.1Skamil		_exit(exitval);
24061.1Skamil	}
24071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24081.1Skamil
24091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24111.1Skamil
24121.1Skamil	validate_status_stopped(status, sigval);
24131.1Skamil
24141.1Skamil	lookup_me = magic;
24151.1Skamil
24161.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24171.1Skamil	    child, getpid());
24181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24191.1Skamil
24201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24211.1Skamil	    "without signal to be sent\n");
24221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24231.1Skamil
24241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24261.1Skamil
24271.1Skamil	validate_status_exited(status, exitval);
24281.1Skamil
24291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24311.1Skamil}
24321.1Skamil
24331.1SkamilATF_TC(io_read_auxv1);
24341.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
24351.1Skamil{
24361.1Skamil	atf_tc_set_md_var(tc, "descr",
24371.1Skamil	    "Verify PT_READ_AUXV called for tracee");
24381.1Skamil}
24391.1Skamil
24401.1SkamilATF_TC_BODY(io_read_auxv1, tc)
24411.1Skamil{
24421.1Skamil	const int exitval = 5;
24431.1Skamil	const int sigval = SIGSTOP;
24441.1Skamil	pid_t child, wpid;
24451.1Skamil#if defined(TWAIT_HAVE_STATUS)
24461.1Skamil	int status;
24471.1Skamil#endif
24481.1Skamil	AuxInfo ai[100], *aip;
24491.1Skamil	struct ptrace_io_desc io = {
24501.1Skamil		.piod_op = PIOD_READ_AUXV,
24511.1Skamil		.piod_offs = 0,
24521.1Skamil		.piod_addr = ai,
24531.1Skamil		.piod_len = sizeof(ai)
24541.1Skamil	};
24551.1Skamil
24561.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24571.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24581.1Skamil	if (child == 0) {
24591.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24601.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24611.1Skamil
24621.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24631.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24641.1Skamil
24651.13Schristos		DPRINTF("Before exiting of the child process\n");
24661.1Skamil		_exit(exitval);
24671.1Skamil	}
24681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24691.1Skamil
24701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24721.1Skamil
24731.1Skamil	validate_status_stopped(status, sigval);
24741.1Skamil
24751.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
24761.1Skamil	    child, getpid());
24771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24781.1Skamil
24791.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
24801.1Skamil	ATF_REQUIRE(io.piod_len > 0);
24811.1Skamil
24821.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
24831.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
24841.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
24851.1Skamil
24861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24871.1Skamil	    "without signal to be sent\n");
24881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24891.1Skamil
24901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24921.1Skamil
24931.1Skamil	validate_status_exited(status, exitval);
24941.1Skamil
24951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24971.1Skamil}
24981.1Skamil
24991.1SkamilATF_TC(read_d1);
25001.1SkamilATF_TC_HEAD(read_d1, tc)
25011.1Skamil{
25021.1Skamil	atf_tc_set_md_var(tc, "descr",
25031.1Skamil	    "Verify PT_READ_D called once");
25041.1Skamil}
25051.1Skamil
25061.1SkamilATF_TC_BODY(read_d1, tc)
25071.1Skamil{
25081.1Skamil	const int exitval = 5;
25091.1Skamil	const int sigval = SIGSTOP;
25101.1Skamil	pid_t child, wpid;
25111.1Skamil	int lookup_me = 0;
25121.1Skamil	const int magic = (int)random();
25131.1Skamil#if defined(TWAIT_HAVE_STATUS)
25141.1Skamil	int status;
25151.1Skamil#endif
25161.1Skamil
25171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25191.1Skamil	if (child == 0) {
25201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25221.1Skamil
25231.1Skamil		lookup_me = magic;
25241.1Skamil
25251.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25261.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25271.1Skamil
25281.13Schristos		DPRINTF("Before exiting of the child process\n");
25291.1Skamil		_exit(exitval);
25301.1Skamil	}
25311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25321.1Skamil
25331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25351.1Skamil
25361.1Skamil	validate_status_stopped(status, sigval);
25371.1Skamil
25381.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
25391.1Skamil	    child, getpid());
25401.1Skamil	errno = 0;
25411.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
25421.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25431.1Skamil
25441.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
25451.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
25461.1Skamil
25471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25481.1Skamil	    "without signal to be sent\n");
25491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25501.1Skamil
25511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25531.1Skamil
25541.1Skamil	validate_status_exited(status, exitval);
25551.1Skamil
25561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25581.1Skamil}
25591.1Skamil
25601.1SkamilATF_TC(read_d2);
25611.1SkamilATF_TC_HEAD(read_d2, tc)
25621.1Skamil{
25631.1Skamil	atf_tc_set_md_var(tc, "descr",
25641.1Skamil	    "Verify PT_READ_D called twice");
25651.1Skamil}
25661.1Skamil
25671.1SkamilATF_TC_BODY(read_d2, tc)
25681.1Skamil{
25691.1Skamil	const int exitval = 5;
25701.1Skamil	const int sigval = SIGSTOP;
25711.1Skamil	pid_t child, wpid;
25721.1Skamil	int lookup_me1 = 0;
25731.1Skamil	int lookup_me2 = 0;
25741.1Skamil	const int magic1 = (int)random();
25751.1Skamil	const int magic2 = (int)random();
25761.1Skamil#if defined(TWAIT_HAVE_STATUS)
25771.1Skamil	int status;
25781.1Skamil#endif
25791.1Skamil
25801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25821.1Skamil	if (child == 0) {
25831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25851.1Skamil
25861.1Skamil		lookup_me1 = magic1;
25871.1Skamil		lookup_me2 = magic2;
25881.1Skamil
25891.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25901.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25911.1Skamil
25921.13Schristos		DPRINTF("Before exiting of the child process\n");
25931.1Skamil		_exit(exitval);
25941.1Skamil	}
25951.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25961.1Skamil
25971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25991.1Skamil
26001.1Skamil	validate_status_stopped(status, sigval);
26011.1Skamil
26021.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26031.1Skamil	    child, getpid());
26041.1Skamil	errno = 0;
26051.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26061.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26071.1Skamil
26081.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26091.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26101.1Skamil
26111.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26121.1Skamil	    child, getpid());
26131.1Skamil	errno = 0;
26141.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26151.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26161.1Skamil
26171.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26181.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26191.1Skamil
26201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26211.1Skamil	    "without signal to be sent\n");
26221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26231.1Skamil
26241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26261.1Skamil
26271.1Skamil	validate_status_exited(status, exitval);
26281.1Skamil
26291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26311.1Skamil}
26321.1Skamil
26331.1SkamilATF_TC(read_d3);
26341.1SkamilATF_TC_HEAD(read_d3, tc)
26351.1Skamil{
26361.1Skamil	atf_tc_set_md_var(tc, "descr",
26371.1Skamil	    "Verify PT_READ_D called three times");
26381.1Skamil}
26391.1Skamil
26401.1SkamilATF_TC_BODY(read_d3, tc)
26411.1Skamil{
26421.1Skamil	const int exitval = 5;
26431.1Skamil	const int sigval = SIGSTOP;
26441.1Skamil	pid_t child, wpid;
26451.1Skamil	int lookup_me1 = 0;
26461.1Skamil	int lookup_me2 = 0;
26471.1Skamil	int lookup_me3 = 0;
26481.1Skamil	const int magic1 = (int)random();
26491.1Skamil	const int magic2 = (int)random();
26501.1Skamil	const int magic3 = (int)random();
26511.1Skamil#if defined(TWAIT_HAVE_STATUS)
26521.1Skamil	int status;
26531.1Skamil#endif
26541.1Skamil
26551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26571.1Skamil	if (child == 0) {
26581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26601.1Skamil
26611.1Skamil		lookup_me1 = magic1;
26621.1Skamil		lookup_me2 = magic2;
26631.1Skamil		lookup_me3 = magic3;
26641.1Skamil
26651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26671.1Skamil
26681.13Schristos		DPRINTF("Before exiting of the child process\n");
26691.1Skamil		_exit(exitval);
26701.1Skamil	}
26711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26721.1Skamil
26731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26751.1Skamil
26761.1Skamil	validate_status_stopped(status, sigval);
26771.1Skamil
26781.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26791.1Skamil	    child, getpid());
26801.1Skamil	errno = 0;
26811.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26821.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26831.1Skamil
26841.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26851.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26861.1Skamil
26871.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26881.1Skamil	    child, getpid());
26891.1Skamil	errno = 0;
26901.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26911.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26921.1Skamil
26931.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26941.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26951.1Skamil
26961.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
26971.1Skamil	    child, getpid());
26981.1Skamil	errno = 0;
26991.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27001.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27011.1Skamil
27021.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27031.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27041.1Skamil
27051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27061.1Skamil	    "without signal to be sent\n");
27071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27081.1Skamil
27091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27111.1Skamil
27121.1Skamil	validate_status_exited(status, exitval);
27131.1Skamil
27141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27161.1Skamil}
27171.1Skamil
27181.1SkamilATF_TC(read_d4);
27191.1SkamilATF_TC_HEAD(read_d4, tc)
27201.1Skamil{
27211.1Skamil	atf_tc_set_md_var(tc, "descr",
27221.1Skamil	    "Verify PT_READ_D called four times");
27231.1Skamil}
27241.1Skamil
27251.1SkamilATF_TC_BODY(read_d4, tc)
27261.1Skamil{
27271.1Skamil	const int exitval = 5;
27281.1Skamil	const int sigval = SIGSTOP;
27291.1Skamil	pid_t child, wpid;
27301.1Skamil	int lookup_me1 = 0;
27311.1Skamil	int lookup_me2 = 0;
27321.1Skamil	int lookup_me3 = 0;
27331.1Skamil	int lookup_me4 = 0;
27341.1Skamil	const int magic1 = (int)random();
27351.1Skamil	const int magic2 = (int)random();
27361.1Skamil	const int magic3 = (int)random();
27371.1Skamil	const int magic4 = (int)random();
27381.1Skamil#if defined(TWAIT_HAVE_STATUS)
27391.1Skamil	int status;
27401.1Skamil#endif
27411.1Skamil
27421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27441.1Skamil	if (child == 0) {
27451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27471.1Skamil
27481.1Skamil		lookup_me1 = magic1;
27491.1Skamil		lookup_me2 = magic2;
27501.1Skamil		lookup_me3 = magic3;
27511.1Skamil		lookup_me4 = magic4;
27521.1Skamil
27531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27551.1Skamil
27561.13Schristos		DPRINTF("Before exiting of the child process\n");
27571.1Skamil		_exit(exitval);
27581.1Skamil	}
27591.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27601.1Skamil
27611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27631.1Skamil
27641.1Skamil	validate_status_stopped(status, sigval);
27651.1Skamil
27661.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
27671.1Skamil	    child, getpid());
27681.1Skamil	errno = 0;
27691.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
27701.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27711.1Skamil
27721.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27731.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27741.1Skamil
27751.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27761.1Skamil	    child, getpid());
27771.1Skamil	errno = 0;
27781.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27791.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27801.1Skamil
27811.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27821.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27831.1Skamil
27841.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27851.1Skamil	    child, getpid());
27861.1Skamil	errno = 0;
27871.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27881.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27891.1Skamil
27901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27911.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27921.1Skamil
27931.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
27941.1Skamil	    child, getpid());
27951.1Skamil	errno = 0;
27961.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
27971.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27981.1Skamil
27991.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
28001.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
28011.1Skamil
28021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28031.1Skamil	    "without signal to be sent\n");
28041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28051.1Skamil
28061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28081.1Skamil
28091.1Skamil	validate_status_exited(status, exitval);
28101.1Skamil
28111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28131.1Skamil}
28141.1Skamil
28151.1SkamilATF_TC(write_d1);
28161.1SkamilATF_TC_HEAD(write_d1, tc)
28171.1Skamil{
28181.1Skamil	atf_tc_set_md_var(tc, "descr",
28191.1Skamil	    "Verify PT_WRITE_D called once");
28201.1Skamil}
28211.1Skamil
28221.1SkamilATF_TC_BODY(write_d1, tc)
28231.1Skamil{
28241.1Skamil	const int exitval = 5;
28251.1Skamil	const int sigval = SIGSTOP;
28261.1Skamil	pid_t child, wpid;
28271.1Skamil	int lookup_me = 0;
28281.1Skamil	const int magic = (int)random();
28291.1Skamil#if defined(TWAIT_HAVE_STATUS)
28301.1Skamil	int status;
28311.1Skamil#endif
28321.1Skamil
28331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28351.1Skamil	if (child == 0) {
28361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28381.1Skamil
28391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28411.1Skamil
28421.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
28431.1Skamil
28441.13Schristos		DPRINTF("Before exiting of the child process\n");
28451.1Skamil		_exit(exitval);
28461.1Skamil	}
28471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28481.1Skamil
28491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28511.1Skamil
28521.1Skamil	validate_status_stopped(status, sigval);
28531.1Skamil
28541.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
28551.1Skamil	    child, getpid());
28561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
28571.1Skamil
28581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28591.1Skamil	    "without signal to be sent\n");
28601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28611.1Skamil
28621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28641.1Skamil
28651.1Skamil	validate_status_exited(status, exitval);
28661.1Skamil
28671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28691.1Skamil}
28701.1Skamil
28711.1SkamilATF_TC(write_d2);
28721.1SkamilATF_TC_HEAD(write_d2, tc)
28731.1Skamil{
28741.1Skamil	atf_tc_set_md_var(tc, "descr",
28751.1Skamil	    "Verify PT_WRITE_D called twice");
28761.1Skamil}
28771.1Skamil
28781.1SkamilATF_TC_BODY(write_d2, tc)
28791.1Skamil{
28801.1Skamil	const int exitval = 5;
28811.1Skamil	const int sigval = SIGSTOP;
28821.1Skamil	pid_t child, wpid;
28831.1Skamil	int lookup_me1 = 0;
28841.1Skamil	int lookup_me2 = 0;
28851.1Skamil	const int magic1 = (int)random();
28861.1Skamil	const int magic2 = (int)random();
28871.1Skamil#if defined(TWAIT_HAVE_STATUS)
28881.1Skamil	int status;
28891.1Skamil#endif
28901.1Skamil
28911.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28921.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28931.1Skamil	if (child == 0) {
28941.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28951.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28961.1Skamil
28971.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28981.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28991.1Skamil
29001.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29011.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29021.1Skamil
29031.13Schristos		DPRINTF("Before exiting of the child process\n");
29041.1Skamil		_exit(exitval);
29051.1Skamil	}
29061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29071.1Skamil
29081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29101.1Skamil
29111.1Skamil	validate_status_stopped(status, sigval);
29121.1Skamil
29131.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29141.1Skamil	    child, getpid());
29151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29161.1Skamil
29171.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29181.1Skamil	    child, getpid());
29191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29201.1Skamil
29211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29221.1Skamil	    "without signal to be sent\n");
29231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29241.1Skamil
29251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29271.1Skamil
29281.1Skamil	validate_status_exited(status, exitval);
29291.1Skamil
29301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29321.1Skamil}
29331.1Skamil
29341.1SkamilATF_TC(write_d3);
29351.1SkamilATF_TC_HEAD(write_d3, tc)
29361.1Skamil{
29371.1Skamil	atf_tc_set_md_var(tc, "descr",
29381.1Skamil	    "Verify PT_WRITE_D called three times");
29391.1Skamil}
29401.1Skamil
29411.1SkamilATF_TC_BODY(write_d3, tc)
29421.1Skamil{
29431.1Skamil	const int exitval = 5;
29441.1Skamil	const int sigval = SIGSTOP;
29451.1Skamil	pid_t child, wpid;
29461.1Skamil	int lookup_me1 = 0;
29471.1Skamil	int lookup_me2 = 0;
29481.1Skamil	int lookup_me3 = 0;
29491.1Skamil	const int magic1 = (int)random();
29501.1Skamil	const int magic2 = (int)random();
29511.1Skamil	const int magic3 = (int)random();
29521.1Skamil#if defined(TWAIT_HAVE_STATUS)
29531.1Skamil	int status;
29541.1Skamil#endif
29551.1Skamil
29561.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29571.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29581.1Skamil	if (child == 0) {
29591.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29601.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29611.1Skamil
29621.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29631.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29641.1Skamil
29651.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29661.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29671.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
29681.1Skamil
29691.13Schristos		DPRINTF("Before exiting of the child process\n");
29701.1Skamil		_exit(exitval);
29711.1Skamil	}
29721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29731.1Skamil
29741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29761.1Skamil
29771.1Skamil	validate_status_stopped(status, sigval);
29781.1Skamil
29791.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29801.1Skamil	    child, getpid());
29811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29821.1Skamil
29831.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29841.1Skamil	    child, getpid());
29851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29861.1Skamil
29871.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
29881.1Skamil	    child, getpid());
29891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
29901.1Skamil
29911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29921.1Skamil	    "without signal to be sent\n");
29931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29941.1Skamil
29951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29971.1Skamil
29981.1Skamil	validate_status_exited(status, exitval);
29991.1Skamil
30001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30021.1Skamil}
30031.1Skamil
30041.1SkamilATF_TC(write_d4);
30051.1SkamilATF_TC_HEAD(write_d4, tc)
30061.1Skamil{
30071.1Skamil	atf_tc_set_md_var(tc, "descr",
30081.1Skamil	    "Verify PT_WRITE_D called four times");
30091.1Skamil}
30101.1Skamil
30111.1SkamilATF_TC_BODY(write_d4, tc)
30121.1Skamil{
30131.1Skamil	const int exitval = 5;
30141.1Skamil	const int sigval = SIGSTOP;
30151.1Skamil	pid_t child, wpid;
30161.1Skamil	int lookup_me1 = 0;
30171.1Skamil	int lookup_me2 = 0;
30181.1Skamil	int lookup_me3 = 0;
30191.1Skamil	int lookup_me4 = 0;
30201.1Skamil	const int magic1 = (int)random();
30211.1Skamil	const int magic2 = (int)random();
30221.1Skamil	const int magic3 = (int)random();
30231.1Skamil	const int magic4 = (int)random();
30241.1Skamil#if defined(TWAIT_HAVE_STATUS)
30251.1Skamil	int status;
30261.1Skamil#endif
30271.1Skamil
30281.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30291.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30301.1Skamil	if (child == 0) {
30311.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30321.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30331.1Skamil
30341.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30351.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30361.1Skamil
30371.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
30381.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
30391.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
30401.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
30411.1Skamil
30421.13Schristos		DPRINTF("Before exiting of the child process\n");
30431.1Skamil		_exit(exitval);
30441.1Skamil	}
30451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30461.1Skamil
30471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30491.1Skamil
30501.1Skamil	validate_status_stopped(status, sigval);
30511.1Skamil
30521.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
30531.1Skamil	    child, getpid());
30541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
30551.1Skamil
30561.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30571.1Skamil	    child, getpid());
30581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30591.1Skamil
30601.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30611.1Skamil	    child, getpid());
30621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30631.1Skamil
30641.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
30651.1Skamil	    child, getpid());
30661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
30671.1Skamil
30681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30691.1Skamil	    "without signal to be sent\n");
30701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30711.1Skamil
30721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30741.1Skamil
30751.1Skamil	validate_status_exited(status, exitval);
30761.1Skamil
30771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30791.1Skamil}
30801.1Skamil
30811.1SkamilATF_TC(io_read_d_write_d_handshake1);
30821.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
30831.1Skamil{
30841.1Skamil	atf_tc_set_md_var(tc, "descr",
30851.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
30861.1Skamil}
30871.1Skamil
30881.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
30891.1Skamil{
30901.1Skamil	const int exitval = 5;
30911.1Skamil	const int sigval = SIGSTOP;
30921.1Skamil	pid_t child, wpid;
30931.1Skamil	uint8_t lookup_me_fromtracee = 0;
30941.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
30951.1Skamil	uint8_t lookup_me_totracee = 0;
30961.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
30971.1Skamil	struct ptrace_io_desc io_fromtracee = {
30981.1Skamil		.piod_op = PIOD_READ_D,
30991.1Skamil		.piod_offs = &lookup_me_fromtracee,
31001.1Skamil		.piod_addr = &lookup_me_fromtracee,
31011.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31021.1Skamil	};
31031.1Skamil	struct ptrace_io_desc io_totracee = {
31041.1Skamil		.piod_op = PIOD_WRITE_D,
31051.1Skamil		.piod_offs = &lookup_me_totracee,
31061.1Skamil		.piod_addr = &lookup_me_totracee,
31071.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31081.1Skamil	};
31091.1Skamil#if defined(TWAIT_HAVE_STATUS)
31101.1Skamil	int status;
31111.1Skamil#endif
31121.1Skamil
31131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31151.1Skamil	if (child == 0) {
31161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31181.1Skamil
31191.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31201.1Skamil
31211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31231.1Skamil
31241.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31251.1Skamil
31261.13Schristos		DPRINTF("Before exiting of the child process\n");
31271.1Skamil		_exit(exitval);
31281.1Skamil	}
31291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31301.1Skamil
31311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31331.1Skamil
31341.1Skamil	validate_status_stopped(status, sigval);
31351.1Skamil
31361.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31371.1Skamil	    child, getpid());
31381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
31391.1Skamil
31401.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31411.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
31421.1Skamil	    magic_fromtracee);
31431.1Skamil
31441.1Skamil	lookup_me_totracee = magic_totracee;
31451.1Skamil
31461.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
31471.1Skamil	    child, getpid());
31481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
31491.1Skamil
31501.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
31511.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
31521.1Skamil	    magic_totracee);
31531.1Skamil
31541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31551.1Skamil	    "without signal to be sent\n");
31561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31571.1Skamil
31581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31601.1Skamil
31611.1Skamil	validate_status_exited(status, exitval);
31621.1Skamil
31631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31651.1Skamil}
31661.1Skamil
31671.1SkamilATF_TC(io_read_d_write_d_handshake2);
31681.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
31691.1Skamil{
31701.1Skamil	atf_tc_set_md_var(tc, "descr",
31711.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
31721.1Skamil}
31731.1Skamil
31741.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
31751.1Skamil{
31761.1Skamil	const int exitval = 5;
31771.1Skamil	const int sigval = SIGSTOP;
31781.1Skamil	pid_t child, wpid;
31791.1Skamil	uint8_t lookup_me_fromtracee = 0;
31801.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31811.1Skamil	uint8_t lookup_me_totracee = 0;
31821.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31831.1Skamil	struct ptrace_io_desc io_fromtracee = {
31841.1Skamil		.piod_op = PIOD_READ_D,
31851.1Skamil		.piod_offs = &lookup_me_fromtracee,
31861.1Skamil		.piod_addr = &lookup_me_fromtracee,
31871.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31881.1Skamil	};
31891.1Skamil	struct ptrace_io_desc io_totracee = {
31901.1Skamil		.piod_op = PIOD_WRITE_D,
31911.1Skamil		.piod_offs = &lookup_me_totracee,
31921.1Skamil		.piod_addr = &lookup_me_totracee,
31931.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31941.1Skamil	};
31951.1Skamil#if defined(TWAIT_HAVE_STATUS)
31961.1Skamil	int status;
31971.1Skamil#endif
31981.1Skamil
31991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32011.1Skamil	if (child == 0) {
32021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32041.1Skamil
32051.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32061.1Skamil
32071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32091.1Skamil
32101.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32111.1Skamil
32121.13Schristos		DPRINTF("Before exiting of the child process\n");
32131.1Skamil		_exit(exitval);
32141.1Skamil	}
32151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32161.1Skamil
32171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32191.1Skamil
32201.1Skamil	validate_status_stopped(status, sigval);
32211.1Skamil
32221.1Skamil	lookup_me_totracee = magic_totracee;
32231.1Skamil
32241.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
32251.1Skamil	    child, getpid());
32261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
32271.1Skamil
32281.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
32291.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
32301.1Skamil	    magic_totracee);
32311.1Skamil
32321.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32331.1Skamil	    child, getpid());
32341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
32351.1Skamil
32361.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32371.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
32381.1Skamil	    magic_fromtracee);
32391.1Skamil
32401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32411.1Skamil	    "without signal to be sent\n");
32421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32431.1Skamil
32441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32461.1Skamil
32471.1Skamil	validate_status_exited(status, exitval);
32481.1Skamil
32491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32511.1Skamil}
32521.1Skamil
32531.1SkamilATF_TC(read_d_write_d_handshake1);
32541.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
32551.1Skamil{
32561.1Skamil	atf_tc_set_md_var(tc, "descr",
32571.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
32581.1Skamil}
32591.1Skamil
32601.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
32611.1Skamil{
32621.1Skamil	const int exitval = 5;
32631.1Skamil	const int sigval = SIGSTOP;
32641.1Skamil	pid_t child, wpid;
32651.1Skamil	int lookup_me_fromtracee = 0;
32661.1Skamil	const int magic_fromtracee = (int)random();
32671.1Skamil	int lookup_me_totracee = 0;
32681.1Skamil	const int magic_totracee = (int)random();
32691.1Skamil#if defined(TWAIT_HAVE_STATUS)
32701.1Skamil	int status;
32711.1Skamil#endif
32721.1Skamil
32731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32751.1Skamil	if (child == 0) {
32761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32781.1Skamil
32791.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32801.1Skamil
32811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32831.1Skamil
32841.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32851.1Skamil
32861.13Schristos		DPRINTF("Before exiting of the child process\n");
32871.1Skamil		_exit(exitval);
32881.1Skamil	}
32891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32901.1Skamil
32911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32931.1Skamil
32941.1Skamil	validate_status_stopped(status, sigval);
32951.1Skamil
32961.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32971.1Skamil	    child, getpid());
32981.1Skamil	errno = 0;
32991.1Skamil	lookup_me_fromtracee =
33001.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33011.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33021.1Skamil
33031.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33041.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33051.1Skamil	    magic_fromtracee);
33061.1Skamil
33071.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33081.1Skamil	    child, getpid());
33091.1Skamil	ATF_REQUIRE
33101.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33111.1Skamil	    != -1);
33121.1Skamil
33131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33141.1Skamil	    "without signal to be sent\n");
33151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33161.1Skamil
33171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33191.1Skamil
33201.1Skamil	validate_status_exited(status, exitval);
33211.1Skamil
33221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33231.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33241.1Skamil}
33251.1Skamil
33261.1SkamilATF_TC(read_d_write_d_handshake2);
33271.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
33281.1Skamil{
33291.1Skamil	atf_tc_set_md_var(tc, "descr",
33301.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
33311.1Skamil}
33321.1Skamil
33331.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
33341.1Skamil{
33351.1Skamil	const int exitval = 5;
33361.1Skamil	const int sigval = SIGSTOP;
33371.1Skamil	pid_t child, wpid;
33381.1Skamil	int lookup_me_fromtracee = 0;
33391.1Skamil	const int magic_fromtracee = (int)random();
33401.1Skamil	int lookup_me_totracee = 0;
33411.1Skamil	const int magic_totracee = (int)random();
33421.1Skamil#if defined(TWAIT_HAVE_STATUS)
33431.1Skamil	int status;
33441.1Skamil#endif
33451.1Skamil
33461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33481.1Skamil	if (child == 0) {
33491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33511.1Skamil
33521.1Skamil		lookup_me_fromtracee = magic_fromtracee;
33531.1Skamil
33541.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33551.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33561.1Skamil
33571.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33581.1Skamil
33591.13Schristos		DPRINTF("Before exiting of the child process\n");
33601.1Skamil		_exit(exitval);
33611.1Skamil	}
33621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33631.1Skamil
33641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33661.1Skamil
33671.1Skamil	validate_status_stopped(status, sigval);
33681.1Skamil
33691.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33701.1Skamil	    child, getpid());
33711.1Skamil	ATF_REQUIRE
33721.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33731.1Skamil	    != -1);
33741.1Skamil
33751.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33761.1Skamil	    child, getpid());
33771.1Skamil	errno = 0;
33781.1Skamil	lookup_me_fromtracee =
33791.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33801.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33811.1Skamil
33821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33831.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33841.1Skamil	    magic_fromtracee);
33851.1Skamil
33861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33871.1Skamil	    "without signal to be sent\n");
33881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33891.1Skamil
33901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33921.1Skamil
33931.1Skamil	validate_status_exited(status, exitval);
33941.1Skamil
33951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33971.1Skamil}
33981.1Skamil
33991.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
34001.1Skamilstatic int __used
34011.1Skamildummy_fn1(int a, int b, int c, int d)
34021.1Skamil{
34031.1Skamil
34041.1Skamil	a *= 1;
34051.1Skamil	b += 2;
34061.1Skamil	c -= 3;
34071.1Skamil	d /= 4;
34081.1Skamil
34091.1Skamil	return a + b * c - d;
34101.1Skamil}
34111.1Skamil
34121.1Skamilstatic int __used
34131.1Skamildummy_fn2(int a, int b, int c, int d)
34141.1Skamil{
34151.1Skamil
34161.1Skamil	a *= 4;
34171.1Skamil	b += 3;
34181.1Skamil	c -= 2;
34191.1Skamil	d /= 1;
34201.1Skamil
34211.1Skamil	return a + b * c - d;
34221.1Skamil}
34231.1Skamil
34241.1Skamilstatic int __used
34251.1Skamildummy_fn3(int a, int b, int c, int d)
34261.1Skamil{
34271.1Skamil
34281.1Skamil	a *= 10;
34291.1Skamil	b += 20;
34301.1Skamil	c -= 30;
34311.1Skamil	d /= 40;
34321.1Skamil
34331.1Skamil	return a + b * c - d;
34341.1Skamil}
34351.1Skamil
34361.1Skamilstatic int __used
34371.1Skamildummy_fn4(int a, int b, int c, int d)
34381.1Skamil{
34391.1Skamil
34401.1Skamil	a *= 40;
34411.1Skamil	b += 30;
34421.1Skamil	c -= 20;
34431.1Skamil	d /= 10;
34441.1Skamil
34451.1Skamil	return a + b * c - d;
34461.1Skamil}
34471.1Skamil
34481.1SkamilATF_TC(io_read_i1);
34491.1SkamilATF_TC_HEAD(io_read_i1, tc)
34501.1Skamil{
34511.1Skamil	atf_tc_set_md_var(tc, "descr",
34521.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
34531.1Skamil}
34541.1Skamil
34551.1SkamilATF_TC_BODY(io_read_i1, tc)
34561.1Skamil{
34571.1Skamil	const int exitval = 5;
34581.1Skamil	const int sigval = SIGSTOP;
34591.1Skamil	pid_t child, wpid;
34601.1Skamil	uint8_t lookup_me = 0;
34611.1Skamil	uint8_t magic;
34621.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34631.1Skamil	struct ptrace_io_desc io = {
34641.1Skamil		.piod_op = PIOD_READ_I,
34651.1Skamil		.piod_offs = dummy_fn1,
34661.1Skamil		.piod_addr = &lookup_me,
34671.1Skamil		.piod_len = sizeof(lookup_me)
34681.1Skamil	};
34691.1Skamil#if defined(TWAIT_HAVE_STATUS)
34701.1Skamil	int status;
34711.1Skamil#endif
34721.1Skamil
34731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34751.1Skamil	if (child == 0) {
34761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34781.1Skamil
34791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34811.1Skamil
34821.13Schristos		DPRINTF("Before exiting of the child process\n");
34831.1Skamil		_exit(exitval);
34841.1Skamil	}
34851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34861.1Skamil
34871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34891.1Skamil
34901.1Skamil	validate_status_stopped(status, sigval);
34911.1Skamil
34921.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34931.1Skamil	    child, getpid());
34941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34951.1Skamil
34961.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34971.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
34981.1Skamil
34991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35001.1Skamil	    "without signal to be sent\n");
35011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35021.1Skamil
35031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35051.1Skamil
35061.1Skamil	validate_status_exited(status, exitval);
35071.1Skamil
35081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35101.1Skamil}
35111.1Skamil
35121.1SkamilATF_TC(io_read_i2);
35131.1SkamilATF_TC_HEAD(io_read_i2, tc)
35141.1Skamil{
35151.1Skamil	atf_tc_set_md_var(tc, "descr",
35161.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
35171.1Skamil}
35181.1Skamil
35191.1SkamilATF_TC_BODY(io_read_i2, tc)
35201.1Skamil{
35211.1Skamil	const int exitval = 5;
35221.1Skamil	const int sigval = SIGSTOP;
35231.1Skamil	pid_t child, wpid;
35241.1Skamil	uint16_t lookup_me = 0;
35251.1Skamil	uint16_t magic;
35261.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35271.1Skamil	struct ptrace_io_desc io = {
35281.1Skamil		.piod_op = PIOD_READ_I,
35291.1Skamil		.piod_offs = dummy_fn1,
35301.1Skamil		.piod_addr = &lookup_me,
35311.1Skamil		.piod_len = sizeof(lookup_me)
35321.1Skamil	};
35331.1Skamil#if defined(TWAIT_HAVE_STATUS)
35341.1Skamil	int status;
35351.1Skamil#endif
35361.1Skamil
35371.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35381.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35391.1Skamil	if (child == 0) {
35401.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35411.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35421.1Skamil
35431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35451.1Skamil
35461.13Schristos		DPRINTF("Before exiting of the child process\n");
35471.1Skamil		_exit(exitval);
35481.1Skamil	}
35491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35501.1Skamil
35511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35531.1Skamil
35541.1Skamil	validate_status_stopped(status, sigval);
35551.1Skamil
35561.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35571.1Skamil	    child, getpid());
35581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35591.1Skamil
35601.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35611.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
35621.1Skamil
35631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35641.1Skamil	    "without signal to be sent\n");
35651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35661.1Skamil
35671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35691.1Skamil
35701.1Skamil	validate_status_exited(status, exitval);
35711.1Skamil
35721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35741.1Skamil}
35751.1Skamil
35761.1SkamilATF_TC(io_read_i3);
35771.1SkamilATF_TC_HEAD(io_read_i3, tc)
35781.1Skamil{
35791.1Skamil	atf_tc_set_md_var(tc, "descr",
35801.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
35811.1Skamil}
35821.1Skamil
35831.1SkamilATF_TC_BODY(io_read_i3, tc)
35841.1Skamil{
35851.1Skamil	const int exitval = 5;
35861.1Skamil	const int sigval = SIGSTOP;
35871.1Skamil	pid_t child, wpid;
35881.1Skamil	uint32_t lookup_me = 0;
35891.1Skamil	uint32_t magic;
35901.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35911.1Skamil	struct ptrace_io_desc io = {
35921.1Skamil		.piod_op = PIOD_READ_I,
35931.1Skamil		.piod_offs = dummy_fn1,
35941.1Skamil		.piod_addr = &lookup_me,
35951.1Skamil		.piod_len = sizeof(lookup_me)
35961.1Skamil	};
35971.1Skamil#if defined(TWAIT_HAVE_STATUS)
35981.1Skamil	int status;
35991.1Skamil#endif
36001.1Skamil
36011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36031.1Skamil	if (child == 0) {
36041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36061.1Skamil
36071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36091.1Skamil
36101.13Schristos		DPRINTF("Before exiting of the child process\n");
36111.1Skamil		_exit(exitval);
36121.1Skamil	}
36131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36141.1Skamil
36151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36171.1Skamil
36181.1Skamil	validate_status_stopped(status, sigval);
36191.1Skamil
36201.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36211.1Skamil	    child, getpid());
36221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36231.1Skamil
36241.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36251.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
36261.1Skamil
36271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36281.1Skamil	    "without signal to be sent\n");
36291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36301.1Skamil
36311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36331.1Skamil
36341.1Skamil	validate_status_exited(status, exitval);
36351.1Skamil
36361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36381.1Skamil}
36391.1Skamil
36401.1SkamilATF_TC(io_read_i4);
36411.1SkamilATF_TC_HEAD(io_read_i4, tc)
36421.1Skamil{
36431.1Skamil	atf_tc_set_md_var(tc, "descr",
36441.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
36451.1Skamil}
36461.1Skamil
36471.1SkamilATF_TC_BODY(io_read_i4, tc)
36481.1Skamil{
36491.1Skamil	const int exitval = 5;
36501.1Skamil	const int sigval = SIGSTOP;
36511.1Skamil	pid_t child, wpid;
36521.1Skamil	uint64_t lookup_me = 0;
36531.1Skamil	uint64_t magic;
36541.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36551.1Skamil	struct ptrace_io_desc io = {
36561.1Skamil		.piod_op = PIOD_READ_I,
36571.1Skamil		.piod_offs = dummy_fn1,
36581.1Skamil		.piod_addr = &lookup_me,
36591.1Skamil		.piod_len = sizeof(lookup_me)
36601.1Skamil	};
36611.1Skamil#if defined(TWAIT_HAVE_STATUS)
36621.1Skamil	int status;
36631.1Skamil#endif
36641.1Skamil
36651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36671.1Skamil	if (child == 0) {
36681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36701.1Skamil
36711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36731.1Skamil
36741.13Schristos		DPRINTF("Before exiting of the child process\n");
36751.1Skamil		_exit(exitval);
36761.1Skamil	}
36771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36781.1Skamil
36791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36811.1Skamil
36821.1Skamil	validate_status_stopped(status, sigval);
36831.1Skamil
36841.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36851.1Skamil	    child, getpid());
36861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36871.1Skamil
36881.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36891.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
36901.1Skamil
36911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36921.1Skamil	    "without signal to be sent\n");
36931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36941.1Skamil
36951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36971.1Skamil
36981.1Skamil	validate_status_exited(status, exitval);
36991.1Skamil
37001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37021.1Skamil}
37031.1Skamil
37041.1SkamilATF_TC(read_i1);
37051.1SkamilATF_TC_HEAD(read_i1, tc)
37061.1Skamil{
37071.1Skamil	atf_tc_set_md_var(tc, "descr",
37081.1Skamil	    "Verify PT_READ_I called once");
37091.1Skamil}
37101.1Skamil
37111.1SkamilATF_TC_BODY(read_i1, tc)
37121.1Skamil{
37131.1Skamil	const int exitval = 5;
37141.1Skamil	const int sigval = SIGSTOP;
37151.1Skamil	pid_t child, wpid;
37161.1Skamil	int lookup_me = 0;
37171.1Skamil	int magic;
37181.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
37191.1Skamil#if defined(TWAIT_HAVE_STATUS)
37201.1Skamil	int status;
37211.1Skamil#endif
37221.1Skamil
37231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37251.1Skamil	if (child == 0) {
37261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37281.1Skamil
37291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37311.1Skamil
37321.13Schristos		DPRINTF("Before exiting of the child process\n");
37331.1Skamil		_exit(exitval);
37341.1Skamil	}
37351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37361.1Skamil
37371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37391.1Skamil
37401.1Skamil	validate_status_stopped(status, sigval);
37411.1Skamil
37421.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37431.1Skamil	    child, getpid());
37441.1Skamil	errno = 0;
37451.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
37461.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37471.1Skamil
37481.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37491.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
37501.1Skamil
37511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37521.1Skamil	    "without signal to be sent\n");
37531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37541.1Skamil
37551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37571.1Skamil
37581.1Skamil	validate_status_exited(status, exitval);
37591.1Skamil
37601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37621.1Skamil}
37631.1Skamil
37641.1SkamilATF_TC(read_i2);
37651.1SkamilATF_TC_HEAD(read_i2, tc)
37661.1Skamil{
37671.1Skamil	atf_tc_set_md_var(tc, "descr",
37681.1Skamil	    "Verify PT_READ_I called twice");
37691.1Skamil}
37701.1Skamil
37711.1SkamilATF_TC_BODY(read_i2, tc)
37721.1Skamil{
37731.1Skamil	const int exitval = 5;
37741.1Skamil	const int sigval = SIGSTOP;
37751.1Skamil	pid_t child, wpid;
37761.1Skamil	int lookup_me1 = 0;
37771.1Skamil	int lookup_me2 = 0;
37781.1Skamil	int magic1;
37791.1Skamil	int magic2;
37801.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37811.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37821.1Skamil#if defined(TWAIT_HAVE_STATUS)
37831.1Skamil	int status;
37841.1Skamil#endif
37851.1Skamil
37861.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37871.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37881.1Skamil	if (child == 0) {
37891.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37901.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37911.1Skamil
37921.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37931.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37941.1Skamil
37951.13Schristos		DPRINTF("Before exiting of the child process\n");
37961.1Skamil		_exit(exitval);
37971.1Skamil	}
37981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37991.1Skamil
38001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38021.1Skamil
38031.1Skamil	validate_status_stopped(status, sigval);
38041.1Skamil
38051.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38061.1Skamil	    child, getpid());
38071.1Skamil	errno = 0;
38081.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38091.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38101.1Skamil
38111.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38121.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38131.1Skamil
38141.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38151.1Skamil	    child, getpid());
38161.1Skamil	errno = 0;
38171.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38181.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38191.1Skamil
38201.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38211.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38221.1Skamil
38231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38241.1Skamil	    "without signal to be sent\n");
38251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38261.1Skamil
38271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38291.1Skamil
38301.1Skamil	validate_status_exited(status, exitval);
38311.1Skamil
38321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38341.1Skamil}
38351.1Skamil
38361.1SkamilATF_TC(read_i3);
38371.1SkamilATF_TC_HEAD(read_i3, tc)
38381.1Skamil{
38391.1Skamil	atf_tc_set_md_var(tc, "descr",
38401.1Skamil	    "Verify PT_READ_I called three times");
38411.1Skamil}
38421.1Skamil
38431.1SkamilATF_TC_BODY(read_i3, tc)
38441.1Skamil{
38451.1Skamil	const int exitval = 5;
38461.1Skamil	const int sigval = SIGSTOP;
38471.1Skamil	pid_t child, wpid;
38481.1Skamil	int lookup_me1 = 0;
38491.1Skamil	int lookup_me2 = 0;
38501.1Skamil	int lookup_me3 = 0;
38511.1Skamil	int magic1;
38521.1Skamil	int magic2;
38531.1Skamil	int magic3;
38541.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
38551.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
38561.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
38571.1Skamil#if defined(TWAIT_HAVE_STATUS)
38581.1Skamil	int status;
38591.1Skamil#endif
38601.1Skamil
38611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38631.1Skamil	if (child == 0) {
38641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38661.1Skamil
38671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38691.1Skamil
38701.13Schristos		DPRINTF("Before exiting of the child process\n");
38711.1Skamil		_exit(exitval);
38721.1Skamil	}
38731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38741.1Skamil
38751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38771.1Skamil
38781.1Skamil	validate_status_stopped(status, sigval);
38791.1Skamil
38801.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38811.1Skamil	    child, getpid());
38821.1Skamil	errno = 0;
38831.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38841.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38851.1Skamil
38861.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38871.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38881.1Skamil
38891.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38901.1Skamil	    child, getpid());
38911.1Skamil	errno = 0;
38921.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38931.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38941.1Skamil
38951.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38961.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38971.1Skamil
38981.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
38991.1Skamil	    child, getpid());
39001.1Skamil	errno = 0;
39011.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39021.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39031.1Skamil
39041.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39051.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39061.1Skamil
39071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39081.1Skamil	    "without signal to be sent\n");
39091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39101.1Skamil
39111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39131.1Skamil
39141.1Skamil	validate_status_exited(status, exitval);
39151.1Skamil
39161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39181.1Skamil}
39191.1Skamil
39201.1SkamilATF_TC(read_i4);
39211.1SkamilATF_TC_HEAD(read_i4, tc)
39221.1Skamil{
39231.1Skamil	atf_tc_set_md_var(tc, "descr",
39241.1Skamil	    "Verify PT_READ_I called four times");
39251.1Skamil}
39261.1Skamil
39271.1SkamilATF_TC_BODY(read_i4, tc)
39281.1Skamil{
39291.1Skamil	const int exitval = 5;
39301.1Skamil	const int sigval = SIGSTOP;
39311.1Skamil	pid_t child, wpid;
39321.1Skamil	int lookup_me1 = 0;
39331.1Skamil	int lookup_me2 = 0;
39341.1Skamil	int lookup_me3 = 0;
39351.1Skamil	int lookup_me4 = 0;
39361.1Skamil	int magic1;
39371.1Skamil	int magic2;
39381.1Skamil	int magic3;
39391.1Skamil	int magic4;
39401.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
39411.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
39421.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
39431.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
39441.1Skamil#if defined(TWAIT_HAVE_STATUS)
39451.1Skamil	int status;
39461.1Skamil#endif
39471.1Skamil
39481.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39491.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39501.1Skamil	if (child == 0) {
39511.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39521.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39531.1Skamil
39541.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39551.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39561.1Skamil
39571.13Schristos		DPRINTF("Before exiting of the child process\n");
39581.1Skamil		_exit(exitval);
39591.1Skamil	}
39601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39611.1Skamil
39621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39641.1Skamil
39651.1Skamil	validate_status_stopped(status, sigval);
39661.1Skamil
39671.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
39681.1Skamil	    child, getpid());
39691.1Skamil	errno = 0;
39701.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39711.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39721.1Skamil
39731.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39741.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39751.1Skamil
39761.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39771.1Skamil	    child, getpid());
39781.1Skamil	errno = 0;
39791.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39801.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39811.1Skamil
39821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39831.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39841.1Skamil
39851.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39861.1Skamil	    child, getpid());
39871.1Skamil	errno = 0;
39881.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39891.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39901.1Skamil
39911.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39921.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39931.1Skamil
39941.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
39951.1Skamil	    child, getpid());
39961.1Skamil	errno = 0;
39971.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
39981.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39991.1Skamil
40001.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
40011.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
40021.1Skamil
40031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40041.1Skamil	    "without signal to be sent\n");
40051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40061.1Skamil
40071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40091.1Skamil
40101.1Skamil	validate_status_exited(status, exitval);
40111.1Skamil
40121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40141.1Skamil}
40151.1Skamil
40161.1Skamil#if defined(HAVE_GPREGS)
40171.1SkamilATF_TC(regs1);
40181.1SkamilATF_TC_HEAD(regs1, tc)
40191.1Skamil{
40201.1Skamil	atf_tc_set_md_var(tc, "descr",
40211.1Skamil	    "Verify plain PT_GETREGS call without further steps");
40221.1Skamil}
40231.1Skamil
40241.1SkamilATF_TC_BODY(regs1, tc)
40251.1Skamil{
40261.1Skamil	const int exitval = 5;
40271.1Skamil	const int sigval = SIGSTOP;
40281.1Skamil	pid_t child, wpid;
40291.1Skamil#if defined(TWAIT_HAVE_STATUS)
40301.1Skamil	int status;
40311.1Skamil#endif
40321.1Skamil	struct reg r;
40331.1Skamil
40341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40361.1Skamil	if (child == 0) {
40371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40391.1Skamil
40401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40421.1Skamil
40431.13Schristos		DPRINTF("Before exiting of the child process\n");
40441.1Skamil		_exit(exitval);
40451.1Skamil	}
40461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40471.1Skamil
40481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40501.1Skamil
40511.1Skamil	validate_status_stopped(status, sigval);
40521.1Skamil
40531.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40551.1Skamil
40561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40571.1Skamil	    "without signal to be sent\n");
40581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40591.1Skamil
40601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40621.1Skamil
40631.1Skamil	validate_status_exited(status, exitval);
40641.1Skamil
40651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40671.1Skamil}
40681.1Skamil#endif
40691.1Skamil
40701.1Skamil#if defined(HAVE_GPREGS)
40711.1SkamilATF_TC(regs2);
40721.1SkamilATF_TC_HEAD(regs2, tc)
40731.1Skamil{
40741.1Skamil	atf_tc_set_md_var(tc, "descr",
40751.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
40761.1Skamil}
40771.1Skamil
40781.1SkamilATF_TC_BODY(regs2, tc)
40791.1Skamil{
40801.1Skamil	const int exitval = 5;
40811.1Skamil	const int sigval = SIGSTOP;
40821.1Skamil	pid_t child, wpid;
40831.1Skamil#if defined(TWAIT_HAVE_STATUS)
40841.1Skamil	int status;
40851.1Skamil#endif
40861.1Skamil	struct reg r;
40871.1Skamil
40881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40901.1Skamil	if (child == 0) {
40911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40931.1Skamil
40941.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40951.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40961.1Skamil
40971.13Schristos		DPRINTF("Before exiting of the child process\n");
40981.1Skamil		_exit(exitval);
40991.1Skamil	}
41001.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
41061.1Skamil
41071.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41091.1Skamil
41101.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
41111.1Skamil
41121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41131.1Skamil	    "without signal to be sent\n");
41141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41151.1Skamil
41161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41181.1Skamil
41191.1Skamil	validate_status_exited(status, exitval);
41201.1Skamil
41211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41231.1Skamil}
41241.1Skamil#endif
41251.1Skamil
41261.1Skamil#if defined(HAVE_GPREGS)
41271.1SkamilATF_TC(regs3);
41281.1SkamilATF_TC_HEAD(regs3, tc)
41291.1Skamil{
41301.1Skamil	atf_tc_set_md_var(tc, "descr",
41311.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
41321.1Skamil}
41331.1Skamil
41341.1SkamilATF_TC_BODY(regs3, tc)
41351.1Skamil{
41361.1Skamil	const int exitval = 5;
41371.1Skamil	const int sigval = SIGSTOP;
41381.1Skamil	pid_t child, wpid;
41391.1Skamil#if defined(TWAIT_HAVE_STATUS)
41401.1Skamil	int status;
41411.1Skamil#endif
41421.1Skamil	struct reg r;
41431.1Skamil
41441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41461.1Skamil	if (child == 0) {
41471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41491.1Skamil
41501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41521.1Skamil
41531.13Schristos		DPRINTF("Before exiting of the child process\n");
41541.1Skamil		_exit(exitval);
41551.1Skamil	}
41561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
41621.1Skamil
41631.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41651.1Skamil
41661.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
41671.1Skamil
41681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41691.1Skamil	    "without signal to be sent\n");
41701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41711.1Skamil
41721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41741.1Skamil
41751.1Skamil	validate_status_exited(status, exitval);
41761.1Skamil
41771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41791.1Skamil}
41801.1Skamil#endif
41811.1Skamil
41821.1Skamil#if defined(HAVE_GPREGS)
41831.1SkamilATF_TC(regs4);
41841.1SkamilATF_TC_HEAD(regs4, tc)
41851.1Skamil{
41861.1Skamil	atf_tc_set_md_var(tc, "descr",
41871.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
41881.1Skamil}
41891.1Skamil
41901.1SkamilATF_TC_BODY(regs4, tc)
41911.1Skamil{
41921.1Skamil	const int exitval = 5;
41931.1Skamil	const int sigval = SIGSTOP;
41941.1Skamil	pid_t child, wpid;
41951.1Skamil#if defined(TWAIT_HAVE_STATUS)
41961.1Skamil	int status;
41971.1Skamil#endif
41981.1Skamil	struct reg r;
41991.1Skamil
42001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42021.1Skamil	if (child == 0) {
42031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42051.1Skamil
42061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42081.1Skamil
42091.13Schristos		DPRINTF("Before exiting of the child process\n");
42101.1Skamil		_exit(exitval);
42111.1Skamil	}
42121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
42181.1Skamil
42191.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42211.1Skamil
42221.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
42231.1Skamil
42241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42251.1Skamil	    "without signal to be sent\n");
42261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42271.1Skamil
42281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42301.1Skamil
42311.1Skamil	validate_status_exited(status, exitval);
42321.1Skamil
42331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42351.1Skamil}
42361.1Skamil#endif
42371.1Skamil
42381.1Skamil#if defined(HAVE_GPREGS)
42391.1SkamilATF_TC(regs5);
42401.1SkamilATF_TC_HEAD(regs5, tc)
42411.1Skamil{
42421.1Skamil	atf_tc_set_md_var(tc, "descr",
42431.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
42441.1Skamil}
42451.1Skamil
42461.1SkamilATF_TC_BODY(regs5, tc)
42471.1Skamil{
42481.1Skamil	const int exitval = 5;
42491.1Skamil	const int sigval = SIGSTOP;
42501.1Skamil	pid_t child, wpid;
42511.1Skamil#if defined(TWAIT_HAVE_STATUS)
42521.1Skamil	int status;
42531.1Skamil#endif
42541.1Skamil	struct reg r;
42551.1Skamil
42561.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42571.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42581.1Skamil	if (child == 0) {
42591.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42601.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42611.1Skamil
42621.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42631.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42641.1Skamil
42651.13Schristos		DPRINTF("Before exiting of the child process\n");
42661.1Skamil		_exit(exitval);
42671.1Skamil	}
42681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42691.1Skamil
42701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42721.1Skamil
42731.1Skamil	validate_status_stopped(status, sigval);
42741.1Skamil
42751.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42771.1Skamil
42781.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
42791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42801.1Skamil
42811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42821.1Skamil	    "without signal to be sent\n");
42831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42841.1Skamil
42851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42871.1Skamil
42881.1Skamil	validate_status_exited(status, exitval);
42891.1Skamil
42901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42921.1Skamil}
42931.1Skamil#endif
42941.1Skamil
42951.1Skamil#if defined(HAVE_FPREGS)
42961.1SkamilATF_TC(fpregs1);
42971.1SkamilATF_TC_HEAD(fpregs1, tc)
42981.1Skamil{
42991.1Skamil	atf_tc_set_md_var(tc, "descr",
43001.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
43011.1Skamil}
43021.1Skamil
43031.1SkamilATF_TC_BODY(fpregs1, tc)
43041.1Skamil{
43051.1Skamil	const int exitval = 5;
43061.1Skamil	const int sigval = SIGSTOP;
43071.1Skamil	pid_t child, wpid;
43081.1Skamil#if defined(TWAIT_HAVE_STATUS)
43091.1Skamil	int status;
43101.1Skamil#endif
43111.1Skamil	struct fpreg r;
43121.1Skamil
43131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43151.1Skamil	if (child == 0) {
43161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43181.1Skamil
43191.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43201.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43211.1Skamil
43221.13Schristos		DPRINTF("Before exiting of the child process\n");
43231.1Skamil		_exit(exitval);
43241.1Skamil	}
43251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43261.1Skamil
43271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43291.1Skamil
43301.1Skamil	validate_status_stopped(status, sigval);
43311.1Skamil
43321.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43341.1Skamil
43351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43361.1Skamil	    "without signal to be sent\n");
43371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43381.1Skamil
43391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43411.1Skamil
43421.1Skamil	validate_status_exited(status, exitval);
43431.1Skamil
43441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43461.1Skamil}
43471.1Skamil#endif
43481.1Skamil
43491.1Skamil#if defined(HAVE_FPREGS)
43501.1SkamilATF_TC(fpregs2);
43511.1SkamilATF_TC_HEAD(fpregs2, tc)
43521.1Skamil{
43531.1Skamil	atf_tc_set_md_var(tc, "descr",
43541.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
43551.1Skamil	    "regs");
43561.1Skamil}
43571.1Skamil
43581.1SkamilATF_TC_BODY(fpregs2, tc)
43591.1Skamil{
43601.1Skamil	const int exitval = 5;
43611.1Skamil	const int sigval = SIGSTOP;
43621.1Skamil	pid_t child, wpid;
43631.1Skamil#if defined(TWAIT_HAVE_STATUS)
43641.1Skamil	int status;
43651.1Skamil#endif
43661.1Skamil	struct fpreg r;
43671.1Skamil
43681.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43691.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43701.1Skamil	if (child == 0) {
43711.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43721.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43731.1Skamil
43741.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43751.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43761.1Skamil
43771.13Schristos		DPRINTF("Before exiting of the child process\n");
43781.1Skamil		_exit(exitval);
43791.1Skamil	}
43801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43811.1Skamil
43821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43841.1Skamil
43851.1Skamil	validate_status_stopped(status, sigval);
43861.1Skamil
43871.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43891.1Skamil
43901.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
43911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
43921.1Skamil
43931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43941.1Skamil	    "without signal to be sent\n");
43951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43961.1Skamil
43971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43991.1Skamil
44001.1Skamil	validate_status_exited(status, exitval);
44011.1Skamil
44021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44041.1Skamil}
44051.1Skamil#endif
44061.1Skamil
44071.1Skamil#if defined(PT_STEP)
44081.1Skamilstatic void
44091.2Skamilptrace_step(int N, int setstep)
44101.1Skamil{
44111.1Skamil	const int exitval = 5;
44121.1Skamil	const int sigval = SIGSTOP;
44131.1Skamil	pid_t child, wpid;
44141.1Skamil#if defined(TWAIT_HAVE_STATUS)
44151.1Skamil	int status;
44161.1Skamil#endif
44171.1Skamil	int happy;
44181.1Skamil
44191.1Skamil#if defined(__arm__)
44201.1Skamil	/* PT_STEP not supported on arm 32-bit */
44211.1Skamil	atf_tc_expect_fail("PR kern/52119");
44221.1Skamil#endif
44231.1Skamil
44241.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44251.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44261.1Skamil	if (child == 0) {
44271.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44281.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44291.1Skamil
44301.1Skamil		happy = check_happy(999);
44311.1Skamil
44321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44341.1Skamil
44351.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
44361.1Skamil
44371.13Schristos		DPRINTF("Before exiting of the child process\n");
44381.1Skamil		_exit(exitval);
44391.1Skamil	}
44401.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44411.1Skamil
44421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44441.1Skamil
44451.1Skamil	validate_status_stopped(status, sigval);
44461.1Skamil
44471.1Skamil	while (N --> 0) {
44481.2Skamil		if (setstep) {
44491.13Schristos			DPRINTF("Before resuming the child process where it "
44501.2Skamil			    "left off and without signal to be sent (use "
44511.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
44521.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
44531.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
44541.2Skamil			    != -1);
44551.2Skamil		} else {
44561.13Schristos			DPRINTF("Before resuming the child process where it "
44571.2Skamil			    "left off and without signal to be sent (use "
44581.2Skamil			    "PT_STEP)\n");
44591.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
44601.2Skamil			    != -1);
44611.2Skamil		}
44621.1Skamil
44631.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44641.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
44651.1Skamil		    child);
44661.1Skamil
44671.1Skamil		validate_status_stopped(status, SIGTRAP);
44681.2Skamil
44691.2Skamil		if (setstep) {
44701.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
44711.2Skamil		}
44721.1Skamil	}
44731.1Skamil
44741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44751.1Skamil	    "without signal to be sent\n");
44761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44771.1Skamil
44781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44801.1Skamil
44811.1Skamil	validate_status_exited(status, exitval);
44821.1Skamil
44831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44841.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44851.1Skamil}
44861.1Skamil#endif
44871.1Skamil
44881.1Skamil#if defined(PT_STEP)
44891.1SkamilATF_TC(step1);
44901.1SkamilATF_TC_HEAD(step1, tc)
44911.1Skamil{
44921.1Skamil	atf_tc_set_md_var(tc, "descr",
44931.1Skamil	    "Verify single PT_STEP call");
44941.1Skamil}
44951.1Skamil
44961.1SkamilATF_TC_BODY(step1, tc)
44971.1Skamil{
44981.2Skamil	ptrace_step(1, 0);
44991.1Skamil}
45001.1Skamil#endif
45011.1Skamil
45021.1Skamil#if defined(PT_STEP)
45031.1SkamilATF_TC(step2);
45041.1SkamilATF_TC_HEAD(step2, tc)
45051.1Skamil{
45061.1Skamil	atf_tc_set_md_var(tc, "descr",
45071.1Skamil	    "Verify PT_STEP called twice");
45081.1Skamil}
45091.1Skamil
45101.1SkamilATF_TC_BODY(step2, tc)
45111.1Skamil{
45121.2Skamil	ptrace_step(2, 0);
45131.1Skamil}
45141.1Skamil#endif
45151.1Skamil
45161.1Skamil#if defined(PT_STEP)
45171.1SkamilATF_TC(step3);
45181.1SkamilATF_TC_HEAD(step3, tc)
45191.1Skamil{
45201.1Skamil	atf_tc_set_md_var(tc, "descr",
45211.1Skamil	    "Verify PT_STEP called three times");
45221.1Skamil}
45231.1Skamil
45241.1SkamilATF_TC_BODY(step3, tc)
45251.1Skamil{
45261.2Skamil	ptrace_step(3, 0);
45271.1Skamil}
45281.1Skamil#endif
45291.1Skamil
45301.1Skamil#if defined(PT_STEP)
45311.1SkamilATF_TC(step4);
45321.1SkamilATF_TC_HEAD(step4, tc)
45331.1Skamil{
45341.1Skamil	atf_tc_set_md_var(tc, "descr",
45351.1Skamil	    "Verify PT_STEP called four times");
45361.1Skamil}
45371.1Skamil
45381.1SkamilATF_TC_BODY(step4, tc)
45391.1Skamil{
45401.2Skamil	ptrace_step(4, 0);
45411.2Skamil}
45421.2Skamil#endif
45431.2Skamil
45441.2Skamil#if defined(PT_STEP)
45451.2SkamilATF_TC(setstep1);
45461.2SkamilATF_TC_HEAD(setstep1, tc)
45471.2Skamil{
45481.2Skamil	atf_tc_set_md_var(tc, "descr",
45491.2Skamil	    "Verify single PT_SETSTEP call");
45501.2Skamil}
45511.2Skamil
45521.2SkamilATF_TC_BODY(setstep1, tc)
45531.2Skamil{
45541.2Skamil	ptrace_step(1, 1);
45551.2Skamil}
45561.2Skamil#endif
45571.2Skamil
45581.2Skamil#if defined(PT_STEP)
45591.2SkamilATF_TC(setstep2);
45601.2SkamilATF_TC_HEAD(setstep2, tc)
45611.2Skamil{
45621.2Skamil	atf_tc_set_md_var(tc, "descr",
45631.2Skamil	    "Verify PT_SETSTEP called twice");
45641.2Skamil}
45651.2Skamil
45661.2SkamilATF_TC_BODY(setstep2, tc)
45671.2Skamil{
45681.2Skamil	ptrace_step(2, 1);
45691.2Skamil}
45701.2Skamil#endif
45711.2Skamil
45721.2Skamil#if defined(PT_STEP)
45731.2SkamilATF_TC(setstep3);
45741.2SkamilATF_TC_HEAD(setstep3, tc)
45751.2Skamil{
45761.2Skamil	atf_tc_set_md_var(tc, "descr",
45771.2Skamil	    "Verify PT_SETSTEP called three times");
45781.2Skamil}
45791.2Skamil
45801.2SkamilATF_TC_BODY(setstep3, tc)
45811.2Skamil{
45821.2Skamil	ptrace_step(3, 1);
45831.2Skamil}
45841.2Skamil#endif
45851.2Skamil
45861.2Skamil#if defined(PT_STEP)
45871.2SkamilATF_TC(setstep4);
45881.2SkamilATF_TC_HEAD(setstep4, tc)
45891.2Skamil{
45901.2Skamil	atf_tc_set_md_var(tc, "descr",
45911.2Skamil	    "Verify PT_SETSTEP called four times");
45921.2Skamil}
45931.2Skamil
45941.2SkamilATF_TC_BODY(setstep4, tc)
45951.2Skamil{
45961.2Skamil	ptrace_step(4, 1);
45971.1Skamil}
45981.1Skamil#endif
45991.1Skamil
46001.1SkamilATF_TC(kill1);
46011.1SkamilATF_TC_HEAD(kill1, tc)
46021.1Skamil{
46031.1Skamil	atf_tc_set_md_var(tc, "descr",
46041.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
46051.1Skamil}
46061.1Skamil
46071.1SkamilATF_TC_BODY(kill1, tc)
46081.1Skamil{
46091.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
46101.1Skamil	pid_t child, wpid;
46111.1Skamil#if defined(TWAIT_HAVE_STATUS)
46121.1Skamil	int status;
46131.1Skamil#endif
46141.1Skamil
46151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46171.1Skamil	if (child == 0) {
46181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46201.1Skamil
46211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46231.1Skamil
46241.1Skamil		/* NOTREACHED */
46251.1Skamil		FORKEE_ASSERTX(0 &&
46261.1Skamil		    "Child should be terminated by a signal from its parent");
46271.1Skamil	}
46281.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46291.1Skamil
46301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46321.1Skamil
46331.1Skamil	validate_status_stopped(status, sigval);
46341.1Skamil
46351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46361.1Skamil	    "without signal to be sent\n");
46371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
46381.1Skamil
46391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46411.1Skamil
46421.1Skamil	validate_status_signaled(status, sigsent, 0);
46431.1Skamil
46441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46461.1Skamil}
46471.1Skamil
46481.1SkamilATF_TC(kill2);
46491.1SkamilATF_TC_HEAD(kill2, tc)
46501.1Skamil{
46511.1Skamil	atf_tc_set_md_var(tc, "descr",
46521.1Skamil	    "Verify that PT_KILL terminates child");
46531.1Skamil}
46541.1Skamil
46551.1SkamilATF_TC_BODY(kill2, tc)
46561.1Skamil{
46571.1Skamil	const int sigval = SIGSTOP;
46581.1Skamil	pid_t child, wpid;
46591.1Skamil#if defined(TWAIT_HAVE_STATUS)
46601.1Skamil	int status;
46611.1Skamil#endif
46621.1Skamil
46631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46651.1Skamil	if (child == 0) {
46661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46681.1Skamil
46691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46711.1Skamil
46721.1Skamil		/* NOTREACHED */
46731.1Skamil		FORKEE_ASSERTX(0 &&
46741.1Skamil		    "Child should be terminated by a signal from its parent");
46751.1Skamil	}
46761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46771.1Skamil
46781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46801.1Skamil
46811.1Skamil	validate_status_stopped(status, sigval);
46821.1Skamil
46831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46841.1Skamil	    "without signal to be sent\n");
46851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
46861.1Skamil
46871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46891.1Skamil
46901.1Skamil	validate_status_signaled(status, SIGKILL, 0);
46911.1Skamil
46921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46931.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46941.1Skamil}
46951.1Skamil
46961.1SkamilATF_TC(lwpinfo1);
46971.1SkamilATF_TC_HEAD(lwpinfo1, tc)
46981.1Skamil{
46991.1Skamil	atf_tc_set_md_var(tc, "descr",
47001.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
47011.1Skamil}
47021.1Skamil
47031.1SkamilATF_TC_BODY(lwpinfo1, tc)
47041.1Skamil{
47051.1Skamil	const int exitval = 5;
47061.1Skamil	const int sigval = SIGSTOP;
47071.1Skamil	pid_t child, wpid;
47081.1Skamil#if defined(TWAIT_HAVE_STATUS)
47091.1Skamil	int status;
47101.1Skamil#endif
47111.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47121.1Skamil
47131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47151.1Skamil	if (child == 0) {
47161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47181.1Skamil
47191.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47201.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47211.1Skamil
47221.13Schristos		DPRINTF("Before exiting of the child process\n");
47231.1Skamil		_exit(exitval);
47241.1Skamil	}
47251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47261.1Skamil
47271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47291.1Skamil
47301.1Skamil	validate_status_stopped(status, sigval);
47311.1Skamil
47321.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47341.1Skamil
47351.13Schristos	DPRINTF("Assert that there exists a thread\n");
47361.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
47371.1Skamil
47381.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
47391.1Skamil	    info.pl_lwpid);
47401.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
47411.1Skamil	    "Received event %d != expected event %d",
47421.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
47431.1Skamil
47441.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47461.1Skamil
47471.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
47481.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
47491.1Skamil
47501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47511.1Skamil	    "without signal to be sent\n");
47521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47531.1Skamil
47541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47561.1Skamil
47571.1Skamil	validate_status_exited(status, exitval);
47581.1Skamil
47591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47611.1Skamil}
47621.1Skamil
47631.1Skamil#if defined(TWAIT_HAVE_PID)
47641.1SkamilATF_TC(lwpinfo2);
47651.1SkamilATF_TC_HEAD(lwpinfo2, tc)
47661.1Skamil{
47671.1Skamil	atf_tc_set_md_var(tc, "descr",
47681.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
47691.1Skamil	    "tracer)");
47701.1Skamil}
47711.1Skamil
47721.1SkamilATF_TC_BODY(lwpinfo2, tc)
47731.1Skamil{
47741.1Skamil	struct msg_fds parent_tracee, parent_tracer;
47751.1Skamil	const int exitval_tracee = 5;
47761.1Skamil	const int exitval_tracer = 10;
47771.1Skamil	pid_t tracee, tracer, wpid;
47781.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
47791.1Skamil#if defined(TWAIT_HAVE_STATUS)
47801.1Skamil	int status;
47811.1Skamil#endif
47821.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47831.1Skamil
47841.13Schristos	DPRINTF("Spawn tracee\n");
47851.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
47861.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
47871.1Skamil	tracee = atf_utils_fork();
47881.1Skamil	if (tracee == 0) {
47891.1Skamil
47901.1Skamil		/* Wait for message from the parent */
47911.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
47921.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
47931.1Skamil
47941.1Skamil		_exit(exitval_tracee);
47951.1Skamil	}
47961.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
47971.1Skamil
47981.13Schristos	DPRINTF("Spawn debugger\n");
47991.1Skamil	tracer = atf_utils_fork();
48001.1Skamil	if (tracer == 0) {
48011.1Skamil		/* No IPC to communicate with the child */
48021.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
48031.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
48041.1Skamil
48051.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
48061.1Skamil		FORKEE_REQUIRE_SUCCESS(
48071.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48081.1Skamil
48091.1Skamil		forkee_status_stopped(status, SIGSTOP);
48101.1Skamil
48111.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48121.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48131.1Skamil		    != -1);
48141.1Skamil
48151.13Schristos		DPRINTF("Assert that there exists a thread\n");
48161.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
48171.1Skamil
48181.13Schristos		DPRINTF("Assert that lwp thread %d received event "
48191.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
48201.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
48211.1Skamil
48221.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48231.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48241.1Skamil		    != -1);
48251.1Skamil
48261.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
48271.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
48281.1Skamil
48291.1Skamil		/* Resume tracee with PT_CONTINUE */
48301.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
48311.1Skamil
48321.1Skamil		/* Inform parent that tracer has attached to tracee */
48331.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
48341.1Skamil		/* Wait for parent */
48351.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
48361.1Skamil
48371.1Skamil		/* Wait for tracee and assert that it exited */
48381.1Skamil		FORKEE_REQUIRE_SUCCESS(
48391.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48401.1Skamil
48411.1Skamil		forkee_status_exited(status, exitval_tracee);
48421.1Skamil
48431.13Schristos		DPRINTF("Before exiting of the tracer process\n");
48441.1Skamil		_exit(exitval_tracer);
48451.1Skamil	}
48461.1Skamil
48471.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
48481.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
48491.1Skamil
48501.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
48511.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
48521.1Skamil
48531.13Schristos	DPRINTF("Detect that tracee is zombie\n");
48541.1Skamil	await_zombie(tracee);
48551.1Skamil
48561.13Schristos	DPRINTF("Assert that there is no status about tracee - "
48571.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
48581.1Skamil	TWAIT_REQUIRE_SUCCESS(
48591.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
48601.1Skamil
48611.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
48621.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
48631.1Skamil
48641.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
48651.1Skamil	    TWAIT_FNAME);
48661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
48671.1Skamil	    tracer);
48681.1Skamil
48691.1Skamil	validate_status_exited(status, exitval_tracer);
48701.1Skamil
48711.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
48721.1Skamil	    TWAIT_FNAME);
48731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
48741.1Skamil	    tracee);
48751.1Skamil
48761.1Skamil	validate_status_exited(status, exitval_tracee);
48771.1Skamil
48781.1Skamil	msg_close(&parent_tracer);
48791.1Skamil	msg_close(&parent_tracee);
48801.1Skamil}
48811.1Skamil#endif
48821.1Skamil
48831.1SkamilATF_TC(siginfo1);
48841.1SkamilATF_TC_HEAD(siginfo1, tc)
48851.1Skamil{
48861.1Skamil	atf_tc_set_md_var(tc, "descr",
48871.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
48881.1Skamil}
48891.1Skamil
48901.1SkamilATF_TC_BODY(siginfo1, tc)
48911.1Skamil{
48921.1Skamil	const int exitval = 5;
48931.1Skamil	const int sigval = SIGTRAP;
48941.1Skamil	pid_t child, wpid;
48951.1Skamil#if defined(TWAIT_HAVE_STATUS)
48961.1Skamil	int status;
48971.1Skamil#endif
48981.1Skamil	struct ptrace_siginfo info;
48991.1Skamil	memset(&info, 0, sizeof(info));
49001.1Skamil
49011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49031.1Skamil	if (child == 0) {
49041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49061.1Skamil
49071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49091.1Skamil
49101.13Schristos		DPRINTF("Before exiting of the child process\n");
49111.1Skamil		_exit(exitval);
49121.1Skamil	}
49131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49141.1Skamil
49151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49171.1Skamil
49181.1Skamil	validate_status_stopped(status, sigval);
49191.1Skamil
49201.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49221.1Skamil
49231.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49241.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49251.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49261.1Skamil	    info.psi_siginfo.si_errno);
49271.1Skamil
49281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49291.1Skamil	    "without signal to be sent\n");
49301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49311.1Skamil
49321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49341.1Skamil
49351.1Skamil	validate_status_exited(status, exitval);
49361.1Skamil
49371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49391.1Skamil}
49401.1Skamil
49411.1SkamilATF_TC(siginfo2);
49421.1SkamilATF_TC_HEAD(siginfo2, tc)
49431.1Skamil{
49441.1Skamil	atf_tc_set_md_var(tc, "descr",
49451.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
49461.1Skamil	    "modification of SIGINT from tracee");
49471.1Skamil}
49481.1Skamil
49491.1Skamilstatic int siginfo2_caught = 0;
49501.1Skamil
49511.1Skamilstatic void
49521.1Skamilsiginfo2_sighandler(int sig)
49531.1Skamil{
49541.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
49551.1Skamil
49561.1Skamil	++siginfo2_caught;
49571.1Skamil}
49581.1Skamil
49591.1SkamilATF_TC_BODY(siginfo2, tc)
49601.1Skamil{
49611.1Skamil	const int exitval = 5;
49621.1Skamil	const int sigval = SIGINT;
49631.1Skamil	pid_t child, wpid;
49641.1Skamil	struct sigaction sa;
49651.1Skamil#if defined(TWAIT_HAVE_STATUS)
49661.1Skamil	int status;
49671.1Skamil#endif
49681.1Skamil	struct ptrace_siginfo info;
49691.1Skamil	memset(&info, 0, sizeof(info));
49701.1Skamil
49711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49731.1Skamil	if (child == 0) {
49741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49761.1Skamil
49771.1Skamil		sa.sa_handler = siginfo2_sighandler;
49781.1Skamil		sa.sa_flags = SA_SIGINFO;
49791.1Skamil		sigemptyset(&sa.sa_mask);
49801.1Skamil
49811.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
49821.1Skamil
49831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49851.1Skamil
49861.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
49871.1Skamil
49881.13Schristos		DPRINTF("Before exiting of the child process\n");
49891.1Skamil		_exit(exitval);
49901.1Skamil	}
49911.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49921.1Skamil
49931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49951.1Skamil
49961.1Skamil	validate_status_stopped(status, sigval);
49971.1Skamil
49981.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50001.1Skamil
50011.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50021.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50031.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50041.1Skamil	    info.psi_siginfo.si_errno);
50051.1Skamil
50061.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50081.1Skamil
50091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50101.1Skamil	    "without signal to be sent\n");
50111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
50121.1Skamil
50131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50151.1Skamil
50161.1Skamil	validate_status_exited(status, exitval);
50171.1Skamil
50181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50201.1Skamil}
50211.1Skamil
50221.1SkamilATF_TC(siginfo3);
50231.1SkamilATF_TC_HEAD(siginfo3, tc)
50241.1Skamil{
50251.1Skamil	atf_tc_set_md_var(tc, "descr",
50261.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
50271.1Skamil	    "setting signal to new value");
50281.1Skamil}
50291.1Skamil
50301.1Skamilstatic int siginfo3_caught = 0;
50311.1Skamil
50321.1Skamilstatic void
50331.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
50341.1Skamil{
50351.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
50361.1Skamil
50371.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
50381.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
50391.1Skamil
50401.1Skamil	++siginfo3_caught;
50411.1Skamil}
50421.1Skamil
50431.1SkamilATF_TC_BODY(siginfo3, tc)
50441.1Skamil{
50451.1Skamil	const int exitval = 5;
50461.1Skamil	const int sigval = SIGINT;
50471.1Skamil	const int sigfaked = SIGTRAP;
50481.1Skamil	const int sicodefaked = TRAP_BRKPT;
50491.1Skamil	pid_t child, wpid;
50501.1Skamil	struct sigaction sa;
50511.1Skamil#if defined(TWAIT_HAVE_STATUS)
50521.1Skamil	int status;
50531.1Skamil#endif
50541.1Skamil	struct ptrace_siginfo info;
50551.1Skamil	memset(&info, 0, sizeof(info));
50561.1Skamil
50571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50591.1Skamil	if (child == 0) {
50601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50621.1Skamil
50631.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
50641.1Skamil		sa.sa_flags = SA_SIGINFO;
50651.1Skamil		sigemptyset(&sa.sa_mask);
50661.1Skamil
50671.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
50681.1Skamil
50691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50711.1Skamil
50721.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
50731.1Skamil
50741.13Schristos		DPRINTF("Before exiting of the child process\n");
50751.1Skamil		_exit(exitval);
50761.1Skamil	}
50771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50781.1Skamil
50791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50811.1Skamil
50821.1Skamil	validate_status_stopped(status, sigval);
50831.1Skamil
50841.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50861.1Skamil
50871.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50881.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50891.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50901.1Skamil	    info.psi_siginfo.si_errno);
50911.1Skamil
50921.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
50931.1Skamil	    sigfaked, sicodefaked);
50941.1Skamil	info.psi_siginfo.si_signo = sigfaked;
50951.1Skamil	info.psi_siginfo.si_code = sicodefaked;
50961.1Skamil
50971.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50991.1Skamil
51001.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51021.1Skamil
51031.13Schristos	DPRINTF("Before checking siginfo_t\n");
51041.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
51051.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
51061.1Skamil
51071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51081.1Skamil	    "without signal to be sent\n");
51091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
51101.1Skamil
51111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51131.1Skamil
51141.1Skamil	validate_status_exited(status, exitval);
51151.1Skamil
51161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51181.1Skamil}
51191.1Skamil
51201.1SkamilATF_TC(siginfo4);
51211.1SkamilATF_TC_HEAD(siginfo4, tc)
51221.1Skamil{
51231.1Skamil	atf_tc_set_md_var(tc, "descr",
51241.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
51251.1Skamil}
51261.1Skamil
51271.1SkamilATF_TC_BODY(siginfo4, tc)
51281.1Skamil{
51291.1Skamil	const int sigval = SIGTRAP;
51301.1Skamil	pid_t child, wpid;
51311.1Skamil#if defined(TWAIT_HAVE_STATUS)
51321.1Skamil	int status;
51331.1Skamil#endif
51341.1Skamil
51351.1Skamil	struct ptrace_siginfo info;
51361.1Skamil	memset(&info, 0, sizeof(info));
51371.1Skamil
51381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51401.1Skamil	if (child == 0) {
51411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51431.1Skamil
51441.13Schristos		DPRINTF("Before calling execve(2) from child\n");
51451.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
51461.1Skamil
51471.1Skamil		FORKEE_ASSERT(0 && "Not reached");
51481.1Skamil	}
51491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51501.1Skamil
51511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51531.1Skamil
51541.1Skamil	validate_status_stopped(status, sigval);
51551.1Skamil
51561.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51581.1Skamil
51591.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51601.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51611.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51621.1Skamil	    info.psi_siginfo.si_errno);
51631.1Skamil
51641.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51651.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
51661.1Skamil
51671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51681.1Skamil	    "without signal to be sent\n");
51691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51701.1Skamil
51711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51731.1Skamil
51741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51761.1Skamil}
51771.1Skamil
51781.1Skamil#if defined(TWAIT_HAVE_PID)
51791.1SkamilATF_TC(siginfo5);
51801.1SkamilATF_TC_HEAD(siginfo5, tc)
51811.1Skamil{
51821.1Skamil	atf_tc_set_md_var(tc, "descr",
51831.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
51841.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
51851.1Skamil}
51861.1Skamil
51871.1SkamilATF_TC_BODY(siginfo5, tc)
51881.1Skamil{
51891.1Skamil	const int exitval = 5;
51901.1Skamil	const int exitval2 = 15;
51911.1Skamil	const int sigval = SIGSTOP;
51921.1Skamil	pid_t child, child2, wpid;
51931.1Skamil#if defined(TWAIT_HAVE_STATUS)
51941.1Skamil	int status;
51951.1Skamil#endif
51961.1Skamil	ptrace_state_t state;
51971.1Skamil	const int slen = sizeof(state);
51981.1Skamil	ptrace_event_t event;
51991.1Skamil	const int elen = sizeof(event);
52001.1Skamil	struct ptrace_siginfo info;
52011.1Skamil
52021.1Skamil	memset(&info, 0, sizeof(info));
52031.1Skamil
52041.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52051.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52061.1Skamil	if (child == 0) {
52071.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52081.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52091.1Skamil
52101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52121.1Skamil
52131.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
52141.1Skamil
52151.1Skamil		if (child2 == 0)
52161.1Skamil			_exit(exitval2);
52171.1Skamil
52181.1Skamil		FORKEE_REQUIRE_SUCCESS
52191.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
52201.1Skamil
52211.1Skamil		forkee_status_exited(status, exitval2);
52221.1Skamil
52231.13Schristos		DPRINTF("Before exiting of the child process\n");
52241.1Skamil		_exit(exitval);
52251.1Skamil	}
52261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52271.1Skamil
52281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52301.1Skamil
52311.1Skamil	validate_status_stopped(status, sigval);
52321.1Skamil
52331.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52351.1Skamil
52361.13Schristos	DPRINTF("Before checking siginfo_t\n");
52371.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
52381.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
52391.1Skamil
52401.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
52411.1Skamil	event.pe_set_event = PTRACE_FORK;
52421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52431.1Skamil
52441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52451.1Skamil	    "without signal to be sent\n");
52461.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
52471.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
52481.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
52491.1Skamil                "state.pe_other_pid=child)\n", child);
52501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52511.1Skamil
52521.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
52531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52541.1Skamil
52551.1Skamil	validate_status_stopped(status, SIGTRAP);
52561.1Skamil
52571.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52591.1Skamil
52601.13Schristos	DPRINTF("Before checking siginfo_t\n");
52611.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52621.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52631.1Skamil
52641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52651.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52661.1Skamil
52671.1Skamil	child2 = state.pe_other_pid;
52681.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
52691.1Skamil
52701.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
52711.1Skamil	    TWAIT_FNAME, child2, child);
52721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52731.1Skamil	    child2);
52741.1Skamil
52751.1Skamil	validate_status_stopped(status, SIGTRAP);
52761.1Skamil
52771.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52791.1Skamil
52801.13Schristos	DPRINTF("Before checking siginfo_t\n");
52811.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52821.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52831.1Skamil
52841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
52851.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52861.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
52871.1Skamil
52881.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
52891.1Skamil	    "without signal to be sent\n");
52901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
52911.1Skamil
52921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52931.1Skamil	    "without signal to be sent\n");
52941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52951.1Skamil
52961.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
52971.1Skamil	    TWAIT_FNAME);
52981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52991.1Skamil	    child2);
53001.1Skamil
53011.1Skamil	validate_status_exited(status, exitval2);
53021.1Skamil
53031.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
53041.1Skamil	    TWAIT_FNAME);
53051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
53061.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
53071.1Skamil
53081.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53091.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
53101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53111.1Skamil
53121.1Skamil	validate_status_stopped(status, SIGCHLD);
53131.1Skamil
53141.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53161.1Skamil
53171.13Schristos	DPRINTF("Before checking siginfo_t\n");
53181.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
53191.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
53201.1Skamil
53211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53221.1Skamil	    "without signal to be sent\n");
53231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53241.1Skamil
53251.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53261.1Skamil	    TWAIT_FNAME);
53271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53281.1Skamil
53291.1Skamil	validate_status_exited(status, exitval);
53301.1Skamil
53311.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53321.1Skamil	    TWAIT_FNAME);
53331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53341.1Skamil}
53351.1Skamil#endif
53361.1Skamil
53371.1Skamil#if defined(PT_STEP)
53381.1SkamilATF_TC(siginfo6);
53391.1SkamilATF_TC_HEAD(siginfo6, tc)
53401.1Skamil{
53411.1Skamil	atf_tc_set_md_var(tc, "descr",
53421.1Skamil	    "Verify single PT_STEP call with signal information check");
53431.1Skamil}
53441.1Skamil
53451.1SkamilATF_TC_BODY(siginfo6, tc)
53461.1Skamil{
53471.1Skamil	const int exitval = 5;
53481.1Skamil	const int sigval = SIGSTOP;
53491.1Skamil	pid_t child, wpid;
53501.1Skamil#if defined(TWAIT_HAVE_STATUS)
53511.1Skamil	int status;
53521.1Skamil#endif
53531.1Skamil	int happy;
53541.1Skamil	struct ptrace_siginfo info;
53551.1Skamil
53561.1Skamil#if defined(__arm__)
53571.1Skamil	/* PT_STEP not supported on arm 32-bit */
53581.1Skamil	atf_tc_expect_fail("PR kern/52119");
53591.1Skamil#endif
53601.1Skamil
53611.1Skamil	memset(&info, 0, sizeof(info));
53621.1Skamil
53631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53651.1Skamil	if (child == 0) {
53661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53681.1Skamil
53691.1Skamil		happy = check_happy(100);
53701.1Skamil
53711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53731.1Skamil
53741.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
53751.1Skamil
53761.13Schristos		DPRINTF("Before exiting of the child process\n");
53771.1Skamil		_exit(exitval);
53781.1Skamil	}
53791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53801.1Skamil
53811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53831.1Skamil
53841.1Skamil	validate_status_stopped(status, sigval);
53851.1Skamil
53861.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53881.1Skamil
53891.13Schristos	DPRINTF("Before checking siginfo_t\n");
53901.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
53911.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
53921.1Skamil
53931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53941.1Skamil	    "without signal to be sent (use PT_STEP)\n");
53951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
53961.1Skamil
53971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53991.1Skamil
54001.1Skamil	validate_status_stopped(status, SIGTRAP);
54011.1Skamil
54021.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
54031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
54041.1Skamil
54051.13Schristos	DPRINTF("Before checking siginfo_t\n");
54061.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
54071.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
54081.1Skamil
54091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54101.1Skamil	    "without signal to be sent\n");
54111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54121.1Skamil
54131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54151.1Skamil
54161.1Skamil	validate_status_exited(status, exitval);
54171.1Skamil
54181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54201.1Skamil}
54211.1Skamil#endif
54221.1Skamil
54231.1Skamilvolatile lwpid_t the_lwp_id = 0;
54241.1Skamil
54251.1Skamilstatic void
54261.1Skamillwp_main_func(void *arg)
54271.1Skamil{
54281.1Skamil	the_lwp_id = _lwp_self();
54291.1Skamil	_lwp_exit();
54301.1Skamil}
54311.1Skamil
54321.1SkamilATF_TC(lwp_create1);
54331.1SkamilATF_TC_HEAD(lwp_create1, tc)
54341.1Skamil{
54351.1Skamil	atf_tc_set_md_var(tc, "descr",
54361.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
54371.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
54381.1Skamil}
54391.1Skamil
54401.1SkamilATF_TC_BODY(lwp_create1, tc)
54411.1Skamil{
54421.1Skamil	const int exitval = 5;
54431.1Skamil	const int sigval = SIGSTOP;
54441.1Skamil	pid_t child, wpid;
54451.1Skamil#if defined(TWAIT_HAVE_STATUS)
54461.1Skamil	int status;
54471.1Skamil#endif
54481.1Skamil	ptrace_state_t state;
54491.1Skamil	const int slen = sizeof(state);
54501.1Skamil	ptrace_event_t event;
54511.1Skamil	const int elen = sizeof(event);
54521.1Skamil	ucontext_t uc;
54531.1Skamil	lwpid_t lid;
54541.1Skamil	static const size_t ssize = 16*1024;
54551.1Skamil	void *stack;
54561.1Skamil
54571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54591.1Skamil	if (child == 0) {
54601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54621.1Skamil
54631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54651.1Skamil
54661.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
54671.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
54681.1Skamil
54691.13Schristos		DPRINTF("Before making context for new lwp in child\n");
54701.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
54711.1Skamil
54721.13Schristos		DPRINTF("Before creating new in child\n");
54731.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
54741.1Skamil
54751.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
54761.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
54771.1Skamil
54781.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
54791.1Skamil		    "are the same\n", lid, the_lwp_id);
54801.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
54811.1Skamil
54821.13Schristos		DPRINTF("Before exiting of the child process\n");
54831.1Skamil		_exit(exitval);
54841.1Skamil	}
54851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54861.1Skamil
54871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54891.1Skamil
54901.1Skamil	validate_status_stopped(status, sigval);
54911.1Skamil
54921.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
54931.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
54941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
54951.1Skamil
54961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54971.1Skamil	    "without signal to be sent\n");
54981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54991.1Skamil
55001.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55011.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55031.1Skamil
55041.1Skamil	validate_status_stopped(status, SIGTRAP);
55051.1Skamil
55061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55071.1Skamil
55081.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
55091.1Skamil
55101.1Skamil	lid = state.pe_lwp;
55111.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
55121.1Skamil
55131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55141.1Skamil	    "without signal to be sent\n");
55151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55161.1Skamil
55171.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
55181.1Skamil	    TWAIT_FNAME);
55191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55201.1Skamil
55211.1Skamil	validate_status_exited(status, exitval);
55221.1Skamil
55231.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
55241.1Skamil	    TWAIT_FNAME);
55251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55261.1Skamil}
55271.1Skamil
55281.1SkamilATF_TC(lwp_exit1);
55291.1SkamilATF_TC_HEAD(lwp_exit1, tc)
55301.1Skamil{
55311.1Skamil	atf_tc_set_md_var(tc, "descr",
55321.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
55331.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
55341.1Skamil}
55351.1Skamil
55361.1SkamilATF_TC_BODY(lwp_exit1, tc)
55371.1Skamil{
55381.1Skamil	const int exitval = 5;
55391.1Skamil	const int sigval = SIGSTOP;
55401.1Skamil	pid_t child, wpid;
55411.1Skamil#if defined(TWAIT_HAVE_STATUS)
55421.1Skamil	int status;
55431.1Skamil#endif
55441.1Skamil	ptrace_state_t state;
55451.1Skamil	const int slen = sizeof(state);
55461.1Skamil	ptrace_event_t event;
55471.1Skamil	const int elen = sizeof(event);
55481.1Skamil	ucontext_t uc;
55491.1Skamil	lwpid_t lid;
55501.1Skamil	static const size_t ssize = 16*1024;
55511.1Skamil	void *stack;
55521.1Skamil
55531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55551.1Skamil	if (child == 0) {
55561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55581.1Skamil
55591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55611.1Skamil
55621.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
55631.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
55641.1Skamil
55651.13Schristos		DPRINTF("Before making context for new lwp in child\n");
55661.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
55671.1Skamil
55681.13Schristos		DPRINTF("Before creating new in child\n");
55691.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
55701.1Skamil
55711.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
55721.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
55731.1Skamil
55741.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
55751.1Skamil		    "are the same\n", lid, the_lwp_id);
55761.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
55771.1Skamil
55781.13Schristos		DPRINTF("Before exiting of the child process\n");
55791.1Skamil		_exit(exitval);
55801.1Skamil	}
55811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55821.1Skamil
55831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55851.1Skamil
55861.1Skamil	validate_status_stopped(status, sigval);
55871.1Skamil
55881.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55891.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
55901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55911.1Skamil
55921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55931.1Skamil	    "without signal to be sent\n");
55941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55951.1Skamil
55961.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55971.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55991.1Skamil
56001.1Skamil	validate_status_stopped(status, SIGTRAP);
56011.1Skamil
56021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
56031.1Skamil
56041.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
56051.1Skamil
56061.1Skamil	lid = state.pe_lwp;
56071.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
56081.1Skamil
56091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56101.1Skamil	    "without signal to be sent\n");
56111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56121.1Skamil
56131.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
56141.1Skamil	    TWAIT_FNAME);
56151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56161.1Skamil
56171.1Skamil	validate_status_exited(status, exitval);
56181.1Skamil
56191.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
56201.1Skamil	    TWAIT_FNAME);
56211.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56221.1Skamil}
56231.1Skamil
56241.1SkamilATF_TC(signal1);
56251.1SkamilATF_TC_HEAD(signal1, tc)
56261.1Skamil{
56271.1Skamil	atf_tc_set_md_var(tc, "descr",
56281.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
56291.1Skamil	    "from catching other signals");
56301.1Skamil}
56311.1Skamil
56321.1SkamilATF_TC_BODY(signal1, tc)
56331.1Skamil{
56341.1Skamil	const int exitval = 5;
56351.1Skamil	const int sigval = SIGSTOP;
56361.1Skamil	const int sigmasked = SIGTRAP;
56371.1Skamil	const int signotmasked = SIGINT;
56381.1Skamil	pid_t child, wpid;
56391.1Skamil#if defined(TWAIT_HAVE_STATUS)
56401.1Skamil	int status;
56411.1Skamil#endif
56421.1Skamil	sigset_t intmask;
56431.1Skamil
56441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56461.1Skamil	if (child == 0) {
56471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56491.1Skamil
56501.1Skamil		sigemptyset(&intmask);
56511.1Skamil		sigaddset(&intmask, sigmasked);
56521.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56531.1Skamil
56541.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56551.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56561.1Skamil
56571.13Schristos		DPRINTF("Before raising %s from child\n",
56581.1Skamil		    strsignal(signotmasked));
56591.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
56601.1Skamil
56611.13Schristos		DPRINTF("Before exiting of the child process\n");
56621.1Skamil		_exit(exitval);
56631.1Skamil	}
56641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56651.1Skamil
56661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56681.1Skamil
56691.1Skamil	validate_status_stopped(status, sigval);
56701.1Skamil
56711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56721.1Skamil	    "without signal to be sent\n");
56731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56741.1Skamil
56751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56771.1Skamil
56781.1Skamil	validate_status_stopped(status, signotmasked);
56791.1Skamil
56801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56811.1Skamil	    "without signal to be sent\n");
56821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56831.1Skamil
56841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56861.1Skamil
56871.1Skamil	validate_status_exited(status, exitval);
56881.1Skamil
56891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56911.1Skamil}
56921.1Skamil
56931.1SkamilATF_TC(signal2);
56941.1SkamilATF_TC_HEAD(signal2, tc)
56951.1Skamil{
56961.1Skamil	atf_tc_set_md_var(tc, "descr",
56971.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
56981.1Skamil	    "catching this raised signal");
56991.1Skamil}
57001.1Skamil
57011.1SkamilATF_TC_BODY(signal2, tc)
57021.1Skamil{
57031.1Skamil	const int exitval = 5;
57041.1Skamil	const int sigval = SIGSTOP;
57051.1Skamil	const int sigmasked = SIGTRAP;
57061.1Skamil	pid_t child, wpid;
57071.1Skamil#if defined(TWAIT_HAVE_STATUS)
57081.1Skamil	int status;
57091.1Skamil#endif
57101.1Skamil	sigset_t intmask;
57111.1Skamil
57121.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57131.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57141.1Skamil	if (child == 0) {
57151.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57161.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57171.1Skamil
57181.1Skamil		sigemptyset(&intmask);
57191.1Skamil		sigaddset(&intmask, sigmasked);
57201.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57211.1Skamil
57221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57241.1Skamil
57251.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
57261.1Skamil		    strsignal(sigmasked));
57271.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
57281.1Skamil
57291.13Schristos		DPRINTF("Before exiting of the child process\n");
57301.1Skamil		_exit(exitval);
57311.1Skamil	}
57321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57331.1Skamil
57341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57361.1Skamil
57371.1Skamil	validate_status_stopped(status, sigval);
57381.1Skamil
57391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57401.1Skamil	    "without signal to be sent\n");
57411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57421.1Skamil
57431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57451.1Skamil
57461.1Skamil	validate_status_exited(status, exitval);
57471.1Skamil
57481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57501.1Skamil}
57511.1Skamil
57521.1SkamilATF_TC(signal3);
57531.1SkamilATF_TC_HEAD(signal3, tc)
57541.1Skamil{
57551.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57561.1Skamil	atf_tc_set_md_var(tc, "descr",
57571.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57581.1Skamil	    "catching software breakpoints");
57591.1Skamil}
57601.1Skamil
57611.1SkamilATF_TC_BODY(signal3, tc)
57621.1Skamil{
57631.1Skamil	const int exitval = 5;
57641.1Skamil	const int sigval = SIGSTOP;
57651.1Skamil	const int sigmasked = SIGTRAP;
57661.1Skamil	pid_t child, wpid;
57671.1Skamil#if defined(TWAIT_HAVE_STATUS)
57681.1Skamil	int status;
57691.1Skamil#endif
57701.1Skamil	sigset_t intmask;
57711.1Skamil
57721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57741.1Skamil	if (child == 0) {
57751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57771.1Skamil
57781.1Skamil		sigemptyset(&intmask);
57791.1Skamil		sigaddset(&intmask, sigmasked);
57801.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57811.1Skamil
57821.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57831.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57841.1Skamil
57851.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
57861.4Skamil
57871.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
57881.4Skamil		PTRACE_BREAKPOINT_ASM;
57891.1Skamil#else
57901.4Skamil		/* port me */
57911.1Skamil#endif
57921.1Skamil
57931.13Schristos		DPRINTF("Before exiting of the child process\n");
57941.1Skamil		_exit(exitval);
57951.1Skamil	}
57961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57971.1Skamil
57981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58001.1Skamil
58011.1Skamil	validate_status_stopped(status, sigval);
58021.1Skamil
58031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58041.1Skamil	    "without signal to be sent\n");
58051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58061.1Skamil
58071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58091.1Skamil
58101.1Skamil	validate_status_stopped(status, sigmasked);
58111.1Skamil
58121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58131.1Skamil	    "without signal to be sent\n");
58141.49Skamil	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
58151.1Skamil
58161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58181.1Skamil
58191.49Skamil	validate_status_signaled(status, SIGKILL, 0);
58201.1Skamil
58211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58231.1Skamil}
58241.1Skamil
58251.1Skamil#if defined(PT_STEP)
58261.1SkamilATF_TC(signal4);
58271.1SkamilATF_TC_HEAD(signal4, tc)
58281.1Skamil{
58291.1Skamil	atf_tc_set_md_var(tc, "descr",
58301.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58311.1Skamil	    "catching single step trap");
58321.1Skamil}
58331.1Skamil
58341.1SkamilATF_TC_BODY(signal4, tc)
58351.1Skamil{
58361.1Skamil	const int exitval = 5;
58371.1Skamil	const int sigval = SIGSTOP;
58381.1Skamil	const int sigmasked = SIGTRAP;
58391.1Skamil	pid_t child, wpid;
58401.1Skamil#if defined(TWAIT_HAVE_STATUS)
58411.1Skamil	int status;
58421.1Skamil#endif
58431.1Skamil	sigset_t intmask;
58441.1Skamil	int happy;
58451.1Skamil
58461.1Skamil#if defined(__arm__)
58471.5Skamil	/* PT_STEP not supported on arm 32-bit */
58481.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
58491.1Skamil#endif
58501.1Skamil
58511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58531.1Skamil	if (child == 0) {
58541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58561.1Skamil
58571.1Skamil		happy = check_happy(100);
58581.1Skamil
58591.1Skamil		sigemptyset(&intmask);
58601.1Skamil		sigaddset(&intmask, sigmasked);
58611.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58621.1Skamil
58631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58651.1Skamil
58661.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
58671.1Skamil
58681.13Schristos		DPRINTF("Before exiting of the child process\n");
58691.1Skamil		_exit(exitval);
58701.1Skamil	}
58711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58721.1Skamil
58731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58751.1Skamil
58761.1Skamil	validate_status_stopped(status, sigval);
58771.1Skamil
58781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58791.1Skamil	    "without signal to be sent\n");
58801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
58811.1Skamil
58821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58841.1Skamil
58851.1Skamil	validate_status_stopped(status, sigmasked);
58861.1Skamil
58871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58881.1Skamil	    "without signal to be sent\n");
58891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58901.1Skamil
58911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58931.1Skamil
58941.1Skamil	validate_status_exited(status, exitval);
58951.1Skamil
58961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58981.1Skamil}
58991.1Skamil#endif
59001.1Skamil
59011.1SkamilATF_TC(signal5);
59021.1SkamilATF_TC_HEAD(signal5, tc)
59031.1Skamil{
59041.1Skamil	atf_tc_set_md_var(tc, "descr",
59051.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59061.1Skamil	    "catching exec() breakpoint");
59071.1Skamil}
59081.1Skamil
59091.1SkamilATF_TC_BODY(signal5, tc)
59101.1Skamil{
59111.1Skamil	const int exitval = 5;
59121.1Skamil	const int sigval = SIGSTOP;
59131.1Skamil	const int sigmasked = SIGTRAP;
59141.1Skamil	pid_t child, wpid;
59151.1Skamil#if defined(TWAIT_HAVE_STATUS)
59161.1Skamil	int status;
59171.1Skamil#endif
59181.1Skamil	sigset_t intmask;
59191.1Skamil
59201.14Schristos	atf_tc_expect_fail("wrong signal");
59211.14Schristos
59221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59241.1Skamil	if (child == 0) {
59251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59271.1Skamil
59281.1Skamil		sigemptyset(&intmask);
59291.1Skamil		sigaddset(&intmask, sigmasked);
59301.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59311.1Skamil
59321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59341.1Skamil
59351.13Schristos		DPRINTF("Before calling execve(2) from child\n");
59361.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
59371.1Skamil
59381.13Schristos		DPRINTF("Before exiting of the child process\n");
59391.1Skamil		_exit(exitval);
59401.1Skamil	}
59411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59421.1Skamil
59431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59451.1Skamil
59461.1Skamil	validate_status_stopped(status, sigval);
59471.1Skamil
59481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59491.1Skamil	    "without signal to be sent\n");
59501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59511.1Skamil
59521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59541.1Skamil
59551.1Skamil	validate_status_stopped(status, sigmasked);
59561.1Skamil
59571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59581.1Skamil	    "without signal to be sent\n");
59591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59601.1Skamil
59611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59631.1Skamil
59641.1Skamil	validate_status_exited(status, exitval);
59651.1Skamil
59661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59681.1Skamil}
59691.1Skamil
59701.1Skamil#if defined(TWAIT_HAVE_PID)
59711.1SkamilATF_TC(signal6);
59721.1SkamilATF_TC_HEAD(signal6, tc)
59731.1Skamil{
59741.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
59751.1Skamil	atf_tc_set_md_var(tc, "descr",
59761.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59771.1Skamil	    "catching PTRACE_FORK breakpoint");
59781.1Skamil}
59791.1Skamil
59801.1SkamilATF_TC_BODY(signal6, tc)
59811.1Skamil{
59821.1Skamil	const int exitval = 5;
59831.1Skamil	const int exitval2 = 15;
59841.1Skamil	const int sigval = SIGSTOP;
59851.1Skamil	const int sigmasked = SIGTRAP;
59861.1Skamil	pid_t child, child2, wpid;
59871.1Skamil#if defined(TWAIT_HAVE_STATUS)
59881.1Skamil	int status;
59891.1Skamil#endif
59901.1Skamil	sigset_t intmask;
59911.1Skamil	ptrace_state_t state;
59921.1Skamil	const int slen = sizeof(state);
59931.1Skamil	ptrace_event_t event;
59941.1Skamil	const int elen = sizeof(event);
59951.1Skamil
59961.38Skamil	atf_tc_expect_fail("PR kern/51918");
59971.14Schristos
59981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60001.1Skamil	if (child == 0) {
60011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60031.1Skamil
60041.1Skamil		sigemptyset(&intmask);
60051.1Skamil		sigaddset(&intmask, sigmasked);
60061.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60071.1Skamil
60081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60101.1Skamil
60111.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
60121.1Skamil
60131.1Skamil		if (child2 == 0)
60141.1Skamil			_exit(exitval2);
60151.1Skamil
60161.1Skamil		FORKEE_REQUIRE_SUCCESS
60171.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60181.1Skamil
60191.1Skamil		forkee_status_exited(status, exitval2);
60201.1Skamil
60211.13Schristos		DPRINTF("Before exiting of the child process\n");
60221.1Skamil		_exit(exitval);
60231.1Skamil	}
60241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60251.1Skamil
60261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60281.1Skamil
60291.1Skamil	validate_status_stopped(status, sigval);
60301.1Skamil
60311.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
60321.1Skamil	event.pe_set_event = PTRACE_FORK;
60331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60341.1Skamil
60351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60361.1Skamil	    "without signal to be sent\n");
60371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60381.1Skamil
60391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60411.1Skamil
60421.1Skamil	validate_status_stopped(status, sigmasked);
60431.1Skamil
60441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60451.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60461.1Skamil
60471.1Skamil	child2 = state.pe_other_pid;
60481.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
60491.1Skamil
60501.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
60511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60521.1Skamil	    child2);
60531.1Skamil
60541.1Skamil	validate_status_stopped(status, SIGTRAP);
60551.1Skamil
60561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
60571.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60581.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
60591.1Skamil
60601.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
60611.1Skamil	    "without signal to be sent\n");
60621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
60631.1Skamil
60641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60651.1Skamil	    "without signal to be sent\n");
60661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60671.1Skamil
60681.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60691.1Skamil	    TWAIT_FNAME);
60701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60711.1Skamil	    child2);
60721.1Skamil
60731.1Skamil	validate_status_exited(status, exitval2);
60741.1Skamil
60751.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
60761.1Skamil	    TWAIT_FNAME);
60771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
60781.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
60791.1Skamil
60801.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60811.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
60821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60831.1Skamil
60841.1Skamil	validate_status_stopped(status, SIGCHLD);
60851.1Skamil
60861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60871.1Skamil	    "without signal to be sent\n");
60881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60891.1Skamil
60901.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60911.1Skamil	    TWAIT_FNAME);
60921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60931.1Skamil
60941.1Skamil	validate_status_exited(status, exitval);
60951.1Skamil
60961.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60971.1Skamil	    TWAIT_FNAME);
60981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60991.1Skamil}
61001.1Skamil#endif
61011.1Skamil
61021.1Skamil#if defined(TWAIT_HAVE_PID)
61031.1SkamilATF_TC(signal7);
61041.1SkamilATF_TC_HEAD(signal7, tc)
61051.1Skamil{
61061.1Skamil	atf_tc_set_md_var(tc, "descr",
61071.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61081.1Skamil	    "catching PTRACE_VFORK breakpoint");
61091.1Skamil}
61101.1Skamil
61111.1SkamilATF_TC_BODY(signal7, tc)
61121.1Skamil{
61131.1Skamil	const int exitval = 5;
61141.1Skamil	const int exitval2 = 15;
61151.1Skamil	const int sigval = SIGSTOP;
61161.1Skamil	const int sigmasked = SIGTRAP;
61171.1Skamil	pid_t child, child2, wpid;
61181.1Skamil#if defined(TWAIT_HAVE_STATUS)
61191.1Skamil	int status;
61201.1Skamil#endif
61211.1Skamil	sigset_t intmask;
61221.1Skamil	ptrace_state_t state;
61231.1Skamil	const int slen = sizeof(state);
61241.1Skamil	ptrace_event_t event;
61251.1Skamil	const int elen = sizeof(event);
61261.1Skamil
61271.38Skamil	atf_tc_expect_fail("PR kern/51918");
61281.14Schristos
61291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61311.1Skamil	if (child == 0) {
61321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61341.1Skamil
61351.1Skamil		sigemptyset(&intmask);
61361.1Skamil		sigaddset(&intmask, sigmasked);
61371.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61381.1Skamil
61391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61411.1Skamil
61421.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
61431.1Skamil
61441.1Skamil		if (child2 == 0)
61451.1Skamil			_exit(exitval2);
61461.1Skamil
61471.1Skamil		FORKEE_REQUIRE_SUCCESS
61481.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
61491.1Skamil
61501.1Skamil		forkee_status_exited(status, exitval2);
61511.1Skamil
61521.13Schristos		DPRINTF("Before exiting of the child process\n");
61531.1Skamil		_exit(exitval);
61541.1Skamil	}
61551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61561.1Skamil
61571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61591.1Skamil
61601.1Skamil	validate_status_stopped(status, sigval);
61611.1Skamil
61621.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
61631.1Skamil	event.pe_set_event = PTRACE_VFORK;
61641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
61651.1Skamil
61661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61671.1Skamil	    "without signal to be sent\n");
61681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61691.1Skamil
61701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61721.1Skamil
61731.1Skamil	validate_status_stopped(status, sigmasked);
61741.1Skamil
61751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61761.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61771.1Skamil
61781.1Skamil	child2 = state.pe_other_pid;
61791.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
61801.1Skamil
61811.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
61821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
61831.1Skamil	    child2);
61841.1Skamil
61851.1Skamil	validate_status_stopped(status, SIGTRAP);
61861.1Skamil
61871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
61881.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61891.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
61901.1Skamil
61911.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
61921.1Skamil	    "without signal to be sent\n");
61931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
61941.1Skamil
61951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61961.1Skamil	    "without signal to be sent\n");
61971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61981.1Skamil
61991.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
62001.1Skamil	    TWAIT_FNAME);
62011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62021.1Skamil	    child2);
62031.1Skamil
62041.1Skamil	validate_status_exited(status, exitval2);
62051.1Skamil
62061.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
62071.1Skamil	    TWAIT_FNAME);
62081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
62091.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
62101.1Skamil
62111.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62121.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
62131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62141.1Skamil
62151.1Skamil	validate_status_stopped(status, SIGCHLD);
62161.1Skamil
62171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62181.1Skamil	    "without signal to be sent\n");
62191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62201.1Skamil
62211.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62221.1Skamil	    TWAIT_FNAME);
62231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62241.1Skamil
62251.1Skamil	validate_status_exited(status, exitval);
62261.1Skamil
62271.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62281.1Skamil	    TWAIT_FNAME);
62291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62301.1Skamil}
62311.1Skamil#endif
62321.1Skamil
62331.1SkamilATF_TC(signal8);
62341.1SkamilATF_TC_HEAD(signal8, tc)
62351.1Skamil{
62361.1Skamil	atf_tc_set_md_var(tc, "descr",
62371.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62381.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
62391.1Skamil}
62401.1Skamil
62411.1SkamilATF_TC_BODY(signal8, tc)
62421.1Skamil{
62431.1Skamil	const int exitval = 5;
62441.1Skamil	const int exitval2 = 15;
62451.1Skamil	const int sigval = SIGSTOP;
62461.1Skamil	const int sigmasked = SIGTRAP;
62471.1Skamil	pid_t child, child2, wpid;
62481.1Skamil#if defined(TWAIT_HAVE_STATUS)
62491.1Skamil	int status;
62501.1Skamil#endif
62511.1Skamil	sigset_t intmask;
62521.1Skamil	ptrace_state_t state;
62531.1Skamil	const int slen = sizeof(state);
62541.1Skamil	ptrace_event_t event;
62551.1Skamil	const int elen = sizeof(event);
62561.1Skamil
62571.14Schristos	atf_tc_expect_fail("PR kern/51918");
62581.14Schristos
62591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62611.1Skamil	if (child == 0) {
62621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62641.1Skamil
62651.1Skamil		sigemptyset(&intmask);
62661.1Skamil		sigaddset(&intmask, sigmasked);
62671.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62681.1Skamil
62691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62711.1Skamil
62721.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
62731.1Skamil
62741.1Skamil		if (child2 == 0)
62751.1Skamil			_exit(exitval2);
62761.1Skamil
62771.1Skamil		FORKEE_REQUIRE_SUCCESS
62781.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
62791.1Skamil
62801.1Skamil		forkee_status_exited(status, exitval2);
62811.1Skamil
62821.13Schristos		DPRINTF("Before exiting of the child process\n");
62831.1Skamil		_exit(exitval);
62841.1Skamil	}
62851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62861.1Skamil
62871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62891.1Skamil
62901.1Skamil	validate_status_stopped(status, sigval);
62911.1Skamil
62921.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
62931.1Skamil	    child);
62941.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
62951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
62961.1Skamil
62971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62981.1Skamil	    "without signal to be sent\n");
62991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63001.1Skamil
63011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63031.1Skamil
63041.1Skamil	validate_status_stopped(status, sigmasked);
63051.1Skamil
63061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63071.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
63081.1Skamil
63091.1Skamil	child2 = state.pe_other_pid;
63101.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
63111.1Skamil
63121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63131.1Skamil	    "without signal to be sent\n");
63141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63151.1Skamil
63161.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63171.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
63181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63191.1Skamil
63201.1Skamil	validate_status_stopped(status, SIGCHLD);
63211.1Skamil
63221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63231.1Skamil	    "without signal to be sent\n");
63241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63251.1Skamil
63261.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63271.1Skamil	    TWAIT_FNAME);
63281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63291.1Skamil
63301.1Skamil	validate_status_exited(status, exitval);
63311.1Skamil
63321.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63331.1Skamil	    TWAIT_FNAME);
63341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63351.1Skamil}
63361.1Skamil
63371.1SkamilATF_TC(signal9);
63381.1SkamilATF_TC_HEAD(signal9, tc)
63391.1Skamil{
63401.1Skamil	atf_tc_set_md_var(tc, "descr",
63411.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
63421.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
63431.1Skamil}
63441.1Skamil
63451.1SkamilATF_TC_BODY(signal9, tc)
63461.1Skamil{
63471.1Skamil	const int exitval = 5;
63481.1Skamil	const int sigval = SIGSTOP;
63491.1Skamil	const int sigmasked = SIGTRAP;
63501.1Skamil	pid_t child, wpid;
63511.1Skamil#if defined(TWAIT_HAVE_STATUS)
63521.1Skamil	int status;
63531.1Skamil#endif
63541.1Skamil	sigset_t intmask;
63551.1Skamil	ptrace_state_t state;
63561.1Skamil	const int slen = sizeof(state);
63571.1Skamil	ptrace_event_t event;
63581.1Skamil	const int elen = sizeof(event);
63591.1Skamil	ucontext_t uc;
63601.1Skamil	lwpid_t lid;
63611.1Skamil	static const size_t ssize = 16*1024;
63621.1Skamil	void *stack;
63631.1Skamil
63641.14Schristos	atf_tc_expect_fail("PR kern/51918");
63651.14Schristos
63661.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63671.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63681.1Skamil	if (child == 0) {
63691.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63701.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63711.1Skamil
63721.1Skamil		sigemptyset(&intmask);
63731.1Skamil		sigaddset(&intmask, sigmasked);
63741.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
63751.1Skamil
63761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63781.1Skamil
63791.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63801.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
63811.1Skamil
63821.13Schristos		DPRINTF("Before making context for new lwp in child\n");
63831.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
63841.1Skamil
63851.13Schristos		DPRINTF("Before creating new in child\n");
63861.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
63871.1Skamil
63881.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
63891.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
63901.1Skamil
63911.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
63921.1Skamil		    "are the same\n", lid, the_lwp_id);
63931.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
63941.1Skamil
63951.13Schristos		DPRINTF("Before exiting of the child process\n");
63961.1Skamil		_exit(exitval);
63971.1Skamil	}
63981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63991.1Skamil
64001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64021.1Skamil
64031.1Skamil	validate_status_stopped(status, sigval);
64041.1Skamil
64051.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
64061.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
64071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
64081.1Skamil
64091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64101.1Skamil	    "without signal to be sent\n");
64111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64121.1Skamil
64131.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64141.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64161.1Skamil
64171.1Skamil	validate_status_stopped(status, sigmasked);
64181.1Skamil
64191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
64201.1Skamil
64211.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
64221.1Skamil
64231.1Skamil	lid = state.pe_lwp;
64241.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
64251.1Skamil
64261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64271.1Skamil	    "without signal to be sent\n");
64281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64291.1Skamil
64301.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64311.1Skamil	    TWAIT_FNAME);
64321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64331.1Skamil
64341.1Skamil	validate_status_exited(status, exitval);
64351.1Skamil
64361.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64371.1Skamil	    TWAIT_FNAME);
64381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64391.1Skamil}
64401.1Skamil
64411.1SkamilATF_TC(signal10);
64421.1SkamilATF_TC_HEAD(signal10, tc)
64431.1Skamil{
64441.1Skamil	atf_tc_set_md_var(tc, "descr",
64451.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
64461.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
64471.1Skamil}
64481.1Skamil
64491.1SkamilATF_TC_BODY(signal10, tc)
64501.1Skamil{
64511.1Skamil	const int exitval = 5;
64521.1Skamil	const int sigval = SIGSTOP;
64531.1Skamil	const int sigmasked = SIGTRAP;
64541.1Skamil	pid_t child, wpid;
64551.1Skamil#if defined(TWAIT_HAVE_STATUS)
64561.1Skamil	int status;
64571.1Skamil#endif
64581.1Skamil	sigset_t intmask;
64591.1Skamil	ptrace_state_t state;
64601.1Skamil	const int slen = sizeof(state);
64611.1Skamil	ptrace_event_t event;
64621.1Skamil	const int elen = sizeof(event);
64631.1Skamil	ucontext_t uc;
64641.1Skamil	lwpid_t lid;
64651.1Skamil	static const size_t ssize = 16*1024;
64661.1Skamil	void *stack;
64671.1Skamil
64681.14Schristos	atf_tc_expect_fail("PR kern/51918");
64691.14Schristos
64701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64721.1Skamil	if (child == 0) {
64731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64751.1Skamil
64761.1Skamil		sigemptyset(&intmask);
64771.1Skamil		sigaddset(&intmask, sigmasked);
64781.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
64791.1Skamil
64801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64821.1Skamil
64831.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64841.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64851.1Skamil
64861.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64871.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
64881.1Skamil
64891.13Schristos		DPRINTF("Before creating new in child\n");
64901.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64911.1Skamil
64921.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64931.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64941.1Skamil
64951.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64961.1Skamil		    "are the same\n", lid, the_lwp_id);
64971.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64981.1Skamil
64991.13Schristos		DPRINTF("Before exiting of the child process\n");
65001.1Skamil		_exit(exitval);
65011.1Skamil	}
65021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65031.1Skamil
65041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65061.1Skamil
65071.1Skamil	validate_status_stopped(status, sigval);
65081.1Skamil
65091.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
65101.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
65111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
65121.1Skamil
65131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65141.1Skamil	    "without signal to be sent\n");
65151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65161.1Skamil
65171.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65181.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65201.1Skamil
65211.1Skamil	validate_status_stopped(status, sigmasked);
65221.1Skamil
65231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
65241.1Skamil
65251.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
65261.1Skamil
65271.1Skamil	lid = state.pe_lwp;
65281.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
65291.1Skamil
65301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65311.1Skamil	    "without signal to be sent\n");
65321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65331.1Skamil
65341.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65351.1Skamil	    TWAIT_FNAME);
65361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65371.1Skamil
65381.1Skamil	validate_status_exited(status, exitval);
65391.1Skamil
65401.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65411.1Skamil	    TWAIT_FNAME);
65421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65431.1Skamil}
65441.1Skamil
65451.1Skamilstatic void
65461.1Skamillwp_main_stop(void *arg)
65471.1Skamil{
65481.1Skamil	the_lwp_id = _lwp_self();
65491.1Skamil
65501.1Skamil	raise(SIGTRAP);
65511.1Skamil
65521.1Skamil	_lwp_exit();
65531.1Skamil}
65541.1Skamil
65551.1SkamilATF_TC(suspend1);
65561.1SkamilATF_TC_HEAD(suspend1, tc)
65571.1Skamil{
65581.1Skamil	atf_tc_set_md_var(tc, "descr",
65591.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
65601.1Skamil	    "resumed by a tracee");
65611.1Skamil}
65621.1Skamil
65631.1SkamilATF_TC_BODY(suspend1, tc)
65641.1Skamil{
65651.1Skamil	const int exitval = 5;
65661.1Skamil	const int sigval = SIGSTOP;
65671.1Skamil	pid_t child, wpid;
65681.1Skamil#if defined(TWAIT_HAVE_STATUS)
65691.1Skamil	int status;
65701.1Skamil#endif
65711.1Skamil	ucontext_t uc;
65721.1Skamil	lwpid_t lid;
65731.1Skamil	static const size_t ssize = 16*1024;
65741.1Skamil	void *stack;
65751.1Skamil	struct ptrace_lwpinfo pl;
65761.1Skamil	struct ptrace_siginfo psi;
65771.1Skamil	volatile int go = 0;
65781.1Skamil
65791.17Skamil	// Feature pending for refactoring
65801.17Skamil	atf_tc_expect_fail("PR kern/51995");
65811.17Skamil
65821.16Skamil	// Hangs with qemu
65831.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
65841.16Skamil
65851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65871.1Skamil	if (child == 0) {
65881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65901.1Skamil
65911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65931.1Skamil
65941.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
65951.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
65961.1Skamil
65971.13Schristos		DPRINTF("Before making context for new lwp in child\n");
65981.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
65991.1Skamil
66001.13Schristos		DPRINTF("Before creating new in child\n");
66011.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
66021.1Skamil
66031.1Skamil		while (go == 0)
66041.1Skamil			continue;
66051.1Skamil
66061.1Skamil		raise(SIGINT);
66071.1Skamil
66081.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
66091.1Skamil
66101.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
66111.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
66121.1Skamil
66131.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
66141.1Skamil		    "are the same\n", lid, the_lwp_id);
66151.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
66161.1Skamil
66171.13Schristos		DPRINTF("Before exiting of the child process\n");
66181.1Skamil		_exit(exitval);
66191.1Skamil	}
66201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66211.1Skamil
66221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66241.1Skamil
66251.1Skamil	validate_status_stopped(status, sigval);
66261.1Skamil
66271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66281.1Skamil	    "without signal to be sent\n");
66291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66301.1Skamil
66311.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66321.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
66331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66341.1Skamil
66351.1Skamil	validate_status_stopped(status, SIGTRAP);
66361.1Skamil
66371.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
66381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
66391.1Skamil
66401.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
66411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
66421.1Skamil
66431.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
66441.1Skamil	    child, getpid());
66451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
66461.1Skamil
66471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66481.1Skamil	    "without signal to be sent\n");
66491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66501.1Skamil
66511.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66521.1Skamil	    "SIGINT\n", TWAIT_FNAME);
66531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66541.1Skamil
66551.1Skamil	validate_status_stopped(status, SIGINT);
66561.1Skamil
66571.1Skamil	pl.pl_lwpid = 0;
66581.1Skamil
66591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66601.1Skamil	while (pl.pl_lwpid != 0) {
66611.1Skamil
66621.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66631.1Skamil		switch (pl.pl_lwpid) {
66641.1Skamil		case 1:
66651.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
66661.1Skamil			break;
66671.1Skamil		case 2:
66681.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
66691.1Skamil			break;
66701.1Skamil		}
66711.1Skamil	}
66721.1Skamil
66731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66741.1Skamil	    "without signal to be sent\n");
66751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66761.1Skamil
66771.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
66781.1Skamil	    TWAIT_FNAME);
66791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66801.1Skamil
66811.1Skamil	validate_status_exited(status, exitval);
66821.1Skamil
66831.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
66841.1Skamil	    TWAIT_FNAME);
66851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66861.1Skamil}
66871.1Skamil
66881.1SkamilATF_TC(suspend2);
66891.1SkamilATF_TC_HEAD(suspend2, tc)
66901.1Skamil{
66911.1Skamil	atf_tc_set_md_var(tc, "descr",
66921.1Skamil	    "Verify that the while the only thread within a process is "
66931.1Skamil	    "suspended, the whole process cannot be unstopped");
66941.1Skamil}
66951.1Skamil
66961.1SkamilATF_TC_BODY(suspend2, tc)
66971.1Skamil{
66981.1Skamil	const int exitval = 5;
66991.1Skamil	const int sigval = SIGSTOP;
67001.1Skamil	pid_t child, wpid;
67011.1Skamil#if defined(TWAIT_HAVE_STATUS)
67021.1Skamil	int status;
67031.1Skamil#endif
67041.1Skamil	struct ptrace_siginfo psi;
67051.1Skamil
67061.17Skamil	// Feature pending for refactoring
67071.17Skamil	atf_tc_expect_fail("PR kern/51995");
67081.17Skamil
67091.16Skamil	// Hangs with qemu
67101.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
67111.16Skamil
67121.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67131.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67141.1Skamil	if (child == 0) {
67151.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67161.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67171.1Skamil
67181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67201.1Skamil
67211.13Schristos		DPRINTF("Before exiting of the child process\n");
67221.1Skamil		_exit(exitval);
67231.1Skamil	}
67241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67251.1Skamil
67261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67281.1Skamil
67291.1Skamil	validate_status_stopped(status, sigval);
67301.1Skamil
67311.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
67321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
67331.1Skamil
67341.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
67351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
67361.1Skamil
67371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67381.1Skamil	    "without signal to be sent\n");
67391.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
67401.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
67411.1Skamil
67421.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
67431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
67441.1Skamil
67451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67461.1Skamil	    "without signal to be sent\n");
67471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67481.1Skamil
67491.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
67501.1Skamil	    TWAIT_FNAME);
67511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67521.1Skamil
67531.1Skamil	validate_status_exited(status, exitval);
67541.1Skamil
67551.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
67561.1Skamil	    TWAIT_FNAME);
67571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67581.1Skamil}
67591.1Skamil
67601.1SkamilATF_TC(resume1);
67611.1SkamilATF_TC_HEAD(resume1, tc)
67621.1Skamil{
67631.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
67641.1Skamil	atf_tc_set_md_var(tc, "descr",
67651.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
67661.1Skamil	    "resumed by the debugger");
67671.1Skamil}
67681.1Skamil
67691.1SkamilATF_TC_BODY(resume1, tc)
67701.1Skamil{
67711.1Skamil	struct msg_fds fds;
67721.1Skamil	const int exitval = 5;
67731.1Skamil	const int sigval = SIGSTOP;
67741.1Skamil	pid_t child, wpid;
67751.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
67761.1Skamil#if defined(TWAIT_HAVE_STATUS)
67771.1Skamil	int status;
67781.1Skamil#endif
67791.1Skamil	ucontext_t uc;
67801.1Skamil	lwpid_t lid;
67811.1Skamil	static const size_t ssize = 16*1024;
67821.1Skamil	void *stack;
67831.1Skamil	struct ptrace_lwpinfo pl;
67841.1Skamil	struct ptrace_siginfo psi;
67851.1Skamil
67861.17Skamil	// Feature pending for refactoring
67871.17Skamil	atf_tc_expect_fail("PR kern/51995");
67881.17Skamil
67891.15Schristos	// Hangs with qemu
67901.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
67911.1Skamil
67921.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
67931.1Skamil
67941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67961.1Skamil	if (child == 0) {
67971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67991.1Skamil
68001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68021.1Skamil
68031.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
68041.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
68051.1Skamil
68061.13Schristos		DPRINTF("Before making context for new lwp in child\n");
68071.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
68081.1Skamil
68091.13Schristos		DPRINTF("Before creating new in child\n");
68101.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
68111.1Skamil
68121.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
68131.1Skamil
68141.1Skamil		raise(SIGINT);
68151.1Skamil
68161.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
68171.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
68181.1Skamil
68191.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
68201.1Skamil		    "are the same\n", lid, the_lwp_id);
68211.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
68221.1Skamil
68231.13Schristos		DPRINTF("Before exiting of the child process\n");
68241.1Skamil		_exit(exitval);
68251.1Skamil	}
68261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68271.1Skamil
68281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68301.1Skamil
68311.1Skamil	validate_status_stopped(status, sigval);
68321.1Skamil
68331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68341.1Skamil	    "without signal to be sent\n");
68351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68361.1Skamil
68371.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68381.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
68391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68401.1Skamil
68411.1Skamil	validate_status_stopped(status, SIGTRAP);
68421.1Skamil
68431.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
68441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
68451.1Skamil
68461.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
68471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
68481.1Skamil
68491.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
68501.1Skamil
68511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68521.1Skamil	    "without signal to be sent\n");
68531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68541.1Skamil
68551.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68561.1Skamil	    "SIGINT\n", TWAIT_FNAME);
68571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68581.1Skamil
68591.1Skamil	validate_status_stopped(status, SIGINT);
68601.1Skamil
68611.1Skamil	pl.pl_lwpid = 0;
68621.1Skamil
68631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68641.1Skamil	while (pl.pl_lwpid != 0) {
68651.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68661.1Skamil		switch (pl.pl_lwpid) {
68671.1Skamil		case 1:
68681.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
68691.1Skamil			break;
68701.1Skamil		case 2:
68711.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
68721.1Skamil			break;
68731.1Skamil		}
68741.1Skamil	}
68751.1Skamil
68761.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
68771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
68781.1Skamil
68791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68801.1Skamil	    "without signal to be sent\n");
68811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68821.1Skamil
68831.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
68841.1Skamil	    TWAIT_FNAME);
68851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68861.1Skamil
68871.1Skamil	validate_status_exited(status, exitval);
68881.1Skamil
68891.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
68901.1Skamil	    TWAIT_FNAME);
68911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
68921.1Skamil
68931.1Skamil	msg_close(&fds);
68941.1Skamil
68951.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
68961.1Skamil	sleep(10);
68971.1Skamil}
68981.1Skamil
68991.1SkamilATF_TC(syscall1);
69001.1SkamilATF_TC_HEAD(syscall1, tc)
69011.1Skamil{
69021.1Skamil	atf_tc_set_md_var(tc, "descr",
69031.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
69041.1Skamil}
69051.1Skamil
69061.1SkamilATF_TC_BODY(syscall1, tc)
69071.1Skamil{
69081.1Skamil	const int exitval = 5;
69091.1Skamil	const int sigval = SIGSTOP;
69101.1Skamil	pid_t child, wpid;
69111.1Skamil#if defined(TWAIT_HAVE_STATUS)
69121.1Skamil	int status;
69131.1Skamil#endif
69141.1Skamil	struct ptrace_siginfo info;
69151.1Skamil	memset(&info, 0, sizeof(info));
69161.1Skamil
69171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69191.1Skamil	if (child == 0) {
69201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69221.1Skamil
69231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
69251.1Skamil
69261.1Skamil		syscall(SYS_getpid);
69271.1Skamil
69281.13Schristos		DPRINTF("Before exiting of the child process\n");
69291.1Skamil		_exit(exitval);
69301.1Skamil	}
69311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
69321.1Skamil
69331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69351.1Skamil
69361.1Skamil	validate_status_stopped(status, sigval);
69371.1Skamil
69381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69391.1Skamil	    "without signal to be sent\n");
69401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69411.1Skamil
69421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69441.1Skamil
69451.1Skamil	validate_status_stopped(status, SIGTRAP);
69461.1Skamil
69471.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69491.1Skamil
69501.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
69511.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
69521.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69531.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
69541.1Skamil
69551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69561.1Skamil	    "without signal to be sent\n");
69571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69581.1Skamil
69591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69611.1Skamil
69621.1Skamil	validate_status_stopped(status, SIGTRAP);
69631.1Skamil
69641.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69661.1Skamil
69671.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
69681.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
69691.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69701.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
69711.1Skamil
69721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69731.1Skamil	    "without signal to be sent\n");
69741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69751.1Skamil
69761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69781.1Skamil
69791.1Skamil	validate_status_exited(status, exitval);
69801.1Skamil
69811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69831.1Skamil}
69841.1Skamil
69851.1SkamilATF_TC(syscallemu1);
69861.1SkamilATF_TC_HEAD(syscallemu1, tc)
69871.1Skamil{
69881.1Skamil	atf_tc_set_md_var(tc, "descr",
69891.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
69901.1Skamil}
69911.1Skamil
69921.1SkamilATF_TC_BODY(syscallemu1, tc)
69931.1Skamil{
69941.1Skamil	const int exitval = 5;
69951.1Skamil	const int sigval = SIGSTOP;
69961.1Skamil	pid_t child, wpid;
69971.1Skamil#if defined(TWAIT_HAVE_STATUS)
69981.1Skamil	int status;
69991.1Skamil#endif
70001.1Skamil
70011.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
70021.6Skamil	/* syscallemu does not work on sparc (32-bit) */
70031.6Skamil	atf_tc_expect_fail("PR kern/52166");
70041.6Skamil#endif
70051.6Skamil
70061.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
70071.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
70081.1Skamil	if (child == 0) {
70091.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
70101.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
70111.1Skamil
70121.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70131.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70141.1Skamil
70151.1Skamil		syscall(SYS_exit, 100);
70161.1Skamil
70171.13Schristos		DPRINTF("Before exiting of the child process\n");
70181.1Skamil		_exit(exitval);
70191.1Skamil	}
70201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70211.1Skamil
70221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70241.1Skamil
70251.1Skamil	validate_status_stopped(status, sigval);
70261.1Skamil
70271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70281.1Skamil	    "without signal to be sent\n");
70291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70301.1Skamil
70311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70331.1Skamil
70341.1Skamil	validate_status_stopped(status, SIGTRAP);
70351.1Skamil
70361.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
70371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
70381.1Skamil
70391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70401.1Skamil	    "without signal to be sent\n");
70411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70421.1Skamil
70431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70451.1Skamil
70461.1Skamil	validate_status_stopped(status, SIGTRAP);
70471.1Skamil
70481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70491.1Skamil	    "without signal to be sent\n");
70501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70511.1Skamil
70521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70541.1Skamil
70551.1Skamil	validate_status_exited(status, exitval);
70561.1Skamil
70571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70591.1Skamil}
70601.1Skamil
70611.1Skamil#include "t_ptrace_amd64_wait.h"
70621.1Skamil#include "t_ptrace_i386_wait.h"
70631.1Skamil#include "t_ptrace_x86_wait.h"
70641.1Skamil
70651.1SkamilATF_TP_ADD_TCS(tp)
70661.1Skamil{
70671.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
70681.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
70691.33Skamil
70701.36Skamil	ATF_TP_ADD_TC(tp, traceme_raise1);
70711.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
70721.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
70731.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
70741.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
70751.33Skamil
70761.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1);
70771.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2);
70781.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3);
70791.50Skamil
70801.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1);
70811.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2);
70821.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3);
70831.50Skamil
70841.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1);
70851.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2);
70861.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3);
70871.50Skamil
70881.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1);
70891.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2);
70901.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3);
70911.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4);
70921.50Skamil	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5);
70931.1Skamil
70941.37Skamil	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
70951.37Skamil
70961.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
70971.46Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
70981.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
70991.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
71001.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
71011.47Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
71021.47Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
71031.47Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
71041.40Skamil
71051.41Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_breakpoint);
71061.41Skamil
71071.43Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
71081.43Skamil
71091.51Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
71101.51Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
71111.51Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_terminaton_before_the_parent);
71121.51Skamil
71131.51Skamil	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
71141.51Skamil
71151.51Skamil	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
71161.51Skamil
71171.51Skamil	ATF_TP_ADD_TC_HAVE_PID(tp,
71181.51Skamil		tracee_sees_its_original_parent_getppid);
71191.51Skamil	ATF_TP_ADD_TC_HAVE_PID(tp,
71201.51Skamil		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
71211.51Skamil	ATF_TP_ADD_TC_HAVE_PID(tp,
71221.51Skamil		tracee_sees_its_original_parent_procfs_status);
71231.1Skamil
71241.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
71251.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
71261.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
71271.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
71281.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
71291.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
71301.1Skamil
71311.31Skamil	ATF_TP_ADD_TC(tp, fork1);
71321.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
71331.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
71341.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
71351.31Skamil	ATF_TP_ADD_TC(tp, fork5);
71361.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
71371.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
71381.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
71391.31Skamil
71401.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
71411.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
71421.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
71431.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
71441.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
71451.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
71461.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
71471.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
71481.1Skamil
71491.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
71501.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
71511.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
71521.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
71531.1Skamil
71541.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
71551.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
71561.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
71571.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
71581.1Skamil
71591.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
71601.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
71611.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
71621.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
71631.1Skamil
71641.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
71651.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
71661.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
71671.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
71681.1Skamil
71691.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
71701.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
71711.1Skamil
71721.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
71731.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
71741.1Skamil
71751.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
71761.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
71771.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
71781.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
71791.1Skamil
71801.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
71811.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
71821.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
71831.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
71841.1Skamil
71851.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
71861.1Skamil
71871.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
71881.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
71891.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
71901.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
71911.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
71921.1Skamil
71931.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
71941.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
71951.1Skamil
71961.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
71971.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
71981.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
71991.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
72001.1Skamil
72011.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
72021.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
72031.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
72041.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
72051.2Skamil
72061.1Skamil	ATF_TP_ADD_TC(tp, kill1);
72071.1Skamil	ATF_TP_ADD_TC(tp, kill2);
72081.1Skamil
72091.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
72101.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
72111.1Skamil
72121.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
72131.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
72141.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
72151.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
72161.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
72171.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
72181.1Skamil
72191.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
72201.1Skamil
72211.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
72221.1Skamil
72231.1Skamil	ATF_TP_ADD_TC(tp, signal1);
72241.1Skamil	ATF_TP_ADD_TC(tp, signal2);
72251.1Skamil	ATF_TP_ADD_TC(tp, signal3);
72261.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
72271.1Skamil	ATF_TP_ADD_TC(tp, signal5);
72281.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
72291.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
72301.1Skamil	ATF_TP_ADD_TC(tp, signal8);
72311.1Skamil	ATF_TP_ADD_TC(tp, signal9);
72321.1Skamil	ATF_TP_ADD_TC(tp, signal10);
72331.1Skamil
72341.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
72351.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
72361.1Skamil
72371.1Skamil	ATF_TP_ADD_TC(tp, resume1);
72381.1Skamil
72391.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
72401.1Skamil
72411.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
72421.1Skamil
72431.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
72441.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
72451.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
72461.1Skamil
72471.1Skamil	return atf_no_error();
72481.1Skamil}
7249