t_ptrace_wait.c revision 1.37
11.37Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.37 2018/04/29 13:56:00 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.37Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.37 2018/04/29 13:56:00 kamil Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/types.h>
341.1Skamil#include <sys/ptrace.h>
351.1Skamil#include <sys/resource.h>
361.1Skamil#include <sys/stat.h>
371.1Skamil#include <sys/syscall.h>
381.1Skamil#include <sys/sysctl.h>
391.1Skamil#include <sys/wait.h>
401.1Skamil#include <machine/reg.h>
411.1Skamil#include <elf.h>
421.1Skamil#include <err.h>
431.1Skamil#include <errno.h>
441.1Skamil#include <lwp.h>
451.1Skamil#include <sched.h>
461.1Skamil#include <signal.h>
471.1Skamil#include <stdint.h>
481.1Skamil#include <stdio.h>
491.1Skamil#include <stdlib.h>
501.1Skamil#include <strings.h>
511.26Skamil#include <time.h>
521.1Skamil#include <unistd.h>
531.1Skamil
541.1Skamil#include <atf-c.h>
551.1Skamil
561.1Skamil#include "h_macros.h"
571.1Skamil
581.1Skamil#include "t_ptrace_wait.h"
591.1Skamil#include "msg.h"
601.1Skamil
611.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
621.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
631.1Skamil
641.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
651.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
661.1Skamil
671.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
681.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
691.1Skamil
701.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
711.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
721.13Schristos
731.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
741.13Schristos    strerror(errno))
751.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
761.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
771.13Schristos
781.13Schristosstatic int debug = 0;
791.13Schristos
801.13Schristos#define DPRINTF(a, ...)	do  \
811.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
821.13Schristos    while (/*CONSTCOND*/0)
831.1Skamil
841.34Skamil/// ----------------------------------------------------------------------------
851.34Skamil
861.33Skamilstatic void
871.33Skamiltraceme_raise(int sigval)
881.1Skamil{
891.1Skamil	const int exitval = 5;
901.1Skamil	pid_t child, wpid;
911.1Skamil#if defined(TWAIT_HAVE_STATUS)
921.1Skamil	int status;
931.1Skamil#endif
941.1Skamil
951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
971.1Skamil	if (child == 0) {
981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1001.1Skamil
1011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1031.1Skamil
1041.36Skamil		switch (sigval) {
1051.36Skamil		case SIGKILL:
1061.36Skamil			/* NOTREACHED */
1071.36Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
1081.36Skamil		default:
1091.36Skamil			DPRINTF("Before exiting of the child process\n");
1101.36Skamil			_exit(exitval);
1111.36Skamil		}
1121.1Skamil	}
1131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1141.1Skamil
1151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1171.1Skamil
1181.36Skamil	switch (sigval) {
1191.36Skamil	case SIGKILL:
1201.36Skamil		validate_status_signaled(status, sigval, 0);
1211.36Skamil		break;
1221.36Skamil	default:
1231.36Skamil		validate_status_stopped(status, sigval);
1241.1Skamil
1251.36Skamil		DPRINTF("Before resuming the child process where it left off "
1261.36Skamil		    "and without signal to be sent\n");
1271.36Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1281.1Skamil
1291.36Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1301.36Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1311.36Skamil		                      child);
1321.36Skamil		break;
1331.36Skamil	}
1341.1Skamil
1351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1371.1Skamil}
1381.1Skamil
1391.33Skamil#define TRACEME_RAISE(test, sig)						\
1401.33SkamilATF_TC(test);									\
1411.33SkamilATF_TC_HEAD(test, tc)								\
1421.33Skamil{										\
1431.33Skamil	atf_tc_set_md_var(tc, "descr",						\
1441.33Skamil	    "Verify " #sig " followed by _exit(2) in a child");			\
1451.33Skamil}										\
1461.33Skamil										\
1471.33SkamilATF_TC_BODY(test, tc)								\
1481.33Skamil{										\
1491.33Skamil										\
1501.33Skamil	traceme_raise(sig);							\
1511.33Skamil}
1521.33Skamil
1531.36SkamilTRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
1541.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
1551.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
1561.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
1571.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
1581.33Skamil
1591.34Skamil/// ----------------------------------------------------------------------------
1601.1Skamil
1611.1Skamilstatic void
1621.34Skamiltraceme_sighandler_catch(int sigsent, void (*sah)(int arg), int *traceme_caught)
1631.1Skamil{
1641.1Skamil	const int exitval = 5;
1651.34Skamil	const int sigval = SIGSTOP;
1661.1Skamil	pid_t child, wpid;
1671.1Skamil	struct sigaction sa;
1681.1Skamil#if defined(TWAIT_HAVE_STATUS)
1691.1Skamil	int status;
1701.1Skamil#endif
1711.1Skamil
1721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1741.1Skamil	if (child == 0) {
1751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1771.1Skamil
1781.34Skamil		sa.sa_handler = sah;
1791.1Skamil		sa.sa_flags = SA_SIGINFO;
1801.1Skamil		sigemptyset(&sa.sa_mask);
1811.1Skamil
1821.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1831.1Skamil
1841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1861.1Skamil
1871.34Skamil		FORKEE_ASSERT_EQ(*traceme_caught, 1);
1881.1Skamil
1891.13Schristos		DPRINTF("Before exiting of the child process\n");
1901.1Skamil		_exit(exitval);
1911.1Skamil	}
1921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1931.1Skamil
1941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1961.1Skamil
1971.1Skamil	validate_status_stopped(status, sigval);
1981.1Skamil
1991.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2001.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2021.1Skamil
2031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2051.1Skamil
2061.1Skamil	validate_status_exited(status, exitval);
2071.1Skamil
2081.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2101.1Skamil}
2111.1Skamil
2121.34Skamil#define TRACEME_SIGHANDLER_CATCH(test, sig)					\
2131.34SkamilATF_TC(test);									\
2141.34SkamilATF_TC_HEAD(test, tc)								\
2151.34Skamil{										\
2161.34Skamil	atf_tc_set_md_var(tc, "descr",						\
2171.34Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
2181.34Skamil	    "handled correctly and caught by a signal handler");		\
2191.34Skamil}										\
2201.34Skamil										\
2211.34Skamilstatic int test##_caught = 0;							\
2221.34Skamil										\
2231.34Skamilstatic void									\
2241.34Skamiltest##_sighandler(int arg)							\
2251.34Skamil{										\
2261.34Skamil	FORKEE_ASSERT_EQ(arg, sig);						\
2271.34Skamil										\
2281.34Skamil	++ test##_caught;							\
2291.34Skamil}										\
2301.34Skamil										\
2311.34SkamilATF_TC_BODY(test, tc)								\
2321.34Skamil{										\
2331.34Skamil										\
2341.34Skamil	traceme_sighandler_catch(sig, test##_sighandler, & test##_caught);	\
2351.34Skamil}
2361.34Skamil
2371.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered.
2381.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch1, SIGABRT) /* abort trap */
2391.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch2, SIGHUP)  /* hangup */
2401.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch3, SIGCONT) /* continued? */
2411.34Skamil
2421.34Skamil/// ----------------------------------------------------------------------------
2431.34Skamil
2441.35Skamilstatic void
2451.35Skamiltraceme_signal_nohandler(int sigsent)
2461.1Skamil{
2471.35Skamil	const int sigval = SIGSTOP;
2481.35Skamil	int exitval = 0;
2491.1Skamil	pid_t child, wpid;
2501.1Skamil#if defined(TWAIT_HAVE_STATUS)
2511.1Skamil	int status;
2521.35Skamil	int expect_core = (sigsent == SIGABRT) ? 1 : 0;
2531.1Skamil#endif
2541.1Skamil
2551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2571.1Skamil	if (child == 0) {
2581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2601.1Skamil
2611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2631.1Skamil
2641.35Skamil		switch (sigsent) {
2651.35Skamil		case SIGCONT:
2661.35Skamil			_exit(exitval);
2671.35Skamil		default:
2681.35Skamil			/* NOTREACHED */
2691.35Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
2701.35Skamil		}
2711.1Skamil	}
2721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2731.1Skamil
2741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2761.1Skamil
2771.1Skamil	validate_status_stopped(status, sigval);
2781.1Skamil
2791.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2801.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2821.1Skamil
2831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2851.1Skamil
2861.35Skamil	switch (sigsent) {
2871.35Skamil	case SIGCONT:
2881.35Skamil		validate_status_exited(status, exitval);
2891.35Skamil		break;
2901.35Skamil	default:
2911.35Skamil		validate_status_signaled(status, sigsent, expect_core);
2921.35Skamil		break;
2931.35Skamil	}
2941.1Skamil
2951.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2971.1Skamil}
2981.1Skamil
2991.35Skamil#define TRACEME_SIGNAL_NOHANDLER(test, sig)					\
3001.35SkamilATF_TC(test);									\
3011.35SkamilATF_TC_HEAD(test, tc)								\
3021.35Skamil{										\
3031.35Skamil	atf_tc_set_md_var(tc, "descr",						\
3041.35Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
3051.35Skamil	    "handled correctly in a child without a signal handler");		\
3061.35Skamil}										\
3071.35Skamil										\
3081.35SkamilATF_TC_BODY(test, tc)								\
3091.35Skamil{										\
3101.35Skamil										\
3111.35Skamil	traceme_signal_nohandler(sig);						\
3121.35Skamil}
3131.35Skamil
3141.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */
3151.35Skamil//TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */
3161.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */
3171.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP)  /* hangup */
3181.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */
3191.35Skamil
3201.35Skamil/// ----------------------------------------------------------------------------
3211.35Skamil
3221.37SkamilATF_TC(traceme_pid1_parent);
3231.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc)
3241.37Skamil{
3251.37Skamil	atf_tc_set_md_var(tc, "descr",
3261.37Skamil	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
3271.37Skamil}
3281.37Skamil
3291.37SkamilATF_TC_BODY(traceme_pid1_parent, tc)
3301.37Skamil{
3311.37Skamil	struct msg_fds parent_child;
3321.37Skamil	int exitval_child1 = 1, exitval_child2 = 2;
3331.37Skamil	pid_t child1, child2, wpid;
3341.37Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3351.37Skamil#if defined(TWAIT_HAVE_STATUS)
3361.37Skamil	int status;
3371.37Skamil#endif
3381.37Skamil
3391.37Skamil	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
3401.37Skamil
3411.37Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
3421.37Skamil	SYSCALL_REQUIRE((child1 = fork()) != -1);
3431.37Skamil	if (child1 == 0) {
3441.37Skamil		DPRINTF("Before forking process PID=%d\n", getpid());
3451.37Skamil		SYSCALL_REQUIRE((child2 = fork()) != -1);
3461.37Skamil		if (child2 != 0) {
3471.37Skamil			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
3481.37Skamil			        getpid(), child2);
3491.37Skamil			_exit(exitval_child1);
3501.37Skamil		}
3511.37Skamil		CHILD_FROM_PARENT("exit child1", parent_child, msg);
3521.37Skamil
3531.37Skamil		DPRINTF("Assert that our parent is PID1 (initproc)\n");
3541.37Skamil		FORKEE_ASSERT_EQ(getppid(), 1);
3551.37Skamil
3561.37Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3571.37Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
3581.37Skamil		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
3591.37Skamil
3601.37Skamil		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
3611.37Skamil
3621.37Skamil		_exit(exitval_child2);
3631.37Skamil	}
3641.37Skamil	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
3651.37Skamil
3661.37Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3671.37Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child1, &status, WEXITED),
3681.37Skamil	                      child1);
3691.37Skamil
3701.37Skamil	validate_status_exited(status, exitval_child1);
3711.37Skamil
3721.37Skamil	DPRINTF("Notify that child1 is dead\n");
3731.37Skamil	PARENT_TO_CHILD("exit child1", parent_child, msg);
3741.37Skamil
3751.37Skamil	DPRINTF("Wait for exiting of child2\n");
3761.37Skamil	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
3771.37Skamil}
3781.37Skamil
3791.37Skamil/// ----------------------------------------------------------------------------
3801.37Skamil
3811.1Skamil#if defined(TWAIT_HAVE_PID)
3821.1SkamilATF_TC(attach1);
3831.1SkamilATF_TC_HEAD(attach1, tc)
3841.1Skamil{
3851.1Skamil	atf_tc_set_md_var(tc, "descr",
3861.1Skamil	    "Assert that tracer sees process termination before the parent");
3871.1Skamil}
3881.1Skamil
3891.26Skamilstatic void
3901.26Skamilattach1_raw(bool raw)
3911.1Skamil{
3921.1Skamil	struct msg_fds parent_tracee, parent_tracer;
3931.1Skamil	const int exitval_tracee = 5;
3941.1Skamil	const int exitval_tracer = 10;
3951.1Skamil	pid_t tracee, tracer, wpid;
3961.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3971.1Skamil#if defined(TWAIT_HAVE_STATUS)
3981.1Skamil	int status;
3991.1Skamil#endif
4001.1Skamil
4011.13Schristos	DPRINTF("Spawn tracee\n");
4021.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4031.1Skamil	tracee = atf_utils_fork();
4041.1Skamil	if (tracee == 0) {
4051.1Skamil		// Wait for parent to let us exit
4061.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
4071.1Skamil		_exit(exitval_tracee);
4081.1Skamil	}
4091.1Skamil
4101.13Schristos	DPRINTF("Spawn debugger\n");
4111.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4121.1Skamil	tracer = atf_utils_fork();
4131.1Skamil	if (tracer == 0) {
4141.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4151.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4161.1Skamil
4171.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4181.1Skamil		FORKEE_REQUIRE_SUCCESS(
4191.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4201.1Skamil
4211.1Skamil		forkee_status_stopped(status, SIGSTOP);
4221.1Skamil
4231.1Skamil		/* Resume tracee with PT_CONTINUE */
4241.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4251.1Skamil
4261.1Skamil		/* Inform parent that tracer has attached to tracee */
4271.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
4281.1Skamil
4291.1Skamil		/* Wait for parent to tell use that tracee should have exited */
4301.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
4311.1Skamil
4321.1Skamil		/* Wait for tracee and assert that it exited */
4331.1Skamil		FORKEE_REQUIRE_SUCCESS(
4341.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4351.1Skamil
4361.1Skamil		forkee_status_exited(status, exitval_tracee);
4371.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
4381.1Skamil
4391.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4401.1Skamil		_exit(exitval_tracer);
4411.1Skamil	}
4421.1Skamil
4431.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4441.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
4451.1Skamil
4461.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4471.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
4481.1Skamil
4491.13Schristos	DPRINTF("Detect that tracee is zombie\n");
4501.26Skamil	if (raw)
4511.26Skamil		await_zombie_raw(tracee, 0);
4521.26Skamil	else
4531.26Skamil		await_zombie(tracee);
4541.1Skamil
4551.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
4561.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
4571.1Skamil	    TWAIT_FNAME);
4581.1Skamil	TWAIT_REQUIRE_SUCCESS(
4591.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4601.1Skamil
4611.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
4621.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
4631.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
4641.1Skamil	    TWAIT_FNAME);
4651.1Skamil
4661.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
4671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
4681.1Skamil	    tracer);
4691.1Skamil
4701.1Skamil	validate_status_exited(status, exitval_tracer);
4711.1Skamil
4721.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4731.1Skamil	    TWAIT_FNAME);
4741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4751.1Skamil	    tracee);
4761.1Skamil
4771.1Skamil	validate_status_exited(status, exitval_tracee);
4781.1Skamil
4791.1Skamil	msg_close(&parent_tracer);
4801.1Skamil	msg_close(&parent_tracee);
4811.1Skamil}
4821.26Skamil
4831.26SkamilATF_TC_BODY(attach1, tc)
4841.26Skamil{
4851.26Skamil
4861.26Skamil	/* Reuse this test with race1 */
4871.26Skamil	attach1_raw(false);
4881.26Skamil}
4891.26Skamil
4901.1Skamil#endif
4911.1Skamil
4921.1Skamil#if defined(TWAIT_HAVE_PID)
4931.1SkamilATF_TC(attach2);
4941.1SkamilATF_TC_HEAD(attach2, tc)
4951.1Skamil{
4961.1Skamil	atf_tc_set_md_var(tc, "descr",
4971.1Skamil	    "Assert that any tracer sees process termination before its "
4981.1Skamil	    "parent");
4991.1Skamil}
5001.1Skamil
5011.1SkamilATF_TC_BODY(attach2, tc)
5021.1Skamil{
5031.1Skamil	struct msg_fds parent_tracer, parent_tracee;
5041.1Skamil	const int exitval_tracee = 5;
5051.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
5061.1Skamil	pid_t tracee, tracer, wpid;
5071.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5081.1Skamil#if defined(TWAIT_HAVE_STATUS)
5091.1Skamil	int status;
5101.1Skamil#endif
5111.1Skamil
5121.13Schristos	DPRINTF("Spawn tracee\n");
5131.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5141.1Skamil	tracee = atf_utils_fork();
5151.1Skamil	if (tracee == 0) {
5161.1Skamil		/* Wait for message from the parent */
5171.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5181.1Skamil		_exit(exitval_tracee);
5191.1Skamil	}
5201.1Skamil
5211.13Schristos	DPRINTF("Spawn debugger\n");
5221.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
5231.1Skamil	tracer = atf_utils_fork();
5241.1Skamil	if (tracer == 0) {
5251.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
5261.1Skamil		tracer = atf_utils_fork();
5271.1Skamil		if (tracer != 0)
5281.1Skamil			_exit(exitval_tracer1);
5291.1Skamil
5301.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
5311.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5321.1Skamil
5331.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
5341.1Skamil		FORKEE_REQUIRE_SUCCESS(
5351.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5361.1Skamil
5371.1Skamil		forkee_status_stopped(status, SIGSTOP);
5381.1Skamil
5391.1Skamil		/* Resume tracee with PT_CONTINUE */
5401.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5411.1Skamil
5421.1Skamil		/* Inform parent that tracer has attached to tracee */
5431.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
5441.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
5451.1Skamil
5461.1Skamil		/* Wait for tracee and assert that it exited */
5471.1Skamil		FORKEE_REQUIRE_SUCCESS(
5481.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5491.1Skamil
5501.1Skamil		forkee_status_exited(status, exitval_tracee);
5511.1Skamil
5521.13Schristos		DPRINTF("Before exiting of the tracer process\n");
5531.1Skamil		_exit(exitval_tracer2);
5541.1Skamil	}
5551.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
5561.1Skamil	    "%s()\n", TWAIT_FNAME);
5571.1Skamil	TWAIT_REQUIRE_SUCCESS(
5581.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
5591.1Skamil
5601.1Skamil	validate_status_exited(status, exitval_tracer1);
5611.1Skamil
5621.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
5631.1Skamil	    TWAIT_FNAME);
5641.1Skamil	TWAIT_REQUIRE_SUCCESS(
5651.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
5661.1Skamil
5671.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
5681.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
5691.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
5701.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5711.1Skamil
5721.13Schristos	DPRINTF("Detect that tracee is zombie\n");
5731.1Skamil	await_zombie(tracee);
5741.1Skamil
5751.13Schristos	DPRINTF("Assert that there is no status about tracee - "
5761.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
5771.1Skamil	TWAIT_REQUIRE_SUCCESS(
5781.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
5791.1Skamil
5801.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
5811.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
5821.1Skamil
5831.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5841.1Skamil	    TWAIT_FNAME);
5851.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
5861.1Skamil	    tracee);
5871.1Skamil
5881.1Skamil	validate_status_exited(status, exitval_tracee);
5891.1Skamil
5901.1Skamil	msg_close(&parent_tracer);
5911.1Skamil	msg_close(&parent_tracee);
5921.1Skamil}
5931.1Skamil#endif
5941.1Skamil
5951.1SkamilATF_TC(attach3);
5961.1SkamilATF_TC_HEAD(attach3, tc)
5971.1Skamil{
5981.1Skamil	atf_tc_set_md_var(tc, "descr",
5991.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
6001.1Skamil}
6011.1Skamil
6021.1SkamilATF_TC_BODY(attach3, tc)
6031.1Skamil{
6041.1Skamil	struct msg_fds parent_tracee;
6051.1Skamil	const int exitval_tracee = 5;
6061.1Skamil	pid_t tracee, wpid;
6071.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6081.1Skamil#if defined(TWAIT_HAVE_STATUS)
6091.1Skamil	int status;
6101.1Skamil#endif
6111.1Skamil
6121.13Schristos	DPRINTF("Spawn tracee\n");
6131.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6141.1Skamil	tracee = atf_utils_fork();
6151.1Skamil	if (tracee == 0) {
6161.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
6171.13Schristos		DPRINTF("Parent should now attach to tracee\n");
6181.1Skamil
6191.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
6201.1Skamil		/* Wait for message from the parent */
6211.1Skamil		_exit(exitval_tracee);
6221.1Skamil	}
6231.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6241.1Skamil
6251.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
6261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6271.1Skamil
6281.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
6291.1Skamil	    TWAIT_FNAME);
6301.1Skamil	TWAIT_REQUIRE_SUCCESS(
6311.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6321.1Skamil
6331.1Skamil	validate_status_stopped(status, SIGSTOP);
6341.1Skamil
6351.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
6361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6371.1Skamil
6381.13Schristos	DPRINTF("Let the tracee exit now\n");
6391.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
6401.1Skamil
6411.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
6421.1Skamil	TWAIT_REQUIRE_SUCCESS(
6431.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6441.1Skamil
6451.1Skamil	validate_status_exited(status, exitval_tracee);
6461.1Skamil
6471.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
6481.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6491.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
6501.1Skamil
6511.1Skamil	msg_close(&parent_tracee);
6521.1Skamil}
6531.1Skamil
6541.1SkamilATF_TC(attach4);
6551.1SkamilATF_TC_HEAD(attach4, tc)
6561.1Skamil{
6571.1Skamil	atf_tc_set_md_var(tc, "descr",
6581.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
6591.1Skamil}
6601.1Skamil
6611.1SkamilATF_TC_BODY(attach4, tc)
6621.1Skamil{
6631.1Skamil	struct msg_fds parent_tracee;
6641.1Skamil	const int exitval_tracer = 5;
6651.1Skamil	pid_t tracer, wpid;
6661.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6671.1Skamil#if defined(TWAIT_HAVE_STATUS)
6681.1Skamil	int status;
6691.1Skamil#endif
6701.1Skamil
6711.13Schristos	DPRINTF("Spawn tracer\n");
6721.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6731.1Skamil	tracer = atf_utils_fork();
6741.1Skamil	if (tracer == 0) {
6751.1Skamil
6761.1Skamil		/* Wait for message from the parent */
6771.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
6781.1Skamil
6791.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
6801.1Skamil		    getppid());
6811.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
6821.1Skamil
6831.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
6841.1Skamil		    TWAIT_FNAME);
6851.1Skamil		FORKEE_REQUIRE_SUCCESS(
6861.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
6871.1Skamil
6881.1Skamil		forkee_status_stopped(status, SIGSTOP);
6891.1Skamil
6901.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
6911.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
6921.1Skamil		    != -1);
6931.1Skamil
6941.1Skamil		/* Tell parent we are ready */
6951.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
6961.1Skamil
6971.1Skamil		_exit(exitval_tracer);
6981.1Skamil	}
6991.1Skamil
7001.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
7011.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
7021.13Schristos	DPRINTF("Allow the tracer to exit now\n");
7031.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
7041.1Skamil
7051.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
7061.1Skamil	TWAIT_REQUIRE_SUCCESS(
7071.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
7081.1Skamil
7091.1Skamil	validate_status_exited(status, exitval_tracer);
7101.1Skamil
7111.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
7121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
7131.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
7141.1Skamil
7151.1Skamil	msg_close(&parent_tracee);
7161.1Skamil}
7171.1Skamil
7181.1Skamil#if defined(TWAIT_HAVE_PID)
7191.1SkamilATF_TC(attach5);
7201.1SkamilATF_TC_HEAD(attach5, tc)
7211.1Skamil{
7221.1Skamil	atf_tc_set_md_var(tc, "descr",
7231.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7241.1Skamil	    "(check getppid(2))");
7251.1Skamil}
7261.1Skamil
7271.1SkamilATF_TC_BODY(attach5, tc)
7281.1Skamil{
7291.1Skamil	struct msg_fds parent_tracer, parent_tracee;
7301.1Skamil	const int exitval_tracee = 5;
7311.1Skamil	const int exitval_tracer = 10;
7321.1Skamil	pid_t parent, tracee, tracer, wpid;
7331.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7341.1Skamil#if defined(TWAIT_HAVE_STATUS)
7351.1Skamil	int status;
7361.1Skamil#endif
7371.1Skamil
7381.13Schristos	DPRINTF("Spawn tracee\n");
7391.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7401.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7411.1Skamil	tracee = atf_utils_fork();
7421.1Skamil	if (tracee == 0) {
7431.1Skamil		parent = getppid();
7441.1Skamil
7451.1Skamil		/* Emit message to the parent */
7461.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
7471.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
7481.1Skamil
7491.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
7501.1Skamil
7511.1Skamil		_exit(exitval_tracee);
7521.1Skamil	}
7531.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
7541.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
7551.1Skamil
7561.13Schristos	DPRINTF("Spawn debugger\n");
7571.1Skamil	tracer = atf_utils_fork();
7581.1Skamil	if (tracer == 0) {
7591.1Skamil		/* No IPC to communicate with the child */
7601.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
7611.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7621.1Skamil
7631.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
7641.1Skamil		FORKEE_REQUIRE_SUCCESS(
7651.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7661.1Skamil
7671.1Skamil		forkee_status_stopped(status, SIGSTOP);
7681.1Skamil
7691.1Skamil		/* Resume tracee with PT_CONTINUE */
7701.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7711.1Skamil
7721.1Skamil		/* Inform parent that tracer has attached to tracee */
7731.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
7741.1Skamil
7751.1Skamil		/* Wait for parent to tell use that tracee should have exited */
7761.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
7771.1Skamil
7781.1Skamil		/* Wait for tracee and assert that it exited */
7791.1Skamil		FORKEE_REQUIRE_SUCCESS(
7801.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7811.1Skamil
7821.1Skamil		forkee_status_exited(status, exitval_tracee);
7831.1Skamil
7841.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7851.1Skamil		_exit(exitval_tracer);
7861.1Skamil	}
7871.1Skamil
7881.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7891.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
7901.1Skamil
7911.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7921.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
7931.1Skamil
7941.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7951.1Skamil	await_zombie(tracee);
7961.1Skamil
7971.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7981.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7991.1Skamil	TWAIT_REQUIRE_SUCCESS(
8001.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8011.1Skamil
8021.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
8031.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
8041.1Skamil
8051.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
8061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8071.1Skamil	    tracer);
8081.1Skamil
8091.1Skamil	validate_status_exited(status, exitval_tracer);
8101.1Skamil
8111.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8121.1Skamil	    TWAIT_FNAME);
8131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8141.1Skamil	    tracee);
8151.1Skamil
8161.1Skamil	validate_status_exited(status, exitval_tracee);
8171.1Skamil
8181.1Skamil	msg_close(&parent_tracer);
8191.1Skamil	msg_close(&parent_tracee);
8201.1Skamil}
8211.1Skamil#endif
8221.1Skamil
8231.1Skamil#if defined(TWAIT_HAVE_PID)
8241.1SkamilATF_TC(attach6);
8251.1SkamilATF_TC_HEAD(attach6, tc)
8261.1Skamil{
8271.1Skamil	atf_tc_set_md_var(tc, "descr",
8281.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8291.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
8301.1Skamil}
8311.1Skamil
8321.1SkamilATF_TC_BODY(attach6, tc)
8331.1Skamil{
8341.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8351.1Skamil	const int exitval_tracee = 5;
8361.1Skamil	const int exitval_tracer = 10;
8371.1Skamil	pid_t parent, tracee, tracer, wpid;
8381.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8391.1Skamil#if defined(TWAIT_HAVE_STATUS)
8401.1Skamil	int status;
8411.1Skamil#endif
8421.1Skamil	int name[CTL_MAXNAME];
8431.1Skamil	struct kinfo_proc2 kp;
8441.1Skamil	size_t len = sizeof(kp);
8451.1Skamil	unsigned int namelen;
8461.1Skamil
8471.13Schristos	DPRINTF("Spawn tracee\n");
8481.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8491.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8501.1Skamil	tracee = atf_utils_fork();
8511.1Skamil	if (tracee == 0) {
8521.1Skamil		parent = getppid();
8531.1Skamil
8541.1Skamil		/* Emit message to the parent */
8551.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
8561.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
8571.1Skamil
8581.1Skamil		namelen = 0;
8591.1Skamil		name[namelen++] = CTL_KERN;
8601.1Skamil		name[namelen++] = KERN_PROC2;
8611.1Skamil		name[namelen++] = KERN_PROC_PID;
8621.1Skamil		name[namelen++] = getpid();
8631.1Skamil		name[namelen++] = len;
8641.1Skamil		name[namelen++] = 1;
8651.1Skamil
8661.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
8671.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
8681.1Skamil
8691.1Skamil		_exit(exitval_tracee);
8701.1Skamil	}
8711.1Skamil
8721.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
8731.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
8741.1Skamil
8751.13Schristos	DPRINTF("Spawn debugger\n");
8761.1Skamil	tracer = atf_utils_fork();
8771.1Skamil	if (tracer == 0) {
8781.1Skamil		/* No IPC to communicate with the child */
8791.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8801.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8811.1Skamil
8821.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8831.1Skamil		FORKEE_REQUIRE_SUCCESS(
8841.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8851.1Skamil
8861.1Skamil		forkee_status_stopped(status, SIGSTOP);
8871.1Skamil
8881.1Skamil		/* Resume tracee with PT_CONTINUE */
8891.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8901.1Skamil
8911.1Skamil		/* Inform parent that tracer has attached to tracee */
8921.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8931.1Skamil
8941.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8951.1Skamil
8961.1Skamil		/* Wait for tracee and assert that it exited */
8971.1Skamil		FORKEE_REQUIRE_SUCCESS(
8981.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8991.1Skamil
9001.1Skamil		forkee_status_exited(status, exitval_tracee);
9011.1Skamil
9021.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9031.1Skamil		_exit(exitval_tracer);
9041.1Skamil	}
9051.1Skamil
9061.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9071.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
9081.1Skamil
9091.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9101.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
9111.1Skamil
9121.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9131.1Skamil	await_zombie(tracee);
9141.1Skamil
9151.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9161.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9171.1Skamil	TWAIT_REQUIRE_SUCCESS(
9181.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9191.1Skamil
9201.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9211.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9221.1Skamil
9231.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9241.1Skamil	    TWAIT_FNAME);
9251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9261.1Skamil	    tracer);
9271.1Skamil
9281.1Skamil	validate_status_exited(status, exitval_tracer);
9291.1Skamil
9301.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9311.1Skamil	    TWAIT_FNAME);
9321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9331.1Skamil	    tracee);
9341.1Skamil
9351.1Skamil	validate_status_exited(status, exitval_tracee);
9361.1Skamil
9371.1Skamil	msg_close(&parent_tracee);
9381.1Skamil	msg_close(&parent_tracer);
9391.1Skamil}
9401.1Skamil#endif
9411.1Skamil
9421.1Skamil#if defined(TWAIT_HAVE_PID)
9431.1SkamilATF_TC(attach7);
9441.1SkamilATF_TC_HEAD(attach7, tc)
9451.1Skamil{
9461.1Skamil	atf_tc_set_md_var(tc, "descr",
9471.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
9481.1Skamil	    "(check /proc/curproc/status 3rd column)");
9491.1Skamil}
9501.1Skamil
9511.1SkamilATF_TC_BODY(attach7, tc)
9521.1Skamil{
9531.1Skamil	struct msg_fds parent_tracee, parent_tracer;
9541.1Skamil	int rv;
9551.1Skamil	const int exitval_tracee = 5;
9561.1Skamil	const int exitval_tracer = 10;
9571.1Skamil	pid_t parent, tracee, tracer, wpid;
9581.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
9591.1Skamil#if defined(TWAIT_HAVE_STATUS)
9601.1Skamil	int status;
9611.1Skamil#endif
9621.1Skamil	FILE *fp;
9631.1Skamil	struct stat st;
9641.1Skamil	const char *fname = "/proc/curproc/status";
9651.1Skamil	char s_executable[MAXPATHLEN];
9661.1Skamil	int s_pid, s_ppid;
9671.1Skamil	/*
9681.1Skamil	 * Format:
9691.1Skamil	 *  EXECUTABLE PID PPID ...
9701.1Skamil	 */
9711.1Skamil
9721.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
9731.1Skamil	if (rv != 0) {
9741.1Skamil		atf_tc_skip("/proc/curproc/status not found");
9751.1Skamil	}
9761.1Skamil
9771.13Schristos	DPRINTF("Spawn tracee\n");
9781.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9791.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
9801.1Skamil	tracee = atf_utils_fork();
9811.1Skamil	if (tracee == 0) {
9821.1Skamil		parent = getppid();
9831.1Skamil
9841.1Skamil		// Wait for parent to let us exit
9851.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
9861.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
9871.1Skamil
9881.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
9891.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
9901.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
9911.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
9921.1Skamil
9931.1Skamil		_exit(exitval_tracee);
9941.1Skamil	}
9951.1Skamil
9961.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9971.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
9981.1Skamil
9991.13Schristos	DPRINTF("Spawn debugger\n");
10001.1Skamil	tracer = atf_utils_fork();
10011.1Skamil	if (tracer == 0) {
10021.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
10031.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
10041.1Skamil
10051.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
10061.1Skamil		FORKEE_REQUIRE_SUCCESS(
10071.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10081.1Skamil
10091.1Skamil		forkee_status_stopped(status, SIGSTOP);
10101.1Skamil
10111.1Skamil		/* Resume tracee with PT_CONTINUE */
10121.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
10131.1Skamil
10141.1Skamil		/* Inform parent that tracer has attached to tracee */
10151.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
10161.1Skamil
10171.1Skamil		/* Wait for parent to tell use that tracee should have exited */
10181.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
10191.1Skamil
10201.1Skamil		/* Wait for tracee and assert that it exited */
10211.1Skamil		FORKEE_REQUIRE_SUCCESS(
10221.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10231.1Skamil
10241.1Skamil		forkee_status_exited(status, exitval_tracee);
10251.1Skamil
10261.13Schristos		DPRINTF("Before exiting of the tracer process\n");
10271.1Skamil		_exit(exitval_tracer);
10281.1Skamil	}
10291.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
10301.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
10311.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
10321.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
10331.1Skamil
10341.13Schristos	DPRINTF("Detect that tracee is zombie\n");
10351.1Skamil	await_zombie(tracee);
10361.1Skamil
10371.13Schristos	DPRINTF("Assert that there is no status about tracee - "
10381.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
10391.1Skamil	TWAIT_REQUIRE_SUCCESS(
10401.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
10411.1Skamil
10421.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
10431.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
10441.1Skamil
10451.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
10461.1Skamil	    TWAIT_FNAME);
10471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
10481.1Skamil	    tracer);
10491.1Skamil
10501.1Skamil	validate_status_exited(status, exitval_tracer);
10511.1Skamil
10521.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
10531.1Skamil	    TWAIT_FNAME);
10541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
10551.1Skamil	    tracee);
10561.1Skamil
10571.1Skamil	validate_status_exited(status, exitval_tracee);
10581.1Skamil
10591.1Skamil	msg_close(&parent_tracee);
10601.1Skamil	msg_close(&parent_tracer);
10611.1Skamil}
10621.1Skamil#endif
10631.1Skamil
10641.1SkamilATF_TC(eventmask1);
10651.1SkamilATF_TC_HEAD(eventmask1, tc)
10661.1Skamil{
10671.1Skamil	atf_tc_set_md_var(tc, "descr",
10681.1Skamil	    "Verify that empty EVENT_MASK is preserved");
10691.1Skamil}
10701.1Skamil
10711.1SkamilATF_TC_BODY(eventmask1, tc)
10721.1Skamil{
10731.1Skamil	const int exitval = 5;
10741.1Skamil	const int sigval = SIGSTOP;
10751.1Skamil	pid_t child, wpid;
10761.1Skamil#if defined(TWAIT_HAVE_STATUS)
10771.1Skamil	int status;
10781.1Skamil#endif
10791.1Skamil	ptrace_event_t set_event, get_event;
10801.1Skamil	const int len = sizeof(ptrace_event_t);
10811.1Skamil
10821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10841.1Skamil	if (child == 0) {
10851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10871.1Skamil
10881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10901.1Skamil
10911.13Schristos		DPRINTF("Before exiting of the child process\n");
10921.1Skamil		_exit(exitval);
10931.1Skamil	}
10941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10951.1Skamil
10961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10981.1Skamil
10991.1Skamil	validate_status_stopped(status, sigval);
11001.1Skamil
11011.1Skamil	set_event.pe_set_event = 0;
11021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11041.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11051.1Skamil
11061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11071.1Skamil	    "without signal to be sent\n");
11081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11091.1Skamil
11101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11121.1Skamil
11131.1Skamil	validate_status_exited(status, exitval);
11141.1Skamil
11151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11171.1Skamil}
11181.1Skamil
11191.1SkamilATF_TC(eventmask2);
11201.1SkamilATF_TC_HEAD(eventmask2, tc)
11211.1Skamil{
11221.1Skamil	atf_tc_set_md_var(tc, "descr",
11231.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
11241.1Skamil}
11251.1Skamil
11261.1SkamilATF_TC_BODY(eventmask2, tc)
11271.1Skamil{
11281.1Skamil	const int exitval = 5;
11291.1Skamil	const int sigval = SIGSTOP;
11301.1Skamil	pid_t child, wpid;
11311.1Skamil#if defined(TWAIT_HAVE_STATUS)
11321.1Skamil	int status;
11331.1Skamil#endif
11341.1Skamil	ptrace_event_t set_event, get_event;
11351.1Skamil	const int len = sizeof(ptrace_event_t);
11361.1Skamil
11371.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11381.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11391.1Skamil	if (child == 0) {
11401.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11411.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11421.1Skamil
11431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11451.1Skamil
11461.13Schristos		DPRINTF("Before exiting of the child process\n");
11471.1Skamil		_exit(exitval);
11481.1Skamil	}
11491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11501.1Skamil
11511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11531.1Skamil
11541.1Skamil	validate_status_stopped(status, sigval);
11551.1Skamil
11561.1Skamil	set_event.pe_set_event = PTRACE_FORK;
11571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11591.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11601.1Skamil
11611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11621.1Skamil	    "without signal to be sent\n");
11631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11641.1Skamil
11651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11671.1Skamil
11681.1Skamil	validate_status_exited(status, exitval);
11691.1Skamil
11701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11721.1Skamil}
11731.1Skamil
11741.1SkamilATF_TC(eventmask3);
11751.1SkamilATF_TC_HEAD(eventmask3, tc)
11761.1Skamil{
11771.1Skamil	atf_tc_set_md_var(tc, "descr",
11781.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
11791.1Skamil}
11801.1Skamil
11811.1SkamilATF_TC_BODY(eventmask3, tc)
11821.1Skamil{
11831.1Skamil	const int exitval = 5;
11841.1Skamil	const int sigval = SIGSTOP;
11851.1Skamil	pid_t child, wpid;
11861.1Skamil#if defined(TWAIT_HAVE_STATUS)
11871.1Skamil	int status;
11881.1Skamil#endif
11891.1Skamil	ptrace_event_t set_event, get_event;
11901.1Skamil	const int len = sizeof(ptrace_event_t);
11911.1Skamil
11921.14Schristos	atf_tc_expect_fail("PR kern/51630");
11931.14Schristos
11941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11961.1Skamil	if (child == 0) {
11971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11991.1Skamil
12001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12021.1Skamil
12031.13Schristos		DPRINTF("Before exiting of the child process\n");
12041.1Skamil		_exit(exitval);
12051.1Skamil	}
12061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12071.1Skamil
12081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12101.1Skamil
12111.1Skamil	validate_status_stopped(status, sigval);
12121.1Skamil
12131.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
12141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
12151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12161.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12171.1Skamil
12181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12191.1Skamil	    "without signal to be sent\n");
12201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12211.1Skamil
12221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12241.1Skamil
12251.1Skamil	validate_status_exited(status, exitval);
12261.1Skamil
12271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12281.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12291.1Skamil}
12301.1Skamil
12311.1SkamilATF_TC(eventmask4);
12321.1SkamilATF_TC_HEAD(eventmask4, tc)
12331.1Skamil{
12341.1Skamil	atf_tc_set_md_var(tc, "descr",
12351.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
12361.1Skamil}
12371.1Skamil
12381.1SkamilATF_TC_BODY(eventmask4, tc)
12391.1Skamil{
12401.1Skamil	const int exitval = 5;
12411.1Skamil	const int sigval = SIGSTOP;
12421.1Skamil	pid_t child, wpid;
12431.1Skamil#if defined(TWAIT_HAVE_STATUS)
12441.1Skamil	int status;
12451.1Skamil#endif
12461.1Skamil	ptrace_event_t set_event, get_event;
12471.1Skamil	const int len = sizeof(ptrace_event_t);
12481.1Skamil
12491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12511.1Skamil	if (child == 0) {
12521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12541.1Skamil
12551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12571.1Skamil
12581.13Schristos		DPRINTF("Before exiting of the child process\n");
12591.1Skamil		_exit(exitval);
12601.1Skamil	}
12611.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12621.1Skamil
12631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12651.1Skamil
12661.1Skamil	validate_status_stopped(status, sigval);
12671.1Skamil
12681.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
12691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12711.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12721.1Skamil
12731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12741.1Skamil	    "without signal to be sent\n");
12751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12761.1Skamil
12771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12791.1Skamil
12801.1Skamil	validate_status_exited(status, exitval);
12811.1Skamil
12821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12841.1Skamil}
12851.1Skamil
12861.1SkamilATF_TC(eventmask5);
12871.1SkamilATF_TC_HEAD(eventmask5, tc)
12881.1Skamil{
12891.1Skamil	atf_tc_set_md_var(tc, "descr",
12901.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
12911.1Skamil}
12921.1Skamil
12931.1SkamilATF_TC_BODY(eventmask5, tc)
12941.1Skamil{
12951.1Skamil	const int exitval = 5;
12961.1Skamil	const int sigval = SIGSTOP;
12971.1Skamil	pid_t child, wpid;
12981.1Skamil#if defined(TWAIT_HAVE_STATUS)
12991.1Skamil	int status;
13001.1Skamil#endif
13011.1Skamil	ptrace_event_t set_event, get_event;
13021.1Skamil	const int len = sizeof(ptrace_event_t);
13031.1Skamil
13041.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13051.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13061.1Skamil	if (child == 0) {
13071.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13081.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13091.1Skamil
13101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13121.1Skamil
13131.13Schristos		DPRINTF("Before exiting of the child process\n");
13141.1Skamil		_exit(exitval);
13151.1Skamil	}
13161.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13171.1Skamil
13181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13201.1Skamil
13211.1Skamil	validate_status_stopped(status, sigval);
13221.1Skamil
13231.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
13241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13261.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13271.1Skamil
13281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13291.1Skamil	    "without signal to be sent\n");
13301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13311.1Skamil
13321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13341.1Skamil
13351.1Skamil	validate_status_exited(status, exitval);
13361.1Skamil
13371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13391.1Skamil}
13401.1Skamil
13411.1SkamilATF_TC(eventmask6);
13421.1SkamilATF_TC_HEAD(eventmask6, tc)
13431.1Skamil{
13441.1Skamil	atf_tc_set_md_var(tc, "descr",
13451.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
13461.1Skamil}
13471.1Skamil
13481.1SkamilATF_TC_BODY(eventmask6, tc)
13491.1Skamil{
13501.1Skamil	const int exitval = 5;
13511.1Skamil	const int sigval = SIGSTOP;
13521.1Skamil	pid_t child, wpid;
13531.1Skamil#if defined(TWAIT_HAVE_STATUS)
13541.1Skamil	int status;
13551.1Skamil#endif
13561.1Skamil	ptrace_event_t set_event, get_event;
13571.1Skamil	const int len = sizeof(ptrace_event_t);
13581.1Skamil
13591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13611.1Skamil	if (child == 0) {
13621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13641.1Skamil
13651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13671.1Skamil
13681.13Schristos		DPRINTF("Before exiting of the child process\n");
13691.1Skamil		_exit(exitval);
13701.1Skamil	}
13711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13721.1Skamil
13731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13751.1Skamil
13761.1Skamil	validate_status_stopped(status, sigval);
13771.1Skamil
13781.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
13791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13811.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13821.1Skamil
13831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13841.1Skamil	    "without signal to be sent\n");
13851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13861.1Skamil
13871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13891.1Skamil
13901.1Skamil	validate_status_exited(status, exitval);
13911.1Skamil
13921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13931.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13941.1Skamil}
13951.1Skamil
13961.28Skamilstatic void
13971.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
13981.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
13991.1Skamil{
14001.1Skamil	const int exitval = 5;
14011.1Skamil	const int exitval2 = 15;
14021.1Skamil	const int sigval = SIGSTOP;
14031.31Skamil	pid_t child, child2 = 0, wpid;
14041.1Skamil#if defined(TWAIT_HAVE_STATUS)
14051.1Skamil	int status;
14061.1Skamil#endif
14071.1Skamil	ptrace_state_t state;
14081.1Skamil	const int slen = sizeof(state);
14091.1Skamil	ptrace_event_t event;
14101.1Skamil	const int elen = sizeof(event);
14111.1Skamil
14121.30Skamil	if (trackvfork) {
14131.28Skamil		atf_tc_expect_fail("PR kern/51630");
14141.28Skamil	}
14151.28Skamil
14161.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14171.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14181.1Skamil	if (child == 0) {
14191.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14201.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14211.1Skamil
14221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14241.1Skamil
14251.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
14261.1Skamil
14271.1Skamil		if (child2 == 0)
14281.1Skamil			_exit(exitval2);
14291.1Skamil
14301.1Skamil		FORKEE_REQUIRE_SUCCESS
14311.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
14321.1Skamil
14331.1Skamil		forkee_status_exited(status, exitval2);
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.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
14461.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
14471.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
14481.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
14491.30Skamil	event.pe_set_event = 0;
14501.30Skamil	if (trackfork)
14511.30Skamil		event.pe_set_event |= PTRACE_FORK;
14521.30Skamil	if (trackvfork)
14531.30Skamil		event.pe_set_event |= PTRACE_VFORK;
14541.30Skamil	if (trackvforkdone)
14551.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
14561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
14571.1Skamil
14581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14591.1Skamil	    "without signal to be sent\n");
14601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14611.1Skamil
14621.29Skamil#if defined(TWAIT_HAVE_PID)
14631.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
14641.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
14651.29Skamil		        child);
14661.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
14671.29Skamil		                      child);
14681.1Skamil
14691.29Skamil		validate_status_stopped(status, SIGTRAP);
14701.1Skamil
14711.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
14721.29Skamil		                       slen) != -1);
14731.31Skamil		if (trackfork && fn == fork) {
14741.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
14751.30Skamil			       PTRACE_FORK);
14761.30Skamil		}
14771.31Skamil		if (trackvfork && fn == vfork) {
14781.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
14791.30Skamil			       PTRACE_VFORK);
14801.30Skamil		}
14811.29Skamil
14821.29Skamil		child2 = state.pe_other_pid;
14831.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
14841.29Skamil
14851.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
14861.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
14871.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14881.29Skamil		    child2);
14891.1Skamil
14901.29Skamil		validate_status_stopped(status, SIGTRAP);
14911.1Skamil
14921.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
14931.29Skamil		                       slen) != -1);
14941.31Skamil		if (trackfork && fn == fork) {
14951.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
14961.30Skamil			       PTRACE_FORK);
14971.30Skamil		}
14981.31Skamil		if (trackvfork && fn == vfork) {
14991.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
15001.30Skamil			       PTRACE_VFORK);
15011.30Skamil		}
15021.30Skamil
15031.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
15041.29Skamil
15051.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
15061.29Skamil		    "and without signal to be sent\n");
15071.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
15081.29Skamil		                != -1);
15091.29Skamil
15101.29Skamil		DPRINTF("Before resuming the child process where it left off "
15111.29Skamil		        "and without signal to be sent\n");
15121.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15131.30Skamil	}
15141.30Skamil#endif
15151.30Skamil
15161.31Skamil	if (trackvforkdone && fn == vfork) {
15171.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
15181.30Skamil		        child);
15191.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
15201.30Skamil		                      child);
15211.30Skamil
15221.30Skamil		validate_status_stopped(status, SIGTRAP);
15231.30Skamil
15241.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
15251.30Skamil		                       slen) != -1);
15261.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
15271.30Skamil
15281.30Skamil		child2 = state.pe_other_pid;
15291.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
15301.30Skamil		        child2);
15311.30Skamil
15321.30Skamil		DPRINTF("Before resuming the child process where it left off "
15331.30Skamil		        "and without signal to be sent\n");
15341.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15351.30Skamil	}
15361.29Skamil
15371.30Skamil#if defined(TWAIT_HAVE_PID)
15381.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
15391.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
15401.29Skamil		        "\n", TWAIT_FNAME);
15411.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
15421.29Skamil		    child2);
15431.29Skamil
15441.29Skamil		validate_status_exited(status, exitval2);
15451.29Skamil
15461.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
15471.29Skamil		        "process\n", TWAIT_FNAME);
15481.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
15491.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
15501.29Skamil	}
15511.29Skamil#endif
15521.1Skamil
15531.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
15541.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
15551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15561.1Skamil
15571.1Skamil	validate_status_stopped(status, SIGCHLD);
15581.1Skamil
15591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15601.1Skamil	    "without signal to be sent\n");
15611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15621.1Skamil
15631.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
15641.1Skamil	    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 - expected no process\n",
15701.1Skamil	    TWAIT_FNAME);
15711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15721.1Skamil}
15731.28Skamil
15741.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
15751.32SkamilATF_TC(name);									\
15761.32SkamilATF_TC_HEAD(name, tc)								\
15771.32Skamil{										\
15781.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
15791.32Skamil}										\
15801.32Skamil										\
15811.32SkamilATF_TC_BODY(name, tc)								\
15821.32Skamil{										\
15831.32Skamil										\
15841.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
15851.32Skamil}
15861.32Skamil
15871.32Skamil#define F false
15881.32Skamil#define T true
15891.32Skamil
15901.32Skamil#define F_IF__0(x)
15911.32Skamil#define F_IF__1(x) x
15921.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
15931.32Skamil#define F_IF_(x,y) F_IF__(x,y)
15941.32Skamil#define F_IF(x,y) F_IF_(x,y)
15951.32Skamil
15961.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
15971.32Skamil        "Verify " #function "(2) called with 0"					\
15981.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
15991.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
16001.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
16011.32Skamil        " in EVENT_MASK."							\
16021.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
16031.32Skamil        F_IF(dparentbit," Detach parent in this test.")
16041.1Skamil
16051.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
16061.31Skamil#if defined(TWAIT_HAVE_PID)
16071.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
16081.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
16091.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
16101.31Skamil#endif
16111.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
16121.31Skamil#if defined(TWAIT_HAVE_PID)
16131.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
16141.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
16151.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
16161.31Skamil#endif
16171.1Skamil
16181.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
16191.31Skamil#if defined(TWAIT_HAVE_PID)
16201.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
16211.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
16221.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
16231.31Skamil#endif
16241.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
16251.31Skamil#if defined(TWAIT_HAVE_PID)
16261.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
16271.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
16281.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
16291.31Skamil#endif
16301.31Skamil
16311.31Skamil
16321.31Skamil
16331.1Skamil
16341.1SkamilATF_TC(io_read_d1);
16351.1SkamilATF_TC_HEAD(io_read_d1, tc)
16361.1Skamil{
16371.1Skamil	atf_tc_set_md_var(tc, "descr",
16381.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
16391.1Skamil}
16401.1Skamil
16411.1SkamilATF_TC_BODY(io_read_d1, tc)
16421.1Skamil{
16431.1Skamil	const int exitval = 5;
16441.1Skamil	const int sigval = SIGSTOP;
16451.1Skamil	pid_t child, wpid;
16461.1Skamil	uint8_t lookup_me = 0;
16471.1Skamil	const uint8_t magic = 0xab;
16481.1Skamil	struct ptrace_io_desc io = {
16491.1Skamil		.piod_op = PIOD_READ_D,
16501.1Skamil		.piod_offs = &lookup_me,
16511.1Skamil		.piod_addr = &lookup_me,
16521.1Skamil		.piod_len = sizeof(lookup_me)
16531.1Skamil	};
16541.1Skamil#if defined(TWAIT_HAVE_STATUS)
16551.1Skamil	int status;
16561.1Skamil#endif
16571.1Skamil
16581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16601.1Skamil	if (child == 0) {
16611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16631.1Skamil
16641.1Skamil		lookup_me = magic;
16651.1Skamil
16661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16681.1Skamil
16691.13Schristos		DPRINTF("Before exiting of the child process\n");
16701.1Skamil		_exit(exitval);
16711.1Skamil	}
16721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
16781.1Skamil
16791.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16801.1Skamil	    child, getpid());
16811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16821.1Skamil
16831.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16841.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
16851.1Skamil
16861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16871.1Skamil	    "without signal to be sent\n");
16881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16891.1Skamil
16901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16921.1Skamil
16931.1Skamil	validate_status_exited(status, exitval);
16941.1Skamil
16951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16971.1Skamil}
16981.1Skamil
16991.1SkamilATF_TC(io_read_d2);
17001.1SkamilATF_TC_HEAD(io_read_d2, tc)
17011.1Skamil{
17021.1Skamil	atf_tc_set_md_var(tc, "descr",
17031.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
17041.1Skamil}
17051.1Skamil
17061.1SkamilATF_TC_BODY(io_read_d2, tc)
17071.1Skamil{
17081.1Skamil	const int exitval = 5;
17091.1Skamil	const int sigval = SIGSTOP;
17101.1Skamil	pid_t child, wpid;
17111.1Skamil	uint16_t lookup_me = 0;
17121.1Skamil	const uint16_t magic = 0x1234;
17131.1Skamil	struct ptrace_io_desc io = {
17141.1Skamil		.piod_op = PIOD_READ_D,
17151.1Skamil		.piod_offs = &lookup_me,
17161.1Skamil		.piod_addr = &lookup_me,
17171.1Skamil		.piod_len = sizeof(lookup_me)
17181.1Skamil	};
17191.1Skamil#if defined(TWAIT_HAVE_STATUS)
17201.1Skamil	int status;
17211.1Skamil#endif
17221.1Skamil
17231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17251.1Skamil	if (child == 0) {
17261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17281.1Skamil
17291.1Skamil		lookup_me = magic;
17301.1Skamil
17311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17331.1Skamil
17341.13Schristos		DPRINTF("Before exiting of the child process\n");
17351.1Skamil		_exit(exitval);
17361.1Skamil	}
17371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17381.1Skamil
17391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17411.1Skamil
17421.1Skamil	validate_status_stopped(status, sigval);
17431.1Skamil
17441.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
17451.1Skamil	    child, getpid());
17461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
17471.1Skamil
17481.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
17491.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
17501.1Skamil
17511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17521.1Skamil	    "without signal to be sent\n");
17531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17541.1Skamil
17551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17571.1Skamil
17581.1Skamil	validate_status_exited(status, exitval);
17591.1Skamil
17601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17621.1Skamil}
17631.1Skamil
17641.1SkamilATF_TC(io_read_d3);
17651.1SkamilATF_TC_HEAD(io_read_d3, tc)
17661.1Skamil{
17671.1Skamil	atf_tc_set_md_var(tc, "descr",
17681.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
17691.1Skamil}
17701.1Skamil
17711.1SkamilATF_TC_BODY(io_read_d3, tc)
17721.1Skamil{
17731.1Skamil	const int exitval = 5;
17741.1Skamil	const int sigval = SIGSTOP;
17751.1Skamil	pid_t child, wpid;
17761.1Skamil	uint32_t lookup_me = 0;
17771.1Skamil	const uint32_t magic = 0x1234abcd;
17781.1Skamil	struct ptrace_io_desc io = {
17791.1Skamil		.piod_op = PIOD_READ_D,
17801.1Skamil		.piod_offs = &lookup_me,
17811.1Skamil		.piod_addr = &lookup_me,
17821.1Skamil		.piod_len = sizeof(lookup_me)
17831.1Skamil	};
17841.1Skamil#if defined(TWAIT_HAVE_STATUS)
17851.1Skamil	int status;
17861.1Skamil#endif
17871.1Skamil
17881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17901.1Skamil	if (child == 0) {
17911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17931.1Skamil
17941.1Skamil		lookup_me = magic;
17951.1Skamil
17961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17981.1Skamil
17991.13Schristos		DPRINTF("Before exiting of the child process\n");
18001.1Skamil		_exit(exitval);
18011.1Skamil	}
18021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18031.1Skamil
18041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18061.1Skamil
18071.1Skamil	validate_status_stopped(status, sigval);
18081.1Skamil
18091.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
18101.1Skamil	    child, getpid());
18111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18121.1Skamil
18131.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
18141.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
18151.1Skamil
18161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18171.1Skamil	    "without signal to be sent\n");
18181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18191.1Skamil
18201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18221.1Skamil
18231.1Skamil	validate_status_exited(status, exitval);
18241.1Skamil
18251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18271.1Skamil}
18281.1Skamil
18291.1SkamilATF_TC(io_read_d4);
18301.1SkamilATF_TC_HEAD(io_read_d4, tc)
18311.1Skamil{
18321.1Skamil	atf_tc_set_md_var(tc, "descr",
18331.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
18341.1Skamil}
18351.1Skamil
18361.1SkamilATF_TC_BODY(io_read_d4, tc)
18371.1Skamil{
18381.1Skamil	const int exitval = 5;
18391.1Skamil	const int sigval = SIGSTOP;
18401.1Skamil	pid_t child, wpid;
18411.1Skamil	uint64_t lookup_me = 0;
18421.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
18431.1Skamil	struct ptrace_io_desc io = {
18441.1Skamil		.piod_op = PIOD_READ_D,
18451.1Skamil		.piod_offs = &lookup_me,
18461.1Skamil		.piod_addr = &lookup_me,
18471.1Skamil		.piod_len = sizeof(lookup_me)
18481.1Skamil	};
18491.1Skamil#if defined(TWAIT_HAVE_STATUS)
18501.1Skamil	int status;
18511.1Skamil#endif
18521.1Skamil
18531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18551.1Skamil	if (child == 0) {
18561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18581.1Skamil
18591.1Skamil		lookup_me = magic;
18601.1Skamil
18611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18631.1Skamil
18641.13Schristos		DPRINTF("Before exiting of the child process\n");
18651.1Skamil		_exit(exitval);
18661.1Skamil	}
18671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18681.1Skamil
18691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18711.1Skamil
18721.1Skamil	validate_status_stopped(status, sigval);
18731.1Skamil
18741.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
18751.1Skamil	    child, getpid());
18761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18771.1Skamil
18781.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
18791.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
18801.1Skamil
18811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18821.1Skamil	    "without signal to be sent\n");
18831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18841.1Skamil
18851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18871.1Skamil
18881.1Skamil	validate_status_exited(status, exitval);
18891.1Skamil
18901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18921.1Skamil}
18931.1Skamil
18941.1SkamilATF_TC(io_write_d1);
18951.1SkamilATF_TC_HEAD(io_write_d1, tc)
18961.1Skamil{
18971.1Skamil	atf_tc_set_md_var(tc, "descr",
18981.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
18991.1Skamil}
19001.1Skamil
19011.1SkamilATF_TC_BODY(io_write_d1, tc)
19021.1Skamil{
19031.1Skamil	const int exitval = 5;
19041.1Skamil	const int sigval = SIGSTOP;
19051.1Skamil	pid_t child, wpid;
19061.1Skamil	uint8_t lookup_me = 0;
19071.1Skamil	const uint8_t magic = 0xab;
19081.1Skamil	struct ptrace_io_desc io = {
19091.1Skamil		.piod_op = PIOD_WRITE_D,
19101.1Skamil		.piod_offs = &lookup_me,
19111.1Skamil		.piod_addr = &lookup_me,
19121.1Skamil		.piod_len = sizeof(lookup_me)
19131.1Skamil	};
19141.1Skamil#if defined(TWAIT_HAVE_STATUS)
19151.1Skamil	int status;
19161.1Skamil#endif
19171.1Skamil
19181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19201.1Skamil	if (child == 0) {
19211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19231.1Skamil
19241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19261.1Skamil
19271.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19281.1Skamil
19291.13Schristos		DPRINTF("Before exiting of the child process\n");
19301.1Skamil		_exit(exitval);
19311.1Skamil	}
19321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19331.1Skamil
19341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19361.1Skamil
19371.1Skamil	validate_status_stopped(status, sigval);
19381.1Skamil
19391.1Skamil	lookup_me = magic;
19401.1Skamil
19411.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
19421.1Skamil	    child, getpid());
19431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19441.1Skamil
19451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19461.1Skamil	    "without signal to be sent\n");
19471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19481.1Skamil
19491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19511.1Skamil
19521.1Skamil	validate_status_exited(status, exitval);
19531.1Skamil
19541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19561.1Skamil}
19571.1Skamil
19581.1SkamilATF_TC(io_write_d2);
19591.1SkamilATF_TC_HEAD(io_write_d2, tc)
19601.1Skamil{
19611.1Skamil	atf_tc_set_md_var(tc, "descr",
19621.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
19631.1Skamil}
19641.1Skamil
19651.1SkamilATF_TC_BODY(io_write_d2, tc)
19661.1Skamil{
19671.1Skamil	const int exitval = 5;
19681.1Skamil	const int sigval = SIGSTOP;
19691.1Skamil	pid_t child, wpid;
19701.1Skamil	uint16_t lookup_me = 0;
19711.1Skamil	const uint16_t magic = 0xab12;
19721.1Skamil	struct ptrace_io_desc io = {
19731.1Skamil		.piod_op = PIOD_WRITE_D,
19741.1Skamil		.piod_offs = &lookup_me,
19751.1Skamil		.piod_addr = &lookup_me,
19761.1Skamil		.piod_len = sizeof(lookup_me)
19771.1Skamil	};
19781.1Skamil#if defined(TWAIT_HAVE_STATUS)
19791.1Skamil	int status;
19801.1Skamil#endif
19811.1Skamil
19821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19841.1Skamil	if (child == 0) {
19851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19871.1Skamil
19881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19901.1Skamil
19911.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19921.1Skamil
19931.13Schristos		DPRINTF("Before exiting of the child process\n");
19941.1Skamil		_exit(exitval);
19951.1Skamil	}
19961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19971.1Skamil
19981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20001.1Skamil
20011.1Skamil	validate_status_stopped(status, sigval);
20021.1Skamil
20031.1Skamil	lookup_me = magic;
20041.1Skamil
20051.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20061.1Skamil	    child, getpid());
20071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20081.1Skamil
20091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20101.1Skamil	    "without signal to be sent\n");
20111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20121.1Skamil
20131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20151.1Skamil
20161.1Skamil	validate_status_exited(status, exitval);
20171.1Skamil
20181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20201.1Skamil}
20211.1Skamil
20221.1SkamilATF_TC(io_write_d3);
20231.1SkamilATF_TC_HEAD(io_write_d3, tc)
20241.1Skamil{
20251.1Skamil	atf_tc_set_md_var(tc, "descr",
20261.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
20271.1Skamil}
20281.1Skamil
20291.1SkamilATF_TC_BODY(io_write_d3, tc)
20301.1Skamil{
20311.1Skamil	const int exitval = 5;
20321.1Skamil	const int sigval = SIGSTOP;
20331.1Skamil	pid_t child, wpid;
20341.1Skamil	uint32_t lookup_me = 0;
20351.1Skamil	const uint32_t magic = 0xab127643;
20361.1Skamil	struct ptrace_io_desc io = {
20371.1Skamil		.piod_op = PIOD_WRITE_D,
20381.1Skamil		.piod_offs = &lookup_me,
20391.1Skamil		.piod_addr = &lookup_me,
20401.1Skamil		.piod_len = sizeof(lookup_me)
20411.1Skamil	};
20421.1Skamil#if defined(TWAIT_HAVE_STATUS)
20431.1Skamil	int status;
20441.1Skamil#endif
20451.1Skamil
20461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20481.1Skamil	if (child == 0) {
20491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20511.1Skamil
20521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20541.1Skamil
20551.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
20561.1Skamil
20571.13Schristos		DPRINTF("Before exiting of the child process\n");
20581.1Skamil		_exit(exitval);
20591.1Skamil	}
20601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20611.1Skamil
20621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20641.1Skamil
20651.1Skamil	validate_status_stopped(status, sigval);
20661.1Skamil
20671.1Skamil	lookup_me = magic;
20681.1Skamil
20691.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20701.1Skamil	    child, getpid());
20711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20721.1Skamil
20731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20741.1Skamil	    "without signal to be sent\n");
20751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20761.1Skamil
20771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20791.1Skamil
20801.1Skamil	validate_status_exited(status, exitval);
20811.1Skamil
20821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20841.1Skamil}
20851.1Skamil
20861.1SkamilATF_TC(io_write_d4);
20871.1SkamilATF_TC_HEAD(io_write_d4, tc)
20881.1Skamil{
20891.1Skamil	atf_tc_set_md_var(tc, "descr",
20901.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
20911.1Skamil}
20921.1Skamil
20931.1SkamilATF_TC_BODY(io_write_d4, tc)
20941.1Skamil{
20951.1Skamil	const int exitval = 5;
20961.1Skamil	const int sigval = SIGSTOP;
20971.1Skamil	pid_t child, wpid;
20981.1Skamil	uint64_t lookup_me = 0;
20991.1Skamil	const uint64_t magic = 0xab12764376490123;
21001.1Skamil	struct ptrace_io_desc io = {
21011.1Skamil		.piod_op = PIOD_WRITE_D,
21021.1Skamil		.piod_offs = &lookup_me,
21031.1Skamil		.piod_addr = &lookup_me,
21041.1Skamil		.piod_len = sizeof(lookup_me)
21051.1Skamil	};
21061.1Skamil#if defined(TWAIT_HAVE_STATUS)
21071.1Skamil	int status;
21081.1Skamil#endif
21091.1Skamil
21101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21121.1Skamil	if (child == 0) {
21131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21151.1Skamil
21161.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21171.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21181.1Skamil
21191.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
21201.1Skamil
21211.13Schristos		DPRINTF("Before exiting of the child process\n");
21221.1Skamil		_exit(exitval);
21231.1Skamil	}
21241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21251.1Skamil
21261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21281.1Skamil
21291.1Skamil	validate_status_stopped(status, sigval);
21301.1Skamil
21311.1Skamil	lookup_me = magic;
21321.1Skamil
21331.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
21341.1Skamil	    child, getpid());
21351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21361.1Skamil
21371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21381.1Skamil	    "without signal to be sent\n");
21391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21401.1Skamil
21411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21431.1Skamil
21441.1Skamil	validate_status_exited(status, exitval);
21451.1Skamil
21461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21481.1Skamil}
21491.1Skamil
21501.1SkamilATF_TC(io_read_auxv1);
21511.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
21521.1Skamil{
21531.1Skamil	atf_tc_set_md_var(tc, "descr",
21541.1Skamil	    "Verify PT_READ_AUXV called for tracee");
21551.1Skamil}
21561.1Skamil
21571.1SkamilATF_TC_BODY(io_read_auxv1, tc)
21581.1Skamil{
21591.1Skamil	const int exitval = 5;
21601.1Skamil	const int sigval = SIGSTOP;
21611.1Skamil	pid_t child, wpid;
21621.1Skamil#if defined(TWAIT_HAVE_STATUS)
21631.1Skamil	int status;
21641.1Skamil#endif
21651.1Skamil	AuxInfo ai[100], *aip;
21661.1Skamil	struct ptrace_io_desc io = {
21671.1Skamil		.piod_op = PIOD_READ_AUXV,
21681.1Skamil		.piod_offs = 0,
21691.1Skamil		.piod_addr = ai,
21701.1Skamil		.piod_len = sizeof(ai)
21711.1Skamil	};
21721.1Skamil
21731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21751.1Skamil	if (child == 0) {
21761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21781.1Skamil
21791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21811.1Skamil
21821.13Schristos		DPRINTF("Before exiting of the child process\n");
21831.1Skamil		_exit(exitval);
21841.1Skamil	}
21851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21861.1Skamil
21871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21891.1Skamil
21901.1Skamil	validate_status_stopped(status, sigval);
21911.1Skamil
21921.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
21931.1Skamil	    child, getpid());
21941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21951.1Skamil
21961.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
21971.1Skamil	ATF_REQUIRE(io.piod_len > 0);
21981.1Skamil
21991.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
22001.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
22011.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
22021.1Skamil
22031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22041.1Skamil	    "without signal to be sent\n");
22051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22061.1Skamil
22071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22091.1Skamil
22101.1Skamil	validate_status_exited(status, exitval);
22111.1Skamil
22121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22141.1Skamil}
22151.1Skamil
22161.1SkamilATF_TC(read_d1);
22171.1SkamilATF_TC_HEAD(read_d1, tc)
22181.1Skamil{
22191.1Skamil	atf_tc_set_md_var(tc, "descr",
22201.1Skamil	    "Verify PT_READ_D called once");
22211.1Skamil}
22221.1Skamil
22231.1SkamilATF_TC_BODY(read_d1, tc)
22241.1Skamil{
22251.1Skamil	const int exitval = 5;
22261.1Skamil	const int sigval = SIGSTOP;
22271.1Skamil	pid_t child, wpid;
22281.1Skamil	int lookup_me = 0;
22291.1Skamil	const int magic = (int)random();
22301.1Skamil#if defined(TWAIT_HAVE_STATUS)
22311.1Skamil	int status;
22321.1Skamil#endif
22331.1Skamil
22341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22361.1Skamil	if (child == 0) {
22371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22391.1Skamil
22401.1Skamil		lookup_me = magic;
22411.1Skamil
22421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22441.1Skamil
22451.13Schristos		DPRINTF("Before exiting of the child process\n");
22461.1Skamil		_exit(exitval);
22471.1Skamil	}
22481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22491.1Skamil
22501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22521.1Skamil
22531.1Skamil	validate_status_stopped(status, sigval);
22541.1Skamil
22551.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
22561.1Skamil	    child, getpid());
22571.1Skamil	errno = 0;
22581.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
22591.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22601.1Skamil
22611.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
22621.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
22631.1Skamil
22641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22651.1Skamil	    "without signal to be sent\n");
22661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22671.1Skamil
22681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22701.1Skamil
22711.1Skamil	validate_status_exited(status, exitval);
22721.1Skamil
22731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22751.1Skamil}
22761.1Skamil
22771.1SkamilATF_TC(read_d2);
22781.1SkamilATF_TC_HEAD(read_d2, tc)
22791.1Skamil{
22801.1Skamil	atf_tc_set_md_var(tc, "descr",
22811.1Skamil	    "Verify PT_READ_D called twice");
22821.1Skamil}
22831.1Skamil
22841.1SkamilATF_TC_BODY(read_d2, tc)
22851.1Skamil{
22861.1Skamil	const int exitval = 5;
22871.1Skamil	const int sigval = SIGSTOP;
22881.1Skamil	pid_t child, wpid;
22891.1Skamil	int lookup_me1 = 0;
22901.1Skamil	int lookup_me2 = 0;
22911.1Skamil	const int magic1 = (int)random();
22921.1Skamil	const int magic2 = (int)random();
22931.1Skamil#if defined(TWAIT_HAVE_STATUS)
22941.1Skamil	int status;
22951.1Skamil#endif
22961.1Skamil
22971.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22981.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22991.1Skamil	if (child == 0) {
23001.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23011.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23021.1Skamil
23031.1Skamil		lookup_me1 = magic1;
23041.1Skamil		lookup_me2 = magic2;
23051.1Skamil
23061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23081.1Skamil
23091.13Schristos		DPRINTF("Before exiting of the child process\n");
23101.1Skamil		_exit(exitval);
23111.1Skamil	}
23121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23131.1Skamil
23141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23161.1Skamil
23171.1Skamil	validate_status_stopped(status, sigval);
23181.1Skamil
23191.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
23201.1Skamil	    child, getpid());
23211.1Skamil	errno = 0;
23221.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
23231.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23241.1Skamil
23251.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
23261.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
23271.1Skamil
23281.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
23291.1Skamil	    child, getpid());
23301.1Skamil	errno = 0;
23311.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
23321.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23331.1Skamil
23341.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
23351.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
23361.1Skamil
23371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23381.1Skamil	    "without signal to be sent\n");
23391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23401.1Skamil
23411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23431.1Skamil
23441.1Skamil	validate_status_exited(status, exitval);
23451.1Skamil
23461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23481.1Skamil}
23491.1Skamil
23501.1SkamilATF_TC(read_d3);
23511.1SkamilATF_TC_HEAD(read_d3, tc)
23521.1Skamil{
23531.1Skamil	atf_tc_set_md_var(tc, "descr",
23541.1Skamil	    "Verify PT_READ_D called three times");
23551.1Skamil}
23561.1Skamil
23571.1SkamilATF_TC_BODY(read_d3, tc)
23581.1Skamil{
23591.1Skamil	const int exitval = 5;
23601.1Skamil	const int sigval = SIGSTOP;
23611.1Skamil	pid_t child, wpid;
23621.1Skamil	int lookup_me1 = 0;
23631.1Skamil	int lookup_me2 = 0;
23641.1Skamil	int lookup_me3 = 0;
23651.1Skamil	const int magic1 = (int)random();
23661.1Skamil	const int magic2 = (int)random();
23671.1Skamil	const int magic3 = (int)random();
23681.1Skamil#if defined(TWAIT_HAVE_STATUS)
23691.1Skamil	int status;
23701.1Skamil#endif
23711.1Skamil
23721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23741.1Skamil	if (child == 0) {
23751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23771.1Skamil
23781.1Skamil		lookup_me1 = magic1;
23791.1Skamil		lookup_me2 = magic2;
23801.1Skamil		lookup_me3 = magic3;
23811.1Skamil
23821.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23831.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23841.1Skamil
23851.13Schristos		DPRINTF("Before exiting of the child process\n");
23861.1Skamil		_exit(exitval);
23871.1Skamil	}
23881.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23891.1Skamil
23901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23921.1Skamil
23931.1Skamil	validate_status_stopped(status, sigval);
23941.1Skamil
23951.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
23961.1Skamil	    child, getpid());
23971.1Skamil	errno = 0;
23981.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
23991.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24001.1Skamil
24011.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
24021.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
24031.1Skamil
24041.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
24051.1Skamil	    child, getpid());
24061.1Skamil	errno = 0;
24071.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
24081.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24091.1Skamil
24101.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
24111.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
24121.1Skamil
24131.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
24141.1Skamil	    child, getpid());
24151.1Skamil	errno = 0;
24161.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
24171.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24181.1Skamil
24191.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
24201.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
24211.1Skamil
24221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24231.1Skamil	    "without signal to be sent\n");
24241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24251.1Skamil
24261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24281.1Skamil
24291.1Skamil	validate_status_exited(status, exitval);
24301.1Skamil
24311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24331.1Skamil}
24341.1Skamil
24351.1SkamilATF_TC(read_d4);
24361.1SkamilATF_TC_HEAD(read_d4, tc)
24371.1Skamil{
24381.1Skamil	atf_tc_set_md_var(tc, "descr",
24391.1Skamil	    "Verify PT_READ_D called four times");
24401.1Skamil}
24411.1Skamil
24421.1SkamilATF_TC_BODY(read_d4, tc)
24431.1Skamil{
24441.1Skamil	const int exitval = 5;
24451.1Skamil	const int sigval = SIGSTOP;
24461.1Skamil	pid_t child, wpid;
24471.1Skamil	int lookup_me1 = 0;
24481.1Skamil	int lookup_me2 = 0;
24491.1Skamil	int lookup_me3 = 0;
24501.1Skamil	int lookup_me4 = 0;
24511.1Skamil	const int magic1 = (int)random();
24521.1Skamil	const int magic2 = (int)random();
24531.1Skamil	const int magic3 = (int)random();
24541.1Skamil	const int magic4 = (int)random();
24551.1Skamil#if defined(TWAIT_HAVE_STATUS)
24561.1Skamil	int status;
24571.1Skamil#endif
24581.1Skamil
24591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24611.1Skamil	if (child == 0) {
24621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24641.1Skamil
24651.1Skamil		lookup_me1 = magic1;
24661.1Skamil		lookup_me2 = magic2;
24671.1Skamil		lookup_me3 = magic3;
24681.1Skamil		lookup_me4 = magic4;
24691.1Skamil
24701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24721.1Skamil
24731.13Schristos		DPRINTF("Before exiting of the child process\n");
24741.1Skamil		_exit(exitval);
24751.1Skamil	}
24761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24771.1Skamil
24781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24801.1Skamil
24811.1Skamil	validate_status_stopped(status, sigval);
24821.1Skamil
24831.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
24841.1Skamil	    child, getpid());
24851.1Skamil	errno = 0;
24861.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
24871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24881.1Skamil
24891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
24901.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
24911.1Skamil
24921.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
24931.1Skamil	    child, getpid());
24941.1Skamil	errno = 0;
24951.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
24961.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24971.1Skamil
24981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
24991.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
25001.1Skamil
25011.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
25021.1Skamil	    child, getpid());
25031.1Skamil	errno = 0;
25041.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
25051.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25061.1Skamil
25071.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
25081.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
25091.1Skamil
25101.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
25111.1Skamil	    child, getpid());
25121.1Skamil	errno = 0;
25131.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
25141.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25151.1Skamil
25161.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
25171.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
25181.1Skamil
25191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25201.1Skamil	    "without signal to be sent\n");
25211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25221.1Skamil
25231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25251.1Skamil
25261.1Skamil	validate_status_exited(status, exitval);
25271.1Skamil
25281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25301.1Skamil}
25311.1Skamil
25321.1SkamilATF_TC(write_d1);
25331.1SkamilATF_TC_HEAD(write_d1, tc)
25341.1Skamil{
25351.1Skamil	atf_tc_set_md_var(tc, "descr",
25361.1Skamil	    "Verify PT_WRITE_D called once");
25371.1Skamil}
25381.1Skamil
25391.1SkamilATF_TC_BODY(write_d1, tc)
25401.1Skamil{
25411.1Skamil	const int exitval = 5;
25421.1Skamil	const int sigval = SIGSTOP;
25431.1Skamil	pid_t child, wpid;
25441.1Skamil	int lookup_me = 0;
25451.1Skamil	const int magic = (int)random();
25461.1Skamil#if defined(TWAIT_HAVE_STATUS)
25471.1Skamil	int status;
25481.1Skamil#endif
25491.1Skamil
25501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25521.1Skamil	if (child == 0) {
25531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25551.1Skamil
25561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25581.1Skamil
25591.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
25601.1Skamil
25611.13Schristos		DPRINTF("Before exiting of the child process\n");
25621.1Skamil		_exit(exitval);
25631.1Skamil	}
25641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25651.1Skamil
25661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25681.1Skamil
25691.1Skamil	validate_status_stopped(status, sigval);
25701.1Skamil
25711.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
25721.1Skamil	    child, getpid());
25731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
25741.1Skamil
25751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25761.1Skamil	    "without signal to be sent\n");
25771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25781.1Skamil
25791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25811.1Skamil
25821.1Skamil	validate_status_exited(status, exitval);
25831.1Skamil
25841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25861.1Skamil}
25871.1Skamil
25881.1SkamilATF_TC(write_d2);
25891.1SkamilATF_TC_HEAD(write_d2, tc)
25901.1Skamil{
25911.1Skamil	atf_tc_set_md_var(tc, "descr",
25921.1Skamil	    "Verify PT_WRITE_D called twice");
25931.1Skamil}
25941.1Skamil
25951.1SkamilATF_TC_BODY(write_d2, tc)
25961.1Skamil{
25971.1Skamil	const int exitval = 5;
25981.1Skamil	const int sigval = SIGSTOP;
25991.1Skamil	pid_t child, wpid;
26001.1Skamil	int lookup_me1 = 0;
26011.1Skamil	int lookup_me2 = 0;
26021.1Skamil	const int magic1 = (int)random();
26031.1Skamil	const int magic2 = (int)random();
26041.1Skamil#if defined(TWAIT_HAVE_STATUS)
26051.1Skamil	int status;
26061.1Skamil#endif
26071.1Skamil
26081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26101.1Skamil	if (child == 0) {
26111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26131.1Skamil
26141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26161.1Skamil
26171.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26181.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26191.1Skamil
26201.13Schristos		DPRINTF("Before exiting of the child process\n");
26211.1Skamil		_exit(exitval);
26221.1Skamil	}
26231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26241.1Skamil
26251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26271.1Skamil
26281.1Skamil	validate_status_stopped(status, sigval);
26291.1Skamil
26301.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
26311.1Skamil	    child, getpid());
26321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
26331.1Skamil
26341.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
26351.1Skamil	    child, getpid());
26361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
26371.1Skamil
26381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26391.1Skamil	    "without signal to be sent\n");
26401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26411.1Skamil
26421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26441.1Skamil
26451.1Skamil	validate_status_exited(status, exitval);
26461.1Skamil
26471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26481.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26491.1Skamil}
26501.1Skamil
26511.1SkamilATF_TC(write_d3);
26521.1SkamilATF_TC_HEAD(write_d3, tc)
26531.1Skamil{
26541.1Skamil	atf_tc_set_md_var(tc, "descr",
26551.1Skamil	    "Verify PT_WRITE_D called three times");
26561.1Skamil}
26571.1Skamil
26581.1SkamilATF_TC_BODY(write_d3, tc)
26591.1Skamil{
26601.1Skamil	const int exitval = 5;
26611.1Skamil	const int sigval = SIGSTOP;
26621.1Skamil	pid_t child, wpid;
26631.1Skamil	int lookup_me1 = 0;
26641.1Skamil	int lookup_me2 = 0;
26651.1Skamil	int lookup_me3 = 0;
26661.1Skamil	const int magic1 = (int)random();
26671.1Skamil	const int magic2 = (int)random();
26681.1Skamil	const int magic3 = (int)random();
26691.1Skamil#if defined(TWAIT_HAVE_STATUS)
26701.1Skamil	int status;
26711.1Skamil#endif
26721.1Skamil
26731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26751.1Skamil	if (child == 0) {
26761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26781.1Skamil
26791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26811.1Skamil
26821.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26831.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26841.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
26851.1Skamil
26861.13Schristos		DPRINTF("Before exiting of the child process\n");
26871.1Skamil		_exit(exitval);
26881.1Skamil	}
26891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26901.1Skamil
26911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26931.1Skamil
26941.1Skamil	validate_status_stopped(status, sigval);
26951.1Skamil
26961.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
26971.1Skamil	    child, getpid());
26981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
26991.1Skamil
27001.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
27011.1Skamil	    child, getpid());
27021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
27031.1Skamil
27041.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
27051.1Skamil	    child, getpid());
27061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
27071.1Skamil
27081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27091.1Skamil	    "without signal to be sent\n");
27101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27111.1Skamil
27121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27141.1Skamil
27151.1Skamil	validate_status_exited(status, exitval);
27161.1Skamil
27171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27191.1Skamil}
27201.1Skamil
27211.1SkamilATF_TC(write_d4);
27221.1SkamilATF_TC_HEAD(write_d4, tc)
27231.1Skamil{
27241.1Skamil	atf_tc_set_md_var(tc, "descr",
27251.1Skamil	    "Verify PT_WRITE_D called four times");
27261.1Skamil}
27271.1Skamil
27281.1SkamilATF_TC_BODY(write_d4, tc)
27291.1Skamil{
27301.1Skamil	const int exitval = 5;
27311.1Skamil	const int sigval = SIGSTOP;
27321.1Skamil	pid_t child, wpid;
27331.1Skamil	int lookup_me1 = 0;
27341.1Skamil	int lookup_me2 = 0;
27351.1Skamil	int lookup_me3 = 0;
27361.1Skamil	int lookup_me4 = 0;
27371.1Skamil	const int magic1 = (int)random();
27381.1Skamil	const int magic2 = (int)random();
27391.1Skamil	const int magic3 = (int)random();
27401.1Skamil	const int magic4 = (int)random();
27411.1Skamil#if defined(TWAIT_HAVE_STATUS)
27421.1Skamil	int status;
27431.1Skamil#endif
27441.1Skamil
27451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27471.1Skamil	if (child == 0) {
27481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27501.1Skamil
27511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27531.1Skamil
27541.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
27551.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
27561.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
27571.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
27581.1Skamil
27591.13Schristos		DPRINTF("Before exiting of the child process\n");
27601.1Skamil		_exit(exitval);
27611.1Skamil	}
27621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27631.1Skamil
27641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27661.1Skamil
27671.1Skamil	validate_status_stopped(status, sigval);
27681.1Skamil
27691.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
27701.1Skamil	    child, getpid());
27711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
27721.1Skamil
27731.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
27741.1Skamil	    child, getpid());
27751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
27761.1Skamil
27771.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
27781.1Skamil	    child, getpid());
27791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
27801.1Skamil
27811.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
27821.1Skamil	    child, getpid());
27831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
27841.1Skamil
27851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27861.1Skamil	    "without signal to be sent\n");
27871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27881.1Skamil
27891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27911.1Skamil
27921.1Skamil	validate_status_exited(status, exitval);
27931.1Skamil
27941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27961.1Skamil}
27971.1Skamil
27981.1SkamilATF_TC(io_read_d_write_d_handshake1);
27991.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
28001.1Skamil{
28011.1Skamil	atf_tc_set_md_var(tc, "descr",
28021.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
28031.1Skamil}
28041.1Skamil
28051.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
28061.1Skamil{
28071.1Skamil	const int exitval = 5;
28081.1Skamil	const int sigval = SIGSTOP;
28091.1Skamil	pid_t child, wpid;
28101.1Skamil	uint8_t lookup_me_fromtracee = 0;
28111.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
28121.1Skamil	uint8_t lookup_me_totracee = 0;
28131.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
28141.1Skamil	struct ptrace_io_desc io_fromtracee = {
28151.1Skamil		.piod_op = PIOD_READ_D,
28161.1Skamil		.piod_offs = &lookup_me_fromtracee,
28171.1Skamil		.piod_addr = &lookup_me_fromtracee,
28181.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
28191.1Skamil	};
28201.1Skamil	struct ptrace_io_desc io_totracee = {
28211.1Skamil		.piod_op = PIOD_WRITE_D,
28221.1Skamil		.piod_offs = &lookup_me_totracee,
28231.1Skamil		.piod_addr = &lookup_me_totracee,
28241.1Skamil		.piod_len = sizeof(lookup_me_totracee)
28251.1Skamil	};
28261.1Skamil#if defined(TWAIT_HAVE_STATUS)
28271.1Skamil	int status;
28281.1Skamil#endif
28291.1Skamil
28301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28321.1Skamil	if (child == 0) {
28331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28351.1Skamil
28361.1Skamil		lookup_me_fromtracee = magic_fromtracee;
28371.1Skamil
28381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28401.1Skamil
28411.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
28421.1Skamil
28431.13Schristos		DPRINTF("Before exiting of the child process\n");
28441.1Skamil		_exit(exitval);
28451.1Skamil	}
28461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28471.1Skamil
28481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28501.1Skamil
28511.1Skamil	validate_status_stopped(status, sigval);
28521.1Skamil
28531.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
28541.1Skamil	    child, getpid());
28551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
28561.1Skamil
28571.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
28581.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
28591.1Skamil	    magic_fromtracee);
28601.1Skamil
28611.1Skamil	lookup_me_totracee = magic_totracee;
28621.1Skamil
28631.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
28641.1Skamil	    child, getpid());
28651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
28661.1Skamil
28671.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
28681.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
28691.1Skamil	    magic_totracee);
28701.1Skamil
28711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28721.1Skamil	    "without signal to be sent\n");
28731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28741.1Skamil
28751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28771.1Skamil
28781.1Skamil	validate_status_exited(status, exitval);
28791.1Skamil
28801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28811.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28821.1Skamil}
28831.1Skamil
28841.1SkamilATF_TC(io_read_d_write_d_handshake2);
28851.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
28861.1Skamil{
28871.1Skamil	atf_tc_set_md_var(tc, "descr",
28881.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
28891.1Skamil}
28901.1Skamil
28911.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
28921.1Skamil{
28931.1Skamil	const int exitval = 5;
28941.1Skamil	const int sigval = SIGSTOP;
28951.1Skamil	pid_t child, wpid;
28961.1Skamil	uint8_t lookup_me_fromtracee = 0;
28971.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
28981.1Skamil	uint8_t lookup_me_totracee = 0;
28991.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
29001.1Skamil	struct ptrace_io_desc io_fromtracee = {
29011.1Skamil		.piod_op = PIOD_READ_D,
29021.1Skamil		.piod_offs = &lookup_me_fromtracee,
29031.1Skamil		.piod_addr = &lookup_me_fromtracee,
29041.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
29051.1Skamil	};
29061.1Skamil	struct ptrace_io_desc io_totracee = {
29071.1Skamil		.piod_op = PIOD_WRITE_D,
29081.1Skamil		.piod_offs = &lookup_me_totracee,
29091.1Skamil		.piod_addr = &lookup_me_totracee,
29101.1Skamil		.piod_len = sizeof(lookup_me_totracee)
29111.1Skamil	};
29121.1Skamil#if defined(TWAIT_HAVE_STATUS)
29131.1Skamil	int status;
29141.1Skamil#endif
29151.1Skamil
29161.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29171.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29181.1Skamil	if (child == 0) {
29191.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29201.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29211.1Skamil
29221.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29231.1Skamil
29241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29261.1Skamil
29271.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
29281.1Skamil
29291.13Schristos		DPRINTF("Before exiting of the child process\n");
29301.1Skamil		_exit(exitval);
29311.1Skamil	}
29321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29331.1Skamil
29341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29361.1Skamil
29371.1Skamil	validate_status_stopped(status, sigval);
29381.1Skamil
29391.1Skamil	lookup_me_totracee = magic_totracee;
29401.1Skamil
29411.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
29421.1Skamil	    child, getpid());
29431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
29441.1Skamil
29451.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
29461.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
29471.1Skamil	    magic_totracee);
29481.1Skamil
29491.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
29501.1Skamil	    child, getpid());
29511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
29521.1Skamil
29531.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29541.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
29551.1Skamil	    magic_fromtracee);
29561.1Skamil
29571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29581.1Skamil	    "without signal to be sent\n");
29591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29601.1Skamil
29611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29631.1Skamil
29641.1Skamil	validate_status_exited(status, exitval);
29651.1Skamil
29661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29681.1Skamil}
29691.1Skamil
29701.1SkamilATF_TC(read_d_write_d_handshake1);
29711.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
29721.1Skamil{
29731.1Skamil	atf_tc_set_md_var(tc, "descr",
29741.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
29751.1Skamil}
29761.1Skamil
29771.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
29781.1Skamil{
29791.1Skamil	const int exitval = 5;
29801.1Skamil	const int sigval = SIGSTOP;
29811.1Skamil	pid_t child, wpid;
29821.1Skamil	int lookup_me_fromtracee = 0;
29831.1Skamil	const int magic_fromtracee = (int)random();
29841.1Skamil	int lookup_me_totracee = 0;
29851.1Skamil	const int magic_totracee = (int)random();
29861.1Skamil#if defined(TWAIT_HAVE_STATUS)
29871.1Skamil	int status;
29881.1Skamil#endif
29891.1Skamil
29901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29921.1Skamil	if (child == 0) {
29931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29951.1Skamil
29961.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29971.1Skamil
29981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30001.1Skamil
30011.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
30021.1Skamil
30031.13Schristos		DPRINTF("Before exiting of the child process\n");
30041.1Skamil		_exit(exitval);
30051.1Skamil	}
30061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30071.1Skamil
30081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30101.1Skamil
30111.1Skamil	validate_status_stopped(status, sigval);
30121.1Skamil
30131.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
30141.1Skamil	    child, getpid());
30151.1Skamil	errno = 0;
30161.1Skamil	lookup_me_fromtracee =
30171.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
30181.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
30191.1Skamil
30201.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
30211.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
30221.1Skamil	    magic_fromtracee);
30231.1Skamil
30241.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
30251.1Skamil	    child, getpid());
30261.1Skamil	ATF_REQUIRE
30271.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
30281.1Skamil	    != -1);
30291.1Skamil
30301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30311.1Skamil	    "without signal to be sent\n");
30321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30331.1Skamil
30341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30361.1Skamil
30371.1Skamil	validate_status_exited(status, exitval);
30381.1Skamil
30391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30411.1Skamil}
30421.1Skamil
30431.1SkamilATF_TC(read_d_write_d_handshake2);
30441.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
30451.1Skamil{
30461.1Skamil	atf_tc_set_md_var(tc, "descr",
30471.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
30481.1Skamil}
30491.1Skamil
30501.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
30511.1Skamil{
30521.1Skamil	const int exitval = 5;
30531.1Skamil	const int sigval = SIGSTOP;
30541.1Skamil	pid_t child, wpid;
30551.1Skamil	int lookup_me_fromtracee = 0;
30561.1Skamil	const int magic_fromtracee = (int)random();
30571.1Skamil	int lookup_me_totracee = 0;
30581.1Skamil	const int magic_totracee = (int)random();
30591.1Skamil#if defined(TWAIT_HAVE_STATUS)
30601.1Skamil	int status;
30611.1Skamil#endif
30621.1Skamil
30631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30651.1Skamil	if (child == 0) {
30661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30681.1Skamil
30691.1Skamil		lookup_me_fromtracee = magic_fromtracee;
30701.1Skamil
30711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30731.1Skamil
30741.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
30751.1Skamil
30761.13Schristos		DPRINTF("Before exiting of the child process\n");
30771.1Skamil		_exit(exitval);
30781.1Skamil	}
30791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30801.1Skamil
30811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30831.1Skamil
30841.1Skamil	validate_status_stopped(status, sigval);
30851.1Skamil
30861.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
30871.1Skamil	    child, getpid());
30881.1Skamil	ATF_REQUIRE
30891.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
30901.1Skamil	    != -1);
30911.1Skamil
30921.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
30931.1Skamil	    child, getpid());
30941.1Skamil	errno = 0;
30951.1Skamil	lookup_me_fromtracee =
30961.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
30971.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
30981.1Skamil
30991.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31001.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
31011.1Skamil	    magic_fromtracee);
31021.1Skamil
31031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31041.1Skamil	    "without signal to be sent\n");
31051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31061.1Skamil
31071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31091.1Skamil
31101.1Skamil	validate_status_exited(status, exitval);
31111.1Skamil
31121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31141.1Skamil}
31151.1Skamil
31161.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
31171.1Skamilstatic int __used
31181.1Skamildummy_fn1(int a, int b, int c, int d)
31191.1Skamil{
31201.1Skamil
31211.1Skamil	a *= 1;
31221.1Skamil	b += 2;
31231.1Skamil	c -= 3;
31241.1Skamil	d /= 4;
31251.1Skamil
31261.1Skamil	return a + b * c - d;
31271.1Skamil}
31281.1Skamil
31291.1Skamilstatic int __used
31301.1Skamildummy_fn2(int a, int b, int c, int d)
31311.1Skamil{
31321.1Skamil
31331.1Skamil	a *= 4;
31341.1Skamil	b += 3;
31351.1Skamil	c -= 2;
31361.1Skamil	d /= 1;
31371.1Skamil
31381.1Skamil	return a + b * c - d;
31391.1Skamil}
31401.1Skamil
31411.1Skamilstatic int __used
31421.1Skamildummy_fn3(int a, int b, int c, int d)
31431.1Skamil{
31441.1Skamil
31451.1Skamil	a *= 10;
31461.1Skamil	b += 20;
31471.1Skamil	c -= 30;
31481.1Skamil	d /= 40;
31491.1Skamil
31501.1Skamil	return a + b * c - d;
31511.1Skamil}
31521.1Skamil
31531.1Skamilstatic int __used
31541.1Skamildummy_fn4(int a, int b, int c, int d)
31551.1Skamil{
31561.1Skamil
31571.1Skamil	a *= 40;
31581.1Skamil	b += 30;
31591.1Skamil	c -= 20;
31601.1Skamil	d /= 10;
31611.1Skamil
31621.1Skamil	return a + b * c - d;
31631.1Skamil}
31641.1Skamil
31651.1SkamilATF_TC(io_read_i1);
31661.1SkamilATF_TC_HEAD(io_read_i1, tc)
31671.1Skamil{
31681.1Skamil	atf_tc_set_md_var(tc, "descr",
31691.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
31701.1Skamil}
31711.1Skamil
31721.1SkamilATF_TC_BODY(io_read_i1, tc)
31731.1Skamil{
31741.1Skamil	const int exitval = 5;
31751.1Skamil	const int sigval = SIGSTOP;
31761.1Skamil	pid_t child, wpid;
31771.1Skamil	uint8_t lookup_me = 0;
31781.1Skamil	uint8_t magic;
31791.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31801.1Skamil	struct ptrace_io_desc io = {
31811.1Skamil		.piod_op = PIOD_READ_I,
31821.1Skamil		.piod_offs = dummy_fn1,
31831.1Skamil		.piod_addr = &lookup_me,
31841.1Skamil		.piod_len = sizeof(lookup_me)
31851.1Skamil	};
31861.1Skamil#if defined(TWAIT_HAVE_STATUS)
31871.1Skamil	int status;
31881.1Skamil#endif
31891.1Skamil
31901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31921.1Skamil	if (child == 0) {
31931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31951.1Skamil
31961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31981.1Skamil
31991.13Schristos		DPRINTF("Before exiting of the child process\n");
32001.1Skamil		_exit(exitval);
32011.1Skamil	}
32021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32031.1Skamil
32041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32061.1Skamil
32071.1Skamil	validate_status_stopped(status, sigval);
32081.1Skamil
32091.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32101.1Skamil	    child, getpid());
32111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32121.1Skamil
32131.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32141.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
32151.1Skamil
32161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32171.1Skamil	    "without signal to be sent\n");
32181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32191.1Skamil
32201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32221.1Skamil
32231.1Skamil	validate_status_exited(status, exitval);
32241.1Skamil
32251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32271.1Skamil}
32281.1Skamil
32291.1SkamilATF_TC(io_read_i2);
32301.1SkamilATF_TC_HEAD(io_read_i2, tc)
32311.1Skamil{
32321.1Skamil	atf_tc_set_md_var(tc, "descr",
32331.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
32341.1Skamil}
32351.1Skamil
32361.1SkamilATF_TC_BODY(io_read_i2, tc)
32371.1Skamil{
32381.1Skamil	const int exitval = 5;
32391.1Skamil	const int sigval = SIGSTOP;
32401.1Skamil	pid_t child, wpid;
32411.1Skamil	uint16_t lookup_me = 0;
32421.1Skamil	uint16_t magic;
32431.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
32441.1Skamil	struct ptrace_io_desc io = {
32451.1Skamil		.piod_op = PIOD_READ_I,
32461.1Skamil		.piod_offs = dummy_fn1,
32471.1Skamil		.piod_addr = &lookup_me,
32481.1Skamil		.piod_len = sizeof(lookup_me)
32491.1Skamil	};
32501.1Skamil#if defined(TWAIT_HAVE_STATUS)
32511.1Skamil	int status;
32521.1Skamil#endif
32531.1Skamil
32541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32561.1Skamil	if (child == 0) {
32571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32591.1Skamil
32601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32621.1Skamil
32631.13Schristos		DPRINTF("Before exiting of the child process\n");
32641.1Skamil		_exit(exitval);
32651.1Skamil	}
32661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32671.1Skamil
32681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32701.1Skamil
32711.1Skamil	validate_status_stopped(status, sigval);
32721.1Skamil
32731.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32741.1Skamil	    child, getpid());
32751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32761.1Skamil
32771.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32781.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
32791.1Skamil
32801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32811.1Skamil	    "without signal to be sent\n");
32821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32831.1Skamil
32841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32861.1Skamil
32871.1Skamil	validate_status_exited(status, exitval);
32881.1Skamil
32891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32911.1Skamil}
32921.1Skamil
32931.1SkamilATF_TC(io_read_i3);
32941.1SkamilATF_TC_HEAD(io_read_i3, tc)
32951.1Skamil{
32961.1Skamil	atf_tc_set_md_var(tc, "descr",
32971.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
32981.1Skamil}
32991.1Skamil
33001.1SkamilATF_TC_BODY(io_read_i3, tc)
33011.1Skamil{
33021.1Skamil	const int exitval = 5;
33031.1Skamil	const int sigval = SIGSTOP;
33041.1Skamil	pid_t child, wpid;
33051.1Skamil	uint32_t lookup_me = 0;
33061.1Skamil	uint32_t magic;
33071.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33081.1Skamil	struct ptrace_io_desc io = {
33091.1Skamil		.piod_op = PIOD_READ_I,
33101.1Skamil		.piod_offs = dummy_fn1,
33111.1Skamil		.piod_addr = &lookup_me,
33121.1Skamil		.piod_len = sizeof(lookup_me)
33131.1Skamil	};
33141.1Skamil#if defined(TWAIT_HAVE_STATUS)
33151.1Skamil	int status;
33161.1Skamil#endif
33171.1Skamil
33181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33201.1Skamil	if (child == 0) {
33211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33231.1Skamil
33241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33261.1Skamil
33271.13Schristos		DPRINTF("Before exiting of the child process\n");
33281.1Skamil		_exit(exitval);
33291.1Skamil	}
33301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33311.1Skamil
33321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33341.1Skamil
33351.1Skamil	validate_status_stopped(status, sigval);
33361.1Skamil
33371.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33381.1Skamil	    child, getpid());
33391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
33401.1Skamil
33411.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33421.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
33431.1Skamil
33441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33451.1Skamil	    "without signal to be sent\n");
33461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33471.1Skamil
33481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33501.1Skamil
33511.1Skamil	validate_status_exited(status, exitval);
33521.1Skamil
33531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33551.1Skamil}
33561.1Skamil
33571.1SkamilATF_TC(io_read_i4);
33581.1SkamilATF_TC_HEAD(io_read_i4, tc)
33591.1Skamil{
33601.1Skamil	atf_tc_set_md_var(tc, "descr",
33611.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
33621.1Skamil}
33631.1Skamil
33641.1SkamilATF_TC_BODY(io_read_i4, tc)
33651.1Skamil{
33661.1Skamil	const int exitval = 5;
33671.1Skamil	const int sigval = SIGSTOP;
33681.1Skamil	pid_t child, wpid;
33691.1Skamil	uint64_t lookup_me = 0;
33701.1Skamil	uint64_t magic;
33711.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33721.1Skamil	struct ptrace_io_desc io = {
33731.1Skamil		.piod_op = PIOD_READ_I,
33741.1Skamil		.piod_offs = dummy_fn1,
33751.1Skamil		.piod_addr = &lookup_me,
33761.1Skamil		.piod_len = sizeof(lookup_me)
33771.1Skamil	};
33781.1Skamil#if defined(TWAIT_HAVE_STATUS)
33791.1Skamil	int status;
33801.1Skamil#endif
33811.1Skamil
33821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33841.1Skamil	if (child == 0) {
33851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33871.1Skamil
33881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33901.1Skamil
33911.13Schristos		DPRINTF("Before exiting of the child process\n");
33921.1Skamil		_exit(exitval);
33931.1Skamil	}
33941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33951.1Skamil
33961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33981.1Skamil
33991.1Skamil	validate_status_stopped(status, sigval);
34001.1Skamil
34011.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34021.1Skamil	    child, getpid());
34031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34041.1Skamil
34051.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34061.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
34071.1Skamil
34081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34091.1Skamil	    "without signal to be sent\n");
34101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34111.1Skamil
34121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34141.1Skamil
34151.1Skamil	validate_status_exited(status, exitval);
34161.1Skamil
34171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34191.1Skamil}
34201.1Skamil
34211.1SkamilATF_TC(read_i1);
34221.1SkamilATF_TC_HEAD(read_i1, tc)
34231.1Skamil{
34241.1Skamil	atf_tc_set_md_var(tc, "descr",
34251.1Skamil	    "Verify PT_READ_I called once");
34261.1Skamil}
34271.1Skamil
34281.1SkamilATF_TC_BODY(read_i1, tc)
34291.1Skamil{
34301.1Skamil	const int exitval = 5;
34311.1Skamil	const int sigval = SIGSTOP;
34321.1Skamil	pid_t child, wpid;
34331.1Skamil	int lookup_me = 0;
34341.1Skamil	int magic;
34351.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34361.1Skamil#if defined(TWAIT_HAVE_STATUS)
34371.1Skamil	int status;
34381.1Skamil#endif
34391.1Skamil
34401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34421.1Skamil	if (child == 0) {
34431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34451.1Skamil
34461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34481.1Skamil
34491.13Schristos		DPRINTF("Before exiting of the child process\n");
34501.1Skamil		_exit(exitval);
34511.1Skamil	}
34521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34531.1Skamil
34541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34561.1Skamil
34571.1Skamil	validate_status_stopped(status, sigval);
34581.1Skamil
34591.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34601.1Skamil	    child, getpid());
34611.1Skamil	errno = 0;
34621.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
34631.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34641.1Skamil
34651.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34661.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
34671.1Skamil
34681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34691.1Skamil	    "without signal to be sent\n");
34701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34711.1Skamil
34721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34741.1Skamil
34751.1Skamil	validate_status_exited(status, exitval);
34761.1Skamil
34771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34791.1Skamil}
34801.1Skamil
34811.1SkamilATF_TC(read_i2);
34821.1SkamilATF_TC_HEAD(read_i2, tc)
34831.1Skamil{
34841.1Skamil	atf_tc_set_md_var(tc, "descr",
34851.1Skamil	    "Verify PT_READ_I called twice");
34861.1Skamil}
34871.1Skamil
34881.1SkamilATF_TC_BODY(read_i2, tc)
34891.1Skamil{
34901.1Skamil	const int exitval = 5;
34911.1Skamil	const int sigval = SIGSTOP;
34921.1Skamil	pid_t child, wpid;
34931.1Skamil	int lookup_me1 = 0;
34941.1Skamil	int lookup_me2 = 0;
34951.1Skamil	int magic1;
34961.1Skamil	int magic2;
34971.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
34981.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
34991.1Skamil#if defined(TWAIT_HAVE_STATUS)
35001.1Skamil	int status;
35011.1Skamil#endif
35021.1Skamil
35031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35051.1Skamil	if (child == 0) {
35061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35081.1Skamil
35091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35111.1Skamil
35121.13Schristos		DPRINTF("Before exiting of the child process\n");
35131.1Skamil		_exit(exitval);
35141.1Skamil	}
35151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35161.1Skamil
35171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35191.1Skamil
35201.1Skamil	validate_status_stopped(status, sigval);
35211.1Skamil
35221.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
35231.1Skamil	    child, getpid());
35241.1Skamil	errno = 0;
35251.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
35261.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35271.1Skamil
35281.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
35291.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
35301.1Skamil
35311.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
35321.1Skamil	    child, getpid());
35331.1Skamil	errno = 0;
35341.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
35351.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35361.1Skamil
35371.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
35381.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
35391.1Skamil
35401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35411.1Skamil	    "without signal to be sent\n");
35421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35431.1Skamil
35441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35461.1Skamil
35471.1Skamil	validate_status_exited(status, exitval);
35481.1Skamil
35491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35511.1Skamil}
35521.1Skamil
35531.1SkamilATF_TC(read_i3);
35541.1SkamilATF_TC_HEAD(read_i3, tc)
35551.1Skamil{
35561.1Skamil	atf_tc_set_md_var(tc, "descr",
35571.1Skamil	    "Verify PT_READ_I called three times");
35581.1Skamil}
35591.1Skamil
35601.1SkamilATF_TC_BODY(read_i3, tc)
35611.1Skamil{
35621.1Skamil	const int exitval = 5;
35631.1Skamil	const int sigval = SIGSTOP;
35641.1Skamil	pid_t child, wpid;
35651.1Skamil	int lookup_me1 = 0;
35661.1Skamil	int lookup_me2 = 0;
35671.1Skamil	int lookup_me3 = 0;
35681.1Skamil	int magic1;
35691.1Skamil	int magic2;
35701.1Skamil	int magic3;
35711.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35721.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
35731.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
35741.1Skamil#if defined(TWAIT_HAVE_STATUS)
35751.1Skamil	int status;
35761.1Skamil#endif
35771.1Skamil
35781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35801.1Skamil	if (child == 0) {
35811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35831.1Skamil
35841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35861.1Skamil
35871.13Schristos		DPRINTF("Before exiting of the child process\n");
35881.1Skamil		_exit(exitval);
35891.1Skamil	}
35901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35911.1Skamil
35921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35941.1Skamil
35951.1Skamil	validate_status_stopped(status, sigval);
35961.1Skamil
35971.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
35981.1Skamil	    child, getpid());
35991.1Skamil	errno = 0;
36001.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
36011.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36021.1Skamil
36031.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
36041.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
36051.1Skamil
36061.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
36071.1Skamil	    child, getpid());
36081.1Skamil	errno = 0;
36091.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
36101.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36111.1Skamil
36121.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
36131.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
36141.1Skamil
36151.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
36161.1Skamil	    child, getpid());
36171.1Skamil	errno = 0;
36181.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
36191.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36201.1Skamil
36211.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
36221.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
36231.1Skamil
36241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36251.1Skamil	    "without signal to be sent\n");
36261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36271.1Skamil
36281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36301.1Skamil
36311.1Skamil	validate_status_exited(status, exitval);
36321.1Skamil
36331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36351.1Skamil}
36361.1Skamil
36371.1SkamilATF_TC(read_i4);
36381.1SkamilATF_TC_HEAD(read_i4, tc)
36391.1Skamil{
36401.1Skamil	atf_tc_set_md_var(tc, "descr",
36411.1Skamil	    "Verify PT_READ_I called four times");
36421.1Skamil}
36431.1Skamil
36441.1SkamilATF_TC_BODY(read_i4, tc)
36451.1Skamil{
36461.1Skamil	const int exitval = 5;
36471.1Skamil	const int sigval = SIGSTOP;
36481.1Skamil	pid_t child, wpid;
36491.1Skamil	int lookup_me1 = 0;
36501.1Skamil	int lookup_me2 = 0;
36511.1Skamil	int lookup_me3 = 0;
36521.1Skamil	int lookup_me4 = 0;
36531.1Skamil	int magic1;
36541.1Skamil	int magic2;
36551.1Skamil	int magic3;
36561.1Skamil	int magic4;
36571.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
36581.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
36591.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
36601.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
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 new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
36851.1Skamil	    child, getpid());
36861.1Skamil	errno = 0;
36871.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
36881.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36891.1Skamil
36901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
36911.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
36921.1Skamil
36931.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
36941.1Skamil	    child, getpid());
36951.1Skamil	errno = 0;
36961.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
36971.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36981.1Skamil
36991.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
37001.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
37011.1Skamil
37021.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
37031.1Skamil	    child, getpid());
37041.1Skamil	errno = 0;
37051.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
37061.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37071.1Skamil
37081.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
37091.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
37101.1Skamil
37111.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
37121.1Skamil	    child, getpid());
37131.1Skamil	errno = 0;
37141.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
37151.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37161.1Skamil
37171.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
37181.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
37191.1Skamil
37201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37211.1Skamil	    "without signal to be sent\n");
37221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37231.1Skamil
37241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37261.1Skamil
37271.1Skamil	validate_status_exited(status, exitval);
37281.1Skamil
37291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37311.1Skamil}
37321.1Skamil
37331.1Skamil#if defined(HAVE_GPREGS)
37341.1SkamilATF_TC(regs1);
37351.1SkamilATF_TC_HEAD(regs1, tc)
37361.1Skamil{
37371.1Skamil	atf_tc_set_md_var(tc, "descr",
37381.1Skamil	    "Verify plain PT_GETREGS call without further steps");
37391.1Skamil}
37401.1Skamil
37411.1SkamilATF_TC_BODY(regs1, tc)
37421.1Skamil{
37431.1Skamil	const int exitval = 5;
37441.1Skamil	const int sigval = SIGSTOP;
37451.1Skamil	pid_t child, wpid;
37461.1Skamil#if defined(TWAIT_HAVE_STATUS)
37471.1Skamil	int status;
37481.1Skamil#endif
37491.1Skamil	struct reg r;
37501.1Skamil
37511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37531.1Skamil	if (child == 0) {
37541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37561.1Skamil
37571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37591.1Skamil
37601.13Schristos		DPRINTF("Before exiting of the child process\n");
37611.1Skamil		_exit(exitval);
37621.1Skamil	}
37631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37641.1Skamil
37651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37671.1Skamil
37681.1Skamil	validate_status_stopped(status, sigval);
37691.1Skamil
37701.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37721.1Skamil
37731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37741.1Skamil	    "without signal to be sent\n");
37751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37761.1Skamil
37771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37791.1Skamil
37801.1Skamil	validate_status_exited(status, exitval);
37811.1Skamil
37821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37841.1Skamil}
37851.1Skamil#endif
37861.1Skamil
37871.1Skamil#if defined(HAVE_GPREGS)
37881.1SkamilATF_TC(regs2);
37891.1SkamilATF_TC_HEAD(regs2, tc)
37901.1Skamil{
37911.1Skamil	atf_tc_set_md_var(tc, "descr",
37921.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
37931.1Skamil}
37941.1Skamil
37951.1SkamilATF_TC_BODY(regs2, tc)
37961.1Skamil{
37971.1Skamil	const int exitval = 5;
37981.1Skamil	const int sigval = SIGSTOP;
37991.1Skamil	pid_t child, wpid;
38001.1Skamil#if defined(TWAIT_HAVE_STATUS)
38011.1Skamil	int status;
38021.1Skamil#endif
38031.1Skamil	struct reg r;
38041.1Skamil
38051.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38061.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38071.1Skamil	if (child == 0) {
38081.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38091.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38101.1Skamil
38111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38131.1Skamil
38141.13Schristos		DPRINTF("Before exiting of the child process\n");
38151.1Skamil		_exit(exitval);
38161.1Skamil	}
38171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38181.1Skamil
38191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38211.1Skamil
38221.1Skamil	validate_status_stopped(status, sigval);
38231.1Skamil
38241.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38261.1Skamil
38271.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
38281.1Skamil
38291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38301.1Skamil	    "without signal to be sent\n");
38311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38321.1Skamil
38331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38351.1Skamil
38361.1Skamil	validate_status_exited(status, exitval);
38371.1Skamil
38381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38401.1Skamil}
38411.1Skamil#endif
38421.1Skamil
38431.1Skamil#if defined(HAVE_GPREGS)
38441.1SkamilATF_TC(regs3);
38451.1SkamilATF_TC_HEAD(regs3, tc)
38461.1Skamil{
38471.1Skamil	atf_tc_set_md_var(tc, "descr",
38481.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
38491.1Skamil}
38501.1Skamil
38511.1SkamilATF_TC_BODY(regs3, tc)
38521.1Skamil{
38531.1Skamil	const int exitval = 5;
38541.1Skamil	const int sigval = SIGSTOP;
38551.1Skamil	pid_t child, wpid;
38561.1Skamil#if defined(TWAIT_HAVE_STATUS)
38571.1Skamil	int status;
38581.1Skamil#endif
38591.1Skamil	struct reg r;
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("Call GETREGS for the child process\n");
38811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38821.1Skamil
38831.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
38841.1Skamil
38851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38861.1Skamil	    "without signal to be sent\n");
38871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38881.1Skamil
38891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38911.1Skamil
38921.1Skamil	validate_status_exited(status, exitval);
38931.1Skamil
38941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38961.1Skamil}
38971.1Skamil#endif
38981.1Skamil
38991.1Skamil#if defined(HAVE_GPREGS)
39001.1SkamilATF_TC(regs4);
39011.1SkamilATF_TC_HEAD(regs4, tc)
39021.1Skamil{
39031.1Skamil	atf_tc_set_md_var(tc, "descr",
39041.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
39051.1Skamil}
39061.1Skamil
39071.1SkamilATF_TC_BODY(regs4, tc)
39081.1Skamil{
39091.1Skamil	const int exitval = 5;
39101.1Skamil	const int sigval = SIGSTOP;
39111.1Skamil	pid_t child, wpid;
39121.1Skamil#if defined(TWAIT_HAVE_STATUS)
39131.1Skamil	int status;
39141.1Skamil#endif
39151.1Skamil	struct reg r;
39161.1Skamil
39171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39191.1Skamil	if (child == 0) {
39201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39221.1Skamil
39231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39251.1Skamil
39261.13Schristos		DPRINTF("Before exiting of the child process\n");
39271.1Skamil		_exit(exitval);
39281.1Skamil	}
39291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39301.1Skamil
39311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39331.1Skamil
39341.1Skamil	validate_status_stopped(status, sigval);
39351.1Skamil
39361.13Schristos	DPRINTF("Call GETREGS for the child process\n");
39371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39381.1Skamil
39391.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
39401.1Skamil
39411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39421.1Skamil	    "without signal to be sent\n");
39431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39441.1Skamil
39451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39471.1Skamil
39481.1Skamil	validate_status_exited(status, exitval);
39491.1Skamil
39501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39521.1Skamil}
39531.1Skamil#endif
39541.1Skamil
39551.1Skamil#if defined(HAVE_GPREGS)
39561.1SkamilATF_TC(regs5);
39571.1SkamilATF_TC_HEAD(regs5, tc)
39581.1Skamil{
39591.1Skamil	atf_tc_set_md_var(tc, "descr",
39601.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
39611.1Skamil}
39621.1Skamil
39631.1SkamilATF_TC_BODY(regs5, tc)
39641.1Skamil{
39651.1Skamil	const int exitval = 5;
39661.1Skamil	const int sigval = SIGSTOP;
39671.1Skamil	pid_t child, wpid;
39681.1Skamil#if defined(TWAIT_HAVE_STATUS)
39691.1Skamil	int status;
39701.1Skamil#endif
39711.1Skamil	struct reg r;
39721.1Skamil
39731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39751.1Skamil	if (child == 0) {
39761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39781.1Skamil
39791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39811.1Skamil
39821.13Schristos		DPRINTF("Before exiting of the child process\n");
39831.1Skamil		_exit(exitval);
39841.1Skamil	}
39851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39861.1Skamil
39871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39891.1Skamil
39901.1Skamil	validate_status_stopped(status, sigval);
39911.1Skamil
39921.13Schristos	DPRINTF("Call GETREGS for the child process\n");
39931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39941.1Skamil
39951.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
39961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39971.1Skamil
39981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39991.1Skamil	    "without signal to be sent\n");
40001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40011.1Skamil
40021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40041.1Skamil
40051.1Skamil	validate_status_exited(status, exitval);
40061.1Skamil
40071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40091.1Skamil}
40101.1Skamil#endif
40111.1Skamil
40121.1Skamil#if defined(HAVE_FPREGS)
40131.1SkamilATF_TC(fpregs1);
40141.1SkamilATF_TC_HEAD(fpregs1, tc)
40151.1Skamil{
40161.1Skamil	atf_tc_set_md_var(tc, "descr",
40171.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
40181.1Skamil}
40191.1Skamil
40201.1SkamilATF_TC_BODY(fpregs1, tc)
40211.1Skamil{
40221.1Skamil	const int exitval = 5;
40231.1Skamil	const int sigval = SIGSTOP;
40241.1Skamil	pid_t child, wpid;
40251.1Skamil#if defined(TWAIT_HAVE_STATUS)
40261.1Skamil	int status;
40271.1Skamil#endif
40281.1Skamil	struct fpreg r;
40291.1Skamil
40301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40321.1Skamil	if (child == 0) {
40331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40351.1Skamil
40361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40381.1Skamil
40391.13Schristos		DPRINTF("Before exiting of the child process\n");
40401.1Skamil		_exit(exitval);
40411.1Skamil	}
40421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40431.1Skamil
40441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40461.1Skamil
40471.1Skamil	validate_status_stopped(status, sigval);
40481.1Skamil
40491.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
40501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
40511.1Skamil
40521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40531.1Skamil	    "without signal to be sent\n");
40541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40551.1Skamil
40561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40581.1Skamil
40591.1Skamil	validate_status_exited(status, exitval);
40601.1Skamil
40611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40631.1Skamil}
40641.1Skamil#endif
40651.1Skamil
40661.1Skamil#if defined(HAVE_FPREGS)
40671.1SkamilATF_TC(fpregs2);
40681.1SkamilATF_TC_HEAD(fpregs2, tc)
40691.1Skamil{
40701.1Skamil	atf_tc_set_md_var(tc, "descr",
40711.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
40721.1Skamil	    "regs");
40731.1Skamil}
40741.1Skamil
40751.1SkamilATF_TC_BODY(fpregs2, tc)
40761.1Skamil{
40771.1Skamil	const int exitval = 5;
40781.1Skamil	const int sigval = SIGSTOP;
40791.1Skamil	pid_t child, wpid;
40801.1Skamil#if defined(TWAIT_HAVE_STATUS)
40811.1Skamil	int status;
40821.1Skamil#endif
40831.1Skamil	struct fpreg r;
40841.1Skamil
40851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40871.1Skamil	if (child == 0) {
40881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40901.1Skamil
40911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40931.1Skamil
40941.13Schristos		DPRINTF("Before exiting of the child process\n");
40951.1Skamil		_exit(exitval);
40961.1Skamil	}
40971.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40981.1Skamil
40991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41011.1Skamil
41021.1Skamil	validate_status_stopped(status, sigval);
41031.1Skamil
41041.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
41051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
41061.1Skamil
41071.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
41081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
41091.1Skamil
41101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41111.1Skamil	    "without signal to be sent\n");
41121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41131.1Skamil
41141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41161.1Skamil
41171.1Skamil	validate_status_exited(status, exitval);
41181.1Skamil
41191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41211.1Skamil}
41221.1Skamil#endif
41231.1Skamil
41241.1Skamil#if defined(PT_STEP)
41251.1Skamilstatic void
41261.2Skamilptrace_step(int N, int setstep)
41271.1Skamil{
41281.1Skamil	const int exitval = 5;
41291.1Skamil	const int sigval = SIGSTOP;
41301.1Skamil	pid_t child, wpid;
41311.1Skamil#if defined(TWAIT_HAVE_STATUS)
41321.1Skamil	int status;
41331.1Skamil#endif
41341.1Skamil	int happy;
41351.1Skamil
41361.1Skamil#if defined(__arm__)
41371.1Skamil	/* PT_STEP not supported on arm 32-bit */
41381.1Skamil	atf_tc_expect_fail("PR kern/52119");
41391.1Skamil#endif
41401.1Skamil
41411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41431.1Skamil	if (child == 0) {
41441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41461.1Skamil
41471.1Skamil		happy = check_happy(999);
41481.1Skamil
41491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41511.1Skamil
41521.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
41531.1Skamil
41541.13Schristos		DPRINTF("Before exiting of the child process\n");
41551.1Skamil		_exit(exitval);
41561.1Skamil	}
41571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41581.1Skamil
41591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41611.1Skamil
41621.1Skamil	validate_status_stopped(status, sigval);
41631.1Skamil
41641.1Skamil	while (N --> 0) {
41651.2Skamil		if (setstep) {
41661.13Schristos			DPRINTF("Before resuming the child process where it "
41671.2Skamil			    "left off and without signal to be sent (use "
41681.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
41691.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
41701.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
41711.2Skamil			    != -1);
41721.2Skamil		} else {
41731.13Schristos			DPRINTF("Before resuming the child process where it "
41741.2Skamil			    "left off and without signal to be sent (use "
41751.2Skamil			    "PT_STEP)\n");
41761.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
41771.2Skamil			    != -1);
41781.2Skamil		}
41791.1Skamil
41801.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41811.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
41821.1Skamil		    child);
41831.1Skamil
41841.1Skamil		validate_status_stopped(status, SIGTRAP);
41851.2Skamil
41861.2Skamil		if (setstep) {
41871.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
41881.2Skamil		}
41891.1Skamil	}
41901.1Skamil
41911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41921.1Skamil	    "without signal to be sent\n");
41931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41941.1Skamil
41951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41971.1Skamil
41981.1Skamil	validate_status_exited(status, exitval);
41991.1Skamil
42001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42021.1Skamil}
42031.1Skamil#endif
42041.1Skamil
42051.1Skamil#if defined(PT_STEP)
42061.1SkamilATF_TC(step1);
42071.1SkamilATF_TC_HEAD(step1, tc)
42081.1Skamil{
42091.1Skamil	atf_tc_set_md_var(tc, "descr",
42101.1Skamil	    "Verify single PT_STEP call");
42111.1Skamil}
42121.1Skamil
42131.1SkamilATF_TC_BODY(step1, tc)
42141.1Skamil{
42151.2Skamil	ptrace_step(1, 0);
42161.1Skamil}
42171.1Skamil#endif
42181.1Skamil
42191.1Skamil#if defined(PT_STEP)
42201.1SkamilATF_TC(step2);
42211.1SkamilATF_TC_HEAD(step2, tc)
42221.1Skamil{
42231.1Skamil	atf_tc_set_md_var(tc, "descr",
42241.1Skamil	    "Verify PT_STEP called twice");
42251.1Skamil}
42261.1Skamil
42271.1SkamilATF_TC_BODY(step2, tc)
42281.1Skamil{
42291.2Skamil	ptrace_step(2, 0);
42301.1Skamil}
42311.1Skamil#endif
42321.1Skamil
42331.1Skamil#if defined(PT_STEP)
42341.1SkamilATF_TC(step3);
42351.1SkamilATF_TC_HEAD(step3, tc)
42361.1Skamil{
42371.1Skamil	atf_tc_set_md_var(tc, "descr",
42381.1Skamil	    "Verify PT_STEP called three times");
42391.1Skamil}
42401.1Skamil
42411.1SkamilATF_TC_BODY(step3, tc)
42421.1Skamil{
42431.2Skamil	ptrace_step(3, 0);
42441.1Skamil}
42451.1Skamil#endif
42461.1Skamil
42471.1Skamil#if defined(PT_STEP)
42481.1SkamilATF_TC(step4);
42491.1SkamilATF_TC_HEAD(step4, tc)
42501.1Skamil{
42511.1Skamil	atf_tc_set_md_var(tc, "descr",
42521.1Skamil	    "Verify PT_STEP called four times");
42531.1Skamil}
42541.1Skamil
42551.1SkamilATF_TC_BODY(step4, tc)
42561.1Skamil{
42571.2Skamil	ptrace_step(4, 0);
42581.2Skamil}
42591.2Skamil#endif
42601.2Skamil
42611.2Skamil#if defined(PT_STEP)
42621.2SkamilATF_TC(setstep1);
42631.2SkamilATF_TC_HEAD(setstep1, tc)
42641.2Skamil{
42651.2Skamil	atf_tc_set_md_var(tc, "descr",
42661.2Skamil	    "Verify single PT_SETSTEP call");
42671.2Skamil}
42681.2Skamil
42691.2SkamilATF_TC_BODY(setstep1, tc)
42701.2Skamil{
42711.2Skamil	ptrace_step(1, 1);
42721.2Skamil}
42731.2Skamil#endif
42741.2Skamil
42751.2Skamil#if defined(PT_STEP)
42761.2SkamilATF_TC(setstep2);
42771.2SkamilATF_TC_HEAD(setstep2, tc)
42781.2Skamil{
42791.2Skamil	atf_tc_set_md_var(tc, "descr",
42801.2Skamil	    "Verify PT_SETSTEP called twice");
42811.2Skamil}
42821.2Skamil
42831.2SkamilATF_TC_BODY(setstep2, tc)
42841.2Skamil{
42851.2Skamil	ptrace_step(2, 1);
42861.2Skamil}
42871.2Skamil#endif
42881.2Skamil
42891.2Skamil#if defined(PT_STEP)
42901.2SkamilATF_TC(setstep3);
42911.2SkamilATF_TC_HEAD(setstep3, tc)
42921.2Skamil{
42931.2Skamil	atf_tc_set_md_var(tc, "descr",
42941.2Skamil	    "Verify PT_SETSTEP called three times");
42951.2Skamil}
42961.2Skamil
42971.2SkamilATF_TC_BODY(setstep3, tc)
42981.2Skamil{
42991.2Skamil	ptrace_step(3, 1);
43001.2Skamil}
43011.2Skamil#endif
43021.2Skamil
43031.2Skamil#if defined(PT_STEP)
43041.2SkamilATF_TC(setstep4);
43051.2SkamilATF_TC_HEAD(setstep4, tc)
43061.2Skamil{
43071.2Skamil	atf_tc_set_md_var(tc, "descr",
43081.2Skamil	    "Verify PT_SETSTEP called four times");
43091.2Skamil}
43101.2Skamil
43111.2SkamilATF_TC_BODY(setstep4, tc)
43121.2Skamil{
43131.2Skamil	ptrace_step(4, 1);
43141.1Skamil}
43151.1Skamil#endif
43161.1Skamil
43171.1SkamilATF_TC(kill1);
43181.1SkamilATF_TC_HEAD(kill1, tc)
43191.1Skamil{
43201.1Skamil	atf_tc_set_md_var(tc, "descr",
43211.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
43221.1Skamil}
43231.1Skamil
43241.1SkamilATF_TC_BODY(kill1, tc)
43251.1Skamil{
43261.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
43271.1Skamil	pid_t child, wpid;
43281.1Skamil#if defined(TWAIT_HAVE_STATUS)
43291.1Skamil	int status;
43301.1Skamil#endif
43311.1Skamil
43321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43341.1Skamil	if (child == 0) {
43351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43371.1Skamil
43381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43401.1Skamil
43411.1Skamil		/* NOTREACHED */
43421.1Skamil		FORKEE_ASSERTX(0 &&
43431.1Skamil		    "Child should be terminated by a signal from its parent");
43441.1Skamil	}
43451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43461.1Skamil
43471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43491.1Skamil
43501.1Skamil	validate_status_stopped(status, sigval);
43511.1Skamil
43521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43531.1Skamil	    "without signal to be sent\n");
43541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
43551.1Skamil
43561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43581.1Skamil
43591.1Skamil	validate_status_signaled(status, sigsent, 0);
43601.1Skamil
43611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43631.1Skamil}
43641.1Skamil
43651.1SkamilATF_TC(kill2);
43661.1SkamilATF_TC_HEAD(kill2, tc)
43671.1Skamil{
43681.1Skamil	atf_tc_set_md_var(tc, "descr",
43691.1Skamil	    "Verify that PT_KILL terminates child");
43701.1Skamil}
43711.1Skamil
43721.1SkamilATF_TC_BODY(kill2, tc)
43731.1Skamil{
43741.1Skamil	const int sigval = SIGSTOP;
43751.1Skamil	pid_t child, wpid;
43761.1Skamil#if defined(TWAIT_HAVE_STATUS)
43771.1Skamil	int status;
43781.1Skamil#endif
43791.1Skamil
43801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43821.1Skamil	if (child == 0) {
43831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43851.1Skamil
43861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43881.1Skamil
43891.1Skamil		/* NOTREACHED */
43901.1Skamil		FORKEE_ASSERTX(0 &&
43911.1Skamil		    "Child should be terminated by a signal from its parent");
43921.1Skamil	}
43931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43941.1Skamil
43951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43971.1Skamil
43981.1Skamil	validate_status_stopped(status, sigval);
43991.1Skamil
44001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44011.1Skamil	    "without signal to be sent\n");
44021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
44031.1Skamil
44041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44061.1Skamil
44071.1Skamil	validate_status_signaled(status, SIGKILL, 0);
44081.1Skamil
44091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44111.1Skamil}
44121.1Skamil
44131.1SkamilATF_TC(lwpinfo1);
44141.1SkamilATF_TC_HEAD(lwpinfo1, tc)
44151.1Skamil{
44161.1Skamil	atf_tc_set_md_var(tc, "descr",
44171.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
44181.1Skamil}
44191.1Skamil
44201.1SkamilATF_TC_BODY(lwpinfo1, tc)
44211.1Skamil{
44221.1Skamil	const int exitval = 5;
44231.1Skamil	const int sigval = SIGSTOP;
44241.1Skamil	pid_t child, wpid;
44251.1Skamil#if defined(TWAIT_HAVE_STATUS)
44261.1Skamil	int status;
44271.1Skamil#endif
44281.1Skamil	struct ptrace_lwpinfo info = {0, 0};
44291.1Skamil
44301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44321.1Skamil	if (child == 0) {
44331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44351.1Skamil
44361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44381.1Skamil
44391.13Schristos		DPRINTF("Before exiting of the child process\n");
44401.1Skamil		_exit(exitval);
44411.1Skamil	}
44421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44431.1Skamil
44441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44461.1Skamil
44471.1Skamil	validate_status_stopped(status, sigval);
44481.1Skamil
44491.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
44511.1Skamil
44521.13Schristos	DPRINTF("Assert that there exists a thread\n");
44531.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
44541.1Skamil
44551.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
44561.1Skamil	    info.pl_lwpid);
44571.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
44581.1Skamil	    "Received event %d != expected event %d",
44591.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
44601.1Skamil
44611.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
44631.1Skamil
44641.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
44651.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
44661.1Skamil
44671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44681.1Skamil	    "without signal to be sent\n");
44691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44701.1Skamil
44711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44731.1Skamil
44741.1Skamil	validate_status_exited(status, exitval);
44751.1Skamil
44761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44781.1Skamil}
44791.1Skamil
44801.1Skamil#if defined(TWAIT_HAVE_PID)
44811.1SkamilATF_TC(lwpinfo2);
44821.1SkamilATF_TC_HEAD(lwpinfo2, tc)
44831.1Skamil{
44841.1Skamil	atf_tc_set_md_var(tc, "descr",
44851.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
44861.1Skamil	    "tracer)");
44871.1Skamil}
44881.1Skamil
44891.1SkamilATF_TC_BODY(lwpinfo2, tc)
44901.1Skamil{
44911.1Skamil	struct msg_fds parent_tracee, parent_tracer;
44921.1Skamil	const int exitval_tracee = 5;
44931.1Skamil	const int exitval_tracer = 10;
44941.1Skamil	pid_t tracee, tracer, wpid;
44951.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
44961.1Skamil#if defined(TWAIT_HAVE_STATUS)
44971.1Skamil	int status;
44981.1Skamil#endif
44991.1Skamil	struct ptrace_lwpinfo info = {0, 0};
45001.1Skamil
45011.13Schristos	DPRINTF("Spawn tracee\n");
45021.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
45031.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
45041.1Skamil	tracee = atf_utils_fork();
45051.1Skamil	if (tracee == 0) {
45061.1Skamil
45071.1Skamil		/* Wait for message from the parent */
45081.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
45091.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
45101.1Skamil
45111.1Skamil		_exit(exitval_tracee);
45121.1Skamil	}
45131.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
45141.1Skamil
45151.13Schristos	DPRINTF("Spawn debugger\n");
45161.1Skamil	tracer = atf_utils_fork();
45171.1Skamil	if (tracer == 0) {
45181.1Skamil		/* No IPC to communicate with the child */
45191.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
45201.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
45211.1Skamil
45221.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
45231.1Skamil		FORKEE_REQUIRE_SUCCESS(
45241.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
45251.1Skamil
45261.1Skamil		forkee_status_stopped(status, SIGSTOP);
45271.1Skamil
45281.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
45291.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
45301.1Skamil		    != -1);
45311.1Skamil
45321.13Schristos		DPRINTF("Assert that there exists a thread\n");
45331.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
45341.1Skamil
45351.13Schristos		DPRINTF("Assert that lwp thread %d received event "
45361.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
45371.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
45381.1Skamil
45391.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
45401.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
45411.1Skamil		    != -1);
45421.1Skamil
45431.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
45441.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
45451.1Skamil
45461.1Skamil		/* Resume tracee with PT_CONTINUE */
45471.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
45481.1Skamil
45491.1Skamil		/* Inform parent that tracer has attached to tracee */
45501.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
45511.1Skamil		/* Wait for parent */
45521.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
45531.1Skamil
45541.1Skamil		/* Wait for tracee and assert that it exited */
45551.1Skamil		FORKEE_REQUIRE_SUCCESS(
45561.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
45571.1Skamil
45581.1Skamil		forkee_status_exited(status, exitval_tracee);
45591.1Skamil
45601.13Schristos		DPRINTF("Before exiting of the tracer process\n");
45611.1Skamil		_exit(exitval_tracer);
45621.1Skamil	}
45631.1Skamil
45641.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
45651.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
45661.1Skamil
45671.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
45681.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
45691.1Skamil
45701.13Schristos	DPRINTF("Detect that tracee is zombie\n");
45711.1Skamil	await_zombie(tracee);
45721.1Skamil
45731.13Schristos	DPRINTF("Assert that there is no status about tracee - "
45741.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
45751.1Skamil	TWAIT_REQUIRE_SUCCESS(
45761.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
45771.1Skamil
45781.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
45791.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
45801.1Skamil
45811.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
45821.1Skamil	    TWAIT_FNAME);
45831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
45841.1Skamil	    tracer);
45851.1Skamil
45861.1Skamil	validate_status_exited(status, exitval_tracer);
45871.1Skamil
45881.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
45891.1Skamil	    TWAIT_FNAME);
45901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
45911.1Skamil	    tracee);
45921.1Skamil
45931.1Skamil	validate_status_exited(status, exitval_tracee);
45941.1Skamil
45951.1Skamil	msg_close(&parent_tracer);
45961.1Skamil	msg_close(&parent_tracee);
45971.1Skamil}
45981.1Skamil#endif
45991.1Skamil
46001.1SkamilATF_TC(siginfo1);
46011.1SkamilATF_TC_HEAD(siginfo1, tc)
46021.1Skamil{
46031.1Skamil	atf_tc_set_md_var(tc, "descr",
46041.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
46051.1Skamil}
46061.1Skamil
46071.1SkamilATF_TC_BODY(siginfo1, tc)
46081.1Skamil{
46091.1Skamil	const int exitval = 5;
46101.1Skamil	const int sigval = SIGTRAP;
46111.1Skamil	pid_t child, wpid;
46121.1Skamil#if defined(TWAIT_HAVE_STATUS)
46131.1Skamil	int status;
46141.1Skamil#endif
46151.1Skamil	struct ptrace_siginfo info;
46161.1Skamil	memset(&info, 0, sizeof(info));
46171.1Skamil
46181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46201.1Skamil	if (child == 0) {
46211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46231.1Skamil
46241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46261.1Skamil
46271.13Schristos		DPRINTF("Before exiting of the child process\n");
46281.1Skamil		_exit(exitval);
46291.1Skamil	}
46301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46311.1Skamil
46321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46341.1Skamil
46351.1Skamil	validate_status_stopped(status, sigval);
46361.1Skamil
46371.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
46381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
46391.1Skamil
46401.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
46411.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
46421.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
46431.1Skamil	    info.psi_siginfo.si_errno);
46441.1Skamil
46451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46461.1Skamil	    "without signal to be sent\n");
46471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
46481.1Skamil
46491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46511.1Skamil
46521.1Skamil	validate_status_exited(status, exitval);
46531.1Skamil
46541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46561.1Skamil}
46571.1Skamil
46581.1SkamilATF_TC(siginfo2);
46591.1SkamilATF_TC_HEAD(siginfo2, tc)
46601.1Skamil{
46611.1Skamil	atf_tc_set_md_var(tc, "descr",
46621.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
46631.1Skamil	    "modification of SIGINT from tracee");
46641.1Skamil}
46651.1Skamil
46661.1Skamilstatic int siginfo2_caught = 0;
46671.1Skamil
46681.1Skamilstatic void
46691.1Skamilsiginfo2_sighandler(int sig)
46701.1Skamil{
46711.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
46721.1Skamil
46731.1Skamil	++siginfo2_caught;
46741.1Skamil}
46751.1Skamil
46761.1SkamilATF_TC_BODY(siginfo2, tc)
46771.1Skamil{
46781.1Skamil	const int exitval = 5;
46791.1Skamil	const int sigval = SIGINT;
46801.1Skamil	pid_t child, wpid;
46811.1Skamil	struct sigaction sa;
46821.1Skamil#if defined(TWAIT_HAVE_STATUS)
46831.1Skamil	int status;
46841.1Skamil#endif
46851.1Skamil	struct ptrace_siginfo info;
46861.1Skamil	memset(&info, 0, sizeof(info));
46871.1Skamil
46881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46901.1Skamil	if (child == 0) {
46911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46931.1Skamil
46941.1Skamil		sa.sa_handler = siginfo2_sighandler;
46951.1Skamil		sa.sa_flags = SA_SIGINFO;
46961.1Skamil		sigemptyset(&sa.sa_mask);
46971.1Skamil
46981.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
46991.1Skamil
47001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47021.1Skamil
47031.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
47041.1Skamil
47051.13Schristos		DPRINTF("Before exiting of the child process\n");
47061.1Skamil		_exit(exitval);
47071.1Skamil	}
47081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47091.1Skamil
47101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47121.1Skamil
47131.1Skamil	validate_status_stopped(status, sigval);
47141.1Skamil
47151.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47171.1Skamil
47181.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47191.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47201.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47211.1Skamil	    info.psi_siginfo.si_errno);
47221.1Skamil
47231.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
47241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
47251.1Skamil
47261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47271.1Skamil	    "without signal to be sent\n");
47281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
47291.1Skamil
47301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47321.1Skamil
47331.1Skamil	validate_status_exited(status, exitval);
47341.1Skamil
47351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47371.1Skamil}
47381.1Skamil
47391.1SkamilATF_TC(siginfo3);
47401.1SkamilATF_TC_HEAD(siginfo3, tc)
47411.1Skamil{
47421.1Skamil	atf_tc_set_md_var(tc, "descr",
47431.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
47441.1Skamil	    "setting signal to new value");
47451.1Skamil}
47461.1Skamil
47471.1Skamilstatic int siginfo3_caught = 0;
47481.1Skamil
47491.1Skamilstatic void
47501.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
47511.1Skamil{
47521.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
47531.1Skamil
47541.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
47551.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
47561.1Skamil
47571.1Skamil	++siginfo3_caught;
47581.1Skamil}
47591.1Skamil
47601.1SkamilATF_TC_BODY(siginfo3, tc)
47611.1Skamil{
47621.1Skamil	const int exitval = 5;
47631.1Skamil	const int sigval = SIGINT;
47641.1Skamil	const int sigfaked = SIGTRAP;
47651.1Skamil	const int sicodefaked = TRAP_BRKPT;
47661.1Skamil	pid_t child, wpid;
47671.1Skamil	struct sigaction sa;
47681.1Skamil#if defined(TWAIT_HAVE_STATUS)
47691.1Skamil	int status;
47701.1Skamil#endif
47711.1Skamil	struct ptrace_siginfo info;
47721.1Skamil	memset(&info, 0, sizeof(info));
47731.1Skamil
47741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47761.1Skamil	if (child == 0) {
47771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47791.1Skamil
47801.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
47811.1Skamil		sa.sa_flags = SA_SIGINFO;
47821.1Skamil		sigemptyset(&sa.sa_mask);
47831.1Skamil
47841.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
47851.1Skamil
47861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47881.1Skamil
47891.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
47901.1Skamil
47911.13Schristos		DPRINTF("Before exiting of the child process\n");
47921.1Skamil		_exit(exitval);
47931.1Skamil	}
47941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47951.1Skamil
47961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47981.1Skamil
47991.1Skamil	validate_status_stopped(status, sigval);
48001.1Skamil
48011.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48031.1Skamil
48041.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
48051.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
48061.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
48071.1Skamil	    info.psi_siginfo.si_errno);
48081.1Skamil
48091.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
48101.1Skamil	    sigfaked, sicodefaked);
48111.1Skamil	info.psi_siginfo.si_signo = sigfaked;
48121.1Skamil	info.psi_siginfo.si_code = sicodefaked;
48131.1Skamil
48141.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
48151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
48161.1Skamil
48171.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48191.1Skamil
48201.13Schristos	DPRINTF("Before checking siginfo_t\n");
48211.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
48221.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
48231.1Skamil
48241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48251.1Skamil	    "without signal to be sent\n");
48261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
48271.1Skamil
48281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48301.1Skamil
48311.1Skamil	validate_status_exited(status, exitval);
48321.1Skamil
48331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
48351.1Skamil}
48361.1Skamil
48371.1SkamilATF_TC(siginfo4);
48381.1SkamilATF_TC_HEAD(siginfo4, tc)
48391.1Skamil{
48401.1Skamil	atf_tc_set_md_var(tc, "descr",
48411.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
48421.1Skamil}
48431.1Skamil
48441.1SkamilATF_TC_BODY(siginfo4, tc)
48451.1Skamil{
48461.1Skamil	const int sigval = SIGTRAP;
48471.1Skamil	pid_t child, wpid;
48481.1Skamil#if defined(TWAIT_HAVE_STATUS)
48491.1Skamil	int status;
48501.1Skamil#endif
48511.1Skamil
48521.1Skamil	struct ptrace_siginfo info;
48531.1Skamil	memset(&info, 0, sizeof(info));
48541.1Skamil
48551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48571.1Skamil	if (child == 0) {
48581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48601.1Skamil
48611.13Schristos		DPRINTF("Before calling execve(2) from child\n");
48621.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
48631.1Skamil
48641.1Skamil		FORKEE_ASSERT(0 && "Not reached");
48651.1Skamil	}
48661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
48671.1Skamil
48681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48701.1Skamil
48711.1Skamil	validate_status_stopped(status, sigval);
48721.1Skamil
48731.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48751.1Skamil
48761.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
48771.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
48781.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
48791.1Skamil	    info.psi_siginfo.si_errno);
48801.1Skamil
48811.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
48821.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
48831.1Skamil
48841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48851.1Skamil	    "without signal to be sent\n");
48861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
48871.1Skamil
48881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48901.1Skamil
48911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
48931.1Skamil}
48941.1Skamil
48951.1Skamil#if defined(TWAIT_HAVE_PID)
48961.1SkamilATF_TC(siginfo5);
48971.1SkamilATF_TC_HEAD(siginfo5, tc)
48981.1Skamil{
48991.1Skamil	atf_tc_set_md_var(tc, "descr",
49001.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
49011.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
49021.1Skamil}
49031.1Skamil
49041.1SkamilATF_TC_BODY(siginfo5, tc)
49051.1Skamil{
49061.1Skamil	const int exitval = 5;
49071.1Skamil	const int exitval2 = 15;
49081.1Skamil	const int sigval = SIGSTOP;
49091.1Skamil	pid_t child, child2, wpid;
49101.1Skamil#if defined(TWAIT_HAVE_STATUS)
49111.1Skamil	int status;
49121.1Skamil#endif
49131.1Skamil	ptrace_state_t state;
49141.1Skamil	const int slen = sizeof(state);
49151.1Skamil	ptrace_event_t event;
49161.1Skamil	const int elen = sizeof(event);
49171.1Skamil	struct ptrace_siginfo info;
49181.1Skamil
49191.1Skamil	memset(&info, 0, sizeof(info));
49201.1Skamil
49211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49231.1Skamil	if (child == 0) {
49241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49261.1Skamil
49271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49291.1Skamil
49301.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
49311.1Skamil
49321.1Skamil		if (child2 == 0)
49331.1Skamil			_exit(exitval2);
49341.1Skamil
49351.1Skamil		FORKEE_REQUIRE_SUCCESS
49361.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
49371.1Skamil
49381.1Skamil		forkee_status_exited(status, exitval2);
49391.1Skamil
49401.13Schristos		DPRINTF("Before exiting of the child process\n");
49411.1Skamil		_exit(exitval);
49421.1Skamil	}
49431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49441.1Skamil
49451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49471.1Skamil
49481.1Skamil	validate_status_stopped(status, sigval);
49491.1Skamil
49501.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49521.1Skamil
49531.13Schristos	DPRINTF("Before checking siginfo_t\n");
49541.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
49551.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
49561.1Skamil
49571.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
49581.1Skamil	event.pe_set_event = PTRACE_FORK;
49591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
49601.1Skamil
49611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49621.1Skamil	    "without signal to be sent\n");
49631.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
49641.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
49651.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
49661.1Skamil                "state.pe_other_pid=child)\n", child);
49671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49681.1Skamil
49691.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
49701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49711.1Skamil
49721.1Skamil	validate_status_stopped(status, SIGTRAP);
49731.1Skamil
49741.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49761.1Skamil
49771.13Schristos	DPRINTF("Before checking siginfo_t\n");
49781.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
49791.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
49801.1Skamil
49811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
49821.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
49831.1Skamil
49841.1Skamil	child2 = state.pe_other_pid;
49851.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
49861.1Skamil
49871.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
49881.1Skamil	    TWAIT_FNAME, child2, child);
49891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
49901.1Skamil	    child2);
49911.1Skamil
49921.1Skamil	validate_status_stopped(status, SIGTRAP);
49931.1Skamil
49941.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49961.1Skamil
49971.13Schristos	DPRINTF("Before checking siginfo_t\n");
49981.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
49991.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
50001.1Skamil
50011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
50021.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
50031.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
50041.1Skamil
50051.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
50061.1Skamil	    "without signal to be sent\n");
50071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -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, 0) != -1);
50121.1Skamil
50131.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
50141.1Skamil	    TWAIT_FNAME);
50151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
50161.1Skamil	    child2);
50171.1Skamil
50181.1Skamil	validate_status_exited(status, exitval2);
50191.1Skamil
50201.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
50211.1Skamil	    TWAIT_FNAME);
50221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
50231.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
50241.1Skamil
50251.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
50261.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
50271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50281.1Skamil
50291.1Skamil	validate_status_stopped(status, SIGCHLD);
50301.1Skamil
50311.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50331.1Skamil
50341.13Schristos	DPRINTF("Before checking siginfo_t\n");
50351.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
50361.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
50371.1Skamil
50381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50391.1Skamil	    "without signal to be sent\n");
50401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50411.1Skamil
50421.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
50431.1Skamil	    TWAIT_FNAME);
50441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50451.1Skamil
50461.1Skamil	validate_status_exited(status, exitval);
50471.1Skamil
50481.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
50491.1Skamil	    TWAIT_FNAME);
50501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50511.1Skamil}
50521.1Skamil#endif
50531.1Skamil
50541.1Skamil#if defined(PT_STEP)
50551.1SkamilATF_TC(siginfo6);
50561.1SkamilATF_TC_HEAD(siginfo6, tc)
50571.1Skamil{
50581.1Skamil	atf_tc_set_md_var(tc, "descr",
50591.1Skamil	    "Verify single PT_STEP call with signal information check");
50601.1Skamil}
50611.1Skamil
50621.1SkamilATF_TC_BODY(siginfo6, tc)
50631.1Skamil{
50641.1Skamil	const int exitval = 5;
50651.1Skamil	const int sigval = SIGSTOP;
50661.1Skamil	pid_t child, wpid;
50671.1Skamil#if defined(TWAIT_HAVE_STATUS)
50681.1Skamil	int status;
50691.1Skamil#endif
50701.1Skamil	int happy;
50711.1Skamil	struct ptrace_siginfo info;
50721.1Skamil
50731.1Skamil#if defined(__arm__)
50741.1Skamil	/* PT_STEP not supported on arm 32-bit */
50751.1Skamil	atf_tc_expect_fail("PR kern/52119");
50761.1Skamil#endif
50771.1Skamil
50781.1Skamil	memset(&info, 0, sizeof(info));
50791.1Skamil
50801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50821.1Skamil	if (child == 0) {
50831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50851.1Skamil
50861.1Skamil		happy = check_happy(100);
50871.1Skamil
50881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50901.1Skamil
50911.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
50921.1Skamil
50931.13Schristos		DPRINTF("Before exiting of the child process\n");
50941.1Skamil		_exit(exitval);
50951.1Skamil	}
50961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50971.1Skamil
50981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51001.1Skamil
51011.1Skamil	validate_status_stopped(status, sigval);
51021.1Skamil
51031.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51051.1Skamil
51061.13Schristos	DPRINTF("Before checking siginfo_t\n");
51071.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51081.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
51091.1Skamil
51101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51111.1Skamil	    "without signal to be sent (use PT_STEP)\n");
51121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
51131.1Skamil
51141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51161.1Skamil
51171.1Skamil	validate_status_stopped(status, SIGTRAP);
51181.1Skamil
51191.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51211.1Skamil
51221.13Schristos	DPRINTF("Before checking siginfo_t\n");
51231.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
51241.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
51251.1Skamil
51261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51271.1Skamil	    "without signal to be sent\n");
51281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51291.1Skamil
51301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51321.1Skamil
51331.1Skamil	validate_status_exited(status, exitval);
51341.1Skamil
51351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51371.1Skamil}
51381.1Skamil#endif
51391.1Skamil
51401.1Skamilvolatile lwpid_t the_lwp_id = 0;
51411.1Skamil
51421.1Skamilstatic void
51431.1Skamillwp_main_func(void *arg)
51441.1Skamil{
51451.1Skamil	the_lwp_id = _lwp_self();
51461.1Skamil	_lwp_exit();
51471.1Skamil}
51481.1Skamil
51491.1SkamilATF_TC(lwp_create1);
51501.1SkamilATF_TC_HEAD(lwp_create1, tc)
51511.1Skamil{
51521.1Skamil	atf_tc_set_md_var(tc, "descr",
51531.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
51541.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
51551.1Skamil}
51561.1Skamil
51571.1SkamilATF_TC_BODY(lwp_create1, tc)
51581.1Skamil{
51591.1Skamil	const int exitval = 5;
51601.1Skamil	const int sigval = SIGSTOP;
51611.1Skamil	pid_t child, wpid;
51621.1Skamil#if defined(TWAIT_HAVE_STATUS)
51631.1Skamil	int status;
51641.1Skamil#endif
51651.1Skamil	ptrace_state_t state;
51661.1Skamil	const int slen = sizeof(state);
51671.1Skamil	ptrace_event_t event;
51681.1Skamil	const int elen = sizeof(event);
51691.1Skamil	ucontext_t uc;
51701.1Skamil	lwpid_t lid;
51711.1Skamil	static const size_t ssize = 16*1024;
51721.1Skamil	void *stack;
51731.1Skamil
51741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51761.1Skamil	if (child == 0) {
51771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51791.1Skamil
51801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
51811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
51821.1Skamil
51831.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
51841.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
51851.1Skamil
51861.13Schristos		DPRINTF("Before making context for new lwp in child\n");
51871.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
51881.1Skamil
51891.13Schristos		DPRINTF("Before creating new in child\n");
51901.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
51911.1Skamil
51921.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
51931.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
51941.1Skamil
51951.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
51961.1Skamil		    "are the same\n", lid, the_lwp_id);
51971.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
51981.1Skamil
51991.13Schristos		DPRINTF("Before exiting of the child process\n");
52001.1Skamil		_exit(exitval);
52011.1Skamil	}
52021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52031.1Skamil
52041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52061.1Skamil
52071.1Skamil	validate_status_stopped(status, sigval);
52081.1Skamil
52091.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
52101.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
52111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52121.1Skamil
52131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52141.1Skamil	    "without signal to be sent\n");
52151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52161.1Skamil
52171.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
52181.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
52191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52201.1Skamil
52211.1Skamil	validate_status_stopped(status, SIGTRAP);
52221.1Skamil
52231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52241.1Skamil
52251.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
52261.1Skamil
52271.1Skamil	lid = state.pe_lwp;
52281.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
52291.1Skamil
52301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52311.1Skamil	    "without signal to be sent\n");
52321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52331.1Skamil
52341.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
52351.1Skamil	    TWAIT_FNAME);
52361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52371.1Skamil
52381.1Skamil	validate_status_exited(status, exitval);
52391.1Skamil
52401.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
52411.1Skamil	    TWAIT_FNAME);
52421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
52431.1Skamil}
52441.1Skamil
52451.1SkamilATF_TC(lwp_exit1);
52461.1SkamilATF_TC_HEAD(lwp_exit1, tc)
52471.1Skamil{
52481.1Skamil	atf_tc_set_md_var(tc, "descr",
52491.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
52501.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
52511.1Skamil}
52521.1Skamil
52531.1SkamilATF_TC_BODY(lwp_exit1, tc)
52541.1Skamil{
52551.1Skamil	const int exitval = 5;
52561.1Skamil	const int sigval = SIGSTOP;
52571.1Skamil	pid_t child, wpid;
52581.1Skamil#if defined(TWAIT_HAVE_STATUS)
52591.1Skamil	int status;
52601.1Skamil#endif
52611.1Skamil	ptrace_state_t state;
52621.1Skamil	const int slen = sizeof(state);
52631.1Skamil	ptrace_event_t event;
52641.1Skamil	const int elen = sizeof(event);
52651.1Skamil	ucontext_t uc;
52661.1Skamil	lwpid_t lid;
52671.1Skamil	static const size_t ssize = 16*1024;
52681.1Skamil	void *stack;
52691.1Skamil
52701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52721.1Skamil	if (child == 0) {
52731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52751.1Skamil
52761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52781.1Skamil
52791.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
52801.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
52811.1Skamil
52821.13Schristos		DPRINTF("Before making context for new lwp in child\n");
52831.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
52841.1Skamil
52851.13Schristos		DPRINTF("Before creating new in child\n");
52861.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
52871.1Skamil
52881.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
52891.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
52901.1Skamil
52911.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
52921.1Skamil		    "are the same\n", lid, the_lwp_id);
52931.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
52941.1Skamil
52951.13Schristos		DPRINTF("Before exiting of the child process\n");
52961.1Skamil		_exit(exitval);
52971.1Skamil	}
52981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52991.1Skamil
53001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53021.1Skamil
53031.1Skamil	validate_status_stopped(status, sigval);
53041.1Skamil
53051.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
53061.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
53071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
53081.1Skamil
53091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53101.1Skamil	    "without signal to be sent\n");
53111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53121.1Skamil
53131.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53141.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
53151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53161.1Skamil
53171.1Skamil	validate_status_stopped(status, SIGTRAP);
53181.1Skamil
53191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
53201.1Skamil
53211.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
53221.1Skamil
53231.1Skamil	lid = state.pe_lwp;
53241.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
53251.1Skamil
53261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53271.1Skamil	    "without signal to be sent\n");
53281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53291.1Skamil
53301.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53311.1Skamil	    TWAIT_FNAME);
53321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53331.1Skamil
53341.1Skamil	validate_status_exited(status, exitval);
53351.1Skamil
53361.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53371.1Skamil	    TWAIT_FNAME);
53381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53391.1Skamil}
53401.1Skamil
53411.1SkamilATF_TC(signal1);
53421.1SkamilATF_TC_HEAD(signal1, tc)
53431.1Skamil{
53441.1Skamil	atf_tc_set_md_var(tc, "descr",
53451.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
53461.1Skamil	    "from catching other signals");
53471.1Skamil}
53481.1Skamil
53491.1SkamilATF_TC_BODY(signal1, tc)
53501.1Skamil{
53511.1Skamil	const int exitval = 5;
53521.1Skamil	const int sigval = SIGSTOP;
53531.1Skamil	const int sigmasked = SIGTRAP;
53541.1Skamil	const int signotmasked = SIGINT;
53551.1Skamil	pid_t child, wpid;
53561.1Skamil#if defined(TWAIT_HAVE_STATUS)
53571.1Skamil	int status;
53581.1Skamil#endif
53591.1Skamil	sigset_t intmask;
53601.1Skamil
53611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53631.1Skamil	if (child == 0) {
53641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53661.1Skamil
53671.1Skamil		sigemptyset(&intmask);
53681.1Skamil		sigaddset(&intmask, sigmasked);
53691.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
53701.1Skamil
53711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53731.1Skamil
53741.13Schristos		DPRINTF("Before raising %s from child\n",
53751.1Skamil		    strsignal(signotmasked));
53761.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
53771.1Skamil
53781.13Schristos		DPRINTF("Before exiting of the child process\n");
53791.1Skamil		_exit(exitval);
53801.1Skamil	}
53811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53821.1Skamil
53831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53851.1Skamil
53861.1Skamil	validate_status_stopped(status, sigval);
53871.1Skamil
53881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53891.1Skamil	    "without signal to be sent\n");
53901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53911.1Skamil
53921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53941.1Skamil
53951.1Skamil	validate_status_stopped(status, signotmasked);
53961.1Skamil
53971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53981.1Skamil	    "without signal to be sent\n");
53991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54001.1Skamil
54011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54031.1Skamil
54041.1Skamil	validate_status_exited(status, exitval);
54051.1Skamil
54061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54081.1Skamil}
54091.1Skamil
54101.1SkamilATF_TC(signal2);
54111.1SkamilATF_TC_HEAD(signal2, tc)
54121.1Skamil{
54131.1Skamil	atf_tc_set_md_var(tc, "descr",
54141.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
54151.1Skamil	    "catching this raised signal");
54161.1Skamil}
54171.1Skamil
54181.1SkamilATF_TC_BODY(signal2, tc)
54191.1Skamil{
54201.1Skamil	const int exitval = 5;
54211.1Skamil	const int sigval = SIGSTOP;
54221.1Skamil	const int sigmasked = SIGTRAP;
54231.1Skamil	pid_t child, wpid;
54241.1Skamil#if defined(TWAIT_HAVE_STATUS)
54251.1Skamil	int status;
54261.1Skamil#endif
54271.1Skamil	sigset_t intmask;
54281.1Skamil
54291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54311.1Skamil	if (child == 0) {
54321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54341.1Skamil
54351.1Skamil		sigemptyset(&intmask);
54361.1Skamil		sigaddset(&intmask, sigmasked);
54371.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
54381.1Skamil
54391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54411.1Skamil
54421.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
54431.1Skamil		    strsignal(sigmasked));
54441.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
54451.1Skamil
54461.13Schristos		DPRINTF("Before exiting of the child process\n");
54471.1Skamil		_exit(exitval);
54481.1Skamil	}
54491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54501.1Skamil
54511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54531.1Skamil
54541.1Skamil	validate_status_stopped(status, sigval);
54551.1Skamil
54561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54571.1Skamil	    "without signal to be sent\n");
54581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54591.1Skamil
54601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54621.1Skamil
54631.1Skamil	validate_status_exited(status, exitval);
54641.1Skamil
54651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54671.1Skamil}
54681.1Skamil
54691.1SkamilATF_TC(signal3);
54701.1SkamilATF_TC_HEAD(signal3, tc)
54711.1Skamil{
54721.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
54731.1Skamil	atf_tc_set_md_var(tc, "descr",
54741.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
54751.1Skamil	    "catching software breakpoints");
54761.1Skamil}
54771.1Skamil
54781.1SkamilATF_TC_BODY(signal3, tc)
54791.1Skamil{
54801.1Skamil	const int exitval = 5;
54811.1Skamil	const int sigval = SIGSTOP;
54821.1Skamil	const int sigmasked = SIGTRAP;
54831.1Skamil	pid_t child, wpid;
54841.1Skamil#if defined(TWAIT_HAVE_STATUS)
54851.1Skamil	int status;
54861.1Skamil#endif
54871.1Skamil	sigset_t intmask;
54881.1Skamil
54891.20Skamil	atf_tc_expect_fail("PR kern/51918");
54901.20Skamil
54911.20Skamil	// This test breaks now on some ports, temporarily disable it
54921.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
54931.20Skamil
54941.10Smartin#if defined(__sparc__)
54951.7Skamil	atf_tc_expect_timeout("PR kern/52167");
54961.7Skamil
54971.7Skamil	// timeout wins, failure still valid
54981.7Skamil	// atf_tc_expect_fail("PR kern/51918");
54991.7Skamil#endif
55001.1Skamil
55011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55031.1Skamil	if (child == 0) {
55041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55061.1Skamil
55071.1Skamil		sigemptyset(&intmask);
55081.1Skamil		sigaddset(&intmask, sigmasked);
55091.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55101.1Skamil
55111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55131.1Skamil
55141.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
55151.4Skamil
55161.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
55171.4Skamil		PTRACE_BREAKPOINT_ASM;
55181.1Skamil#else
55191.4Skamil		/* port me */
55201.1Skamil#endif
55211.1Skamil
55221.13Schristos		DPRINTF("Before exiting of the child process\n");
55231.1Skamil		_exit(exitval);
55241.1Skamil	}
55251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55261.1Skamil
55271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55291.1Skamil
55301.1Skamil	validate_status_stopped(status, sigval);
55311.1Skamil
55321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55331.1Skamil	    "without signal to be sent\n");
55341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55351.1Skamil
55361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55381.1Skamil
55391.1Skamil	validate_status_stopped(status, sigmasked);
55401.1Skamil
55411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55421.1Skamil	    "without signal to be sent\n");
55431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55441.1Skamil
55451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55471.1Skamil
55481.1Skamil	validate_status_exited(status, exitval);
55491.1Skamil
55501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55521.1Skamil}
55531.1Skamil
55541.1Skamil#if defined(PT_STEP)
55551.1SkamilATF_TC(signal4);
55561.1SkamilATF_TC_HEAD(signal4, tc)
55571.1Skamil{
55581.1Skamil	atf_tc_set_md_var(tc, "descr",
55591.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55601.1Skamil	    "catching single step trap");
55611.1Skamil}
55621.1Skamil
55631.1SkamilATF_TC_BODY(signal4, tc)
55641.1Skamil{
55651.1Skamil	const int exitval = 5;
55661.1Skamil	const int sigval = SIGSTOP;
55671.1Skamil	const int sigmasked = SIGTRAP;
55681.1Skamil	pid_t child, wpid;
55691.1Skamil#if defined(TWAIT_HAVE_STATUS)
55701.1Skamil	int status;
55711.1Skamil#endif
55721.1Skamil	sigset_t intmask;
55731.1Skamil	int happy;
55741.1Skamil
55751.1Skamil#if defined(__arm__)
55761.5Skamil	/* PT_STEP not supported on arm 32-bit */
55771.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
55781.1Skamil#endif
55791.1Skamil
55801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55821.1Skamil	if (child == 0) {
55831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55851.1Skamil
55861.1Skamil		happy = check_happy(100);
55871.1Skamil
55881.1Skamil		sigemptyset(&intmask);
55891.1Skamil		sigaddset(&intmask, sigmasked);
55901.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55911.1Skamil
55921.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55931.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55941.1Skamil
55951.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
55961.1Skamil
55971.13Schristos		DPRINTF("Before exiting of the child process\n");
55981.1Skamil		_exit(exitval);
55991.1Skamil	}
56001.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56011.1Skamil
56021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56041.1Skamil
56051.1Skamil	validate_status_stopped(status, sigval);
56061.1Skamil
56071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56081.1Skamil	    "without signal to be sent\n");
56091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
56101.1Skamil
56111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56131.1Skamil
56141.1Skamil	validate_status_stopped(status, sigmasked);
56151.1Skamil
56161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56171.1Skamil	    "without signal to be sent\n");
56181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56191.1Skamil
56201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56221.1Skamil
56231.1Skamil	validate_status_exited(status, exitval);
56241.1Skamil
56251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56271.1Skamil}
56281.1Skamil#endif
56291.1Skamil
56301.1SkamilATF_TC(signal5);
56311.1SkamilATF_TC_HEAD(signal5, tc)
56321.1Skamil{
56331.1Skamil	atf_tc_set_md_var(tc, "descr",
56341.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
56351.1Skamil	    "catching exec() breakpoint");
56361.1Skamil}
56371.1Skamil
56381.1SkamilATF_TC_BODY(signal5, tc)
56391.1Skamil{
56401.1Skamil	const int exitval = 5;
56411.1Skamil	const int sigval = SIGSTOP;
56421.1Skamil	const int sigmasked = SIGTRAP;
56431.1Skamil	pid_t child, wpid;
56441.1Skamil#if defined(TWAIT_HAVE_STATUS)
56451.1Skamil	int status;
56461.1Skamil#endif
56471.1Skamil	sigset_t intmask;
56481.1Skamil
56491.14Schristos	atf_tc_expect_fail("wrong signal");
56501.14Schristos
56511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56531.1Skamil	if (child == 0) {
56541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56561.1Skamil
56571.1Skamil		sigemptyset(&intmask);
56581.1Skamil		sigaddset(&intmask, sigmasked);
56591.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56601.1Skamil
56611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56631.1Skamil
56641.13Schristos		DPRINTF("Before calling execve(2) from child\n");
56651.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
56661.1Skamil
56671.13Schristos		DPRINTF("Before exiting of the child process\n");
56681.1Skamil		_exit(exitval);
56691.1Skamil	}
56701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56711.1Skamil
56721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56741.1Skamil
56751.1Skamil	validate_status_stopped(status, sigval);
56761.1Skamil
56771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56781.1Skamil	    "without signal to be sent\n");
56791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56801.1Skamil
56811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56831.1Skamil
56841.1Skamil	validate_status_stopped(status, sigmasked);
56851.1Skamil
56861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56871.1Skamil	    "without signal to be sent\n");
56881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56891.1Skamil
56901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56921.1Skamil
56931.1Skamil	validate_status_exited(status, exitval);
56941.1Skamil
56951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56971.1Skamil}
56981.1Skamil
56991.1Skamil#if defined(TWAIT_HAVE_PID)
57001.1SkamilATF_TC(signal6);
57011.1SkamilATF_TC_HEAD(signal6, tc)
57021.1Skamil{
57031.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57041.1Skamil	atf_tc_set_md_var(tc, "descr",
57051.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57061.1Skamil	    "catching PTRACE_FORK breakpoint");
57071.1Skamil}
57081.1Skamil
57091.1SkamilATF_TC_BODY(signal6, tc)
57101.1Skamil{
57111.1Skamil	const int exitval = 5;
57121.1Skamil	const int exitval2 = 15;
57131.1Skamil	const int sigval = SIGSTOP;
57141.1Skamil	const int sigmasked = SIGTRAP;
57151.1Skamil	pid_t child, child2, wpid;
57161.1Skamil#if defined(TWAIT_HAVE_STATUS)
57171.1Skamil	int status;
57181.1Skamil#endif
57191.1Skamil	sigset_t intmask;
57201.1Skamil	ptrace_state_t state;
57211.1Skamil	const int slen = sizeof(state);
57221.1Skamil	ptrace_event_t event;
57231.1Skamil	const int elen = sizeof(event);
57241.1Skamil
57251.14Schristos	atf_tc_expect_timeout("PR kern/51918");
57261.14Schristos
57271.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57281.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57291.1Skamil	if (child == 0) {
57301.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57311.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57321.1Skamil
57331.1Skamil		sigemptyset(&intmask);
57341.1Skamil		sigaddset(&intmask, sigmasked);
57351.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57361.1Skamil
57371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57391.1Skamil
57401.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
57411.1Skamil
57421.1Skamil		if (child2 == 0)
57431.1Skamil			_exit(exitval2);
57441.1Skamil
57451.1Skamil		FORKEE_REQUIRE_SUCCESS
57461.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
57471.1Skamil
57481.1Skamil		forkee_status_exited(status, exitval2);
57491.1Skamil
57501.13Schristos		DPRINTF("Before exiting of the child process\n");
57511.1Skamil		_exit(exitval);
57521.1Skamil	}
57531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57541.1Skamil
57551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57571.1Skamil
57581.1Skamil	validate_status_stopped(status, sigval);
57591.1Skamil
57601.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
57611.1Skamil	event.pe_set_event = PTRACE_FORK;
57621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
57631.1Skamil
57641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57651.1Skamil	    "without signal to be sent\n");
57661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57671.1Skamil
57681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57701.1Skamil
57711.1Skamil	validate_status_stopped(status, sigmasked);
57721.1Skamil
57731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
57741.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
57751.1Skamil
57761.1Skamil	child2 = state.pe_other_pid;
57771.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
57781.1Skamil
57791.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
57801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
57811.1Skamil	    child2);
57821.1Skamil
57831.1Skamil	validate_status_stopped(status, SIGTRAP);
57841.1Skamil
57851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
57861.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
57871.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
57881.1Skamil
57891.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
57901.1Skamil	    "without signal to be sent\n");
57911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
57921.1Skamil
57931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57941.1Skamil	    "without signal to be sent\n");
57951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57961.1Skamil
57971.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
57981.1Skamil	    TWAIT_FNAME);
57991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58001.1Skamil	    child2);
58011.1Skamil
58021.1Skamil	validate_status_exited(status, exitval2);
58031.1Skamil
58041.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
58051.1Skamil	    TWAIT_FNAME);
58061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
58071.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
58081.1Skamil
58091.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
58101.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
58111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58121.1Skamil
58131.1Skamil	validate_status_stopped(status, SIGCHLD);
58141.1Skamil
58151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58161.1Skamil	    "without signal to be sent\n");
58171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58181.1Skamil
58191.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
58201.1Skamil	    TWAIT_FNAME);
58211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58221.1Skamil
58231.1Skamil	validate_status_exited(status, exitval);
58241.1Skamil
58251.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
58261.1Skamil	    TWAIT_FNAME);
58271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58281.1Skamil}
58291.1Skamil#endif
58301.1Skamil
58311.1Skamil#if defined(TWAIT_HAVE_PID)
58321.1SkamilATF_TC(signal7);
58331.1SkamilATF_TC_HEAD(signal7, tc)
58341.1Skamil{
58351.1Skamil	atf_tc_set_md_var(tc, "descr",
58361.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58371.1Skamil	    "catching PTRACE_VFORK breakpoint");
58381.1Skamil}
58391.1Skamil
58401.1SkamilATF_TC_BODY(signal7, tc)
58411.1Skamil{
58421.1Skamil	const int exitval = 5;
58431.1Skamil	const int exitval2 = 15;
58441.1Skamil	const int sigval = SIGSTOP;
58451.1Skamil	const int sigmasked = SIGTRAP;
58461.1Skamil	pid_t child, child2, wpid;
58471.1Skamil#if defined(TWAIT_HAVE_STATUS)
58481.1Skamil	int status;
58491.1Skamil#endif
58501.1Skamil	sigset_t intmask;
58511.1Skamil	ptrace_state_t state;
58521.1Skamil	const int slen = sizeof(state);
58531.1Skamil	ptrace_event_t event;
58541.1Skamil	const int elen = sizeof(event);
58551.1Skamil
58561.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
58571.14Schristos
58581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58601.1Skamil	if (child == 0) {
58611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58631.1Skamil
58641.1Skamil		sigemptyset(&intmask);
58651.1Skamil		sigaddset(&intmask, sigmasked);
58661.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58671.1Skamil
58681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58701.1Skamil
58711.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
58721.1Skamil
58731.1Skamil		if (child2 == 0)
58741.1Skamil			_exit(exitval2);
58751.1Skamil
58761.1Skamil		FORKEE_REQUIRE_SUCCESS
58771.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
58781.1Skamil
58791.1Skamil		forkee_status_exited(status, exitval2);
58801.1Skamil
58811.13Schristos		DPRINTF("Before exiting of the child process\n");
58821.1Skamil		_exit(exitval);
58831.1Skamil	}
58841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58851.1Skamil
58861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58881.1Skamil
58891.1Skamil	validate_status_stopped(status, sigval);
58901.1Skamil
58911.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
58921.1Skamil	event.pe_set_event = PTRACE_VFORK;
58931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
58941.1Skamil
58951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58961.1Skamil	    "without signal to be sent\n");
58971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58981.1Skamil
58991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59011.1Skamil
59021.1Skamil	validate_status_stopped(status, sigmasked);
59031.1Skamil
59041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
59051.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
59061.1Skamil
59071.1Skamil	child2 = state.pe_other_pid;
59081.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
59091.1Skamil
59101.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
59111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
59121.1Skamil	    child2);
59131.1Skamil
59141.1Skamil	validate_status_stopped(status, SIGTRAP);
59151.1Skamil
59161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
59171.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
59181.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
59191.1Skamil
59201.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
59211.1Skamil	    "without signal to be sent\n");
59221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
59231.1Skamil
59241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59251.1Skamil	    "without signal to be sent\n");
59261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59271.1Skamil
59281.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
59291.1Skamil	    TWAIT_FNAME);
59301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
59311.1Skamil	    child2);
59321.1Skamil
59331.1Skamil	validate_status_exited(status, exitval2);
59341.1Skamil
59351.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
59361.1Skamil	    TWAIT_FNAME);
59371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
59381.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
59391.1Skamil
59401.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
59411.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
59421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59431.1Skamil
59441.1Skamil	validate_status_stopped(status, SIGCHLD);
59451.1Skamil
59461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59471.1Skamil	    "without signal to be sent\n");
59481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59491.1Skamil
59501.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
59511.1Skamil	    TWAIT_FNAME);
59521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59531.1Skamil
59541.1Skamil	validate_status_exited(status, exitval);
59551.1Skamil
59561.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
59571.1Skamil	    TWAIT_FNAME);
59581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59591.1Skamil}
59601.1Skamil#endif
59611.1Skamil
59621.1SkamilATF_TC(signal8);
59631.1SkamilATF_TC_HEAD(signal8, tc)
59641.1Skamil{
59651.1Skamil	atf_tc_set_md_var(tc, "descr",
59661.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59671.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
59681.1Skamil}
59691.1Skamil
59701.1SkamilATF_TC_BODY(signal8, tc)
59711.1Skamil{
59721.1Skamil	const int exitval = 5;
59731.1Skamil	const int exitval2 = 15;
59741.1Skamil	const int sigval = SIGSTOP;
59751.1Skamil	const int sigmasked = SIGTRAP;
59761.1Skamil	pid_t child, child2, wpid;
59771.1Skamil#if defined(TWAIT_HAVE_STATUS)
59781.1Skamil	int status;
59791.1Skamil#endif
59801.1Skamil	sigset_t intmask;
59811.1Skamil	ptrace_state_t state;
59821.1Skamil	const int slen = sizeof(state);
59831.1Skamil	ptrace_event_t event;
59841.1Skamil	const int elen = sizeof(event);
59851.1Skamil
59861.14Schristos	atf_tc_expect_fail("PR kern/51918");
59871.14Schristos
59881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59901.1Skamil	if (child == 0) {
59911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59931.1Skamil
59941.1Skamil		sigemptyset(&intmask);
59951.1Skamil		sigaddset(&intmask, sigmasked);
59961.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59971.1Skamil
59981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60001.1Skamil
60011.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
60021.1Skamil
60031.1Skamil		if (child2 == 0)
60041.1Skamil			_exit(exitval2);
60051.1Skamil
60061.1Skamil		FORKEE_REQUIRE_SUCCESS
60071.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60081.1Skamil
60091.1Skamil		forkee_status_exited(status, exitval2);
60101.1Skamil
60111.13Schristos		DPRINTF("Before exiting of the child process\n");
60121.1Skamil		_exit(exitval);
60131.1Skamil	}
60141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60151.1Skamil
60161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60181.1Skamil
60191.1Skamil	validate_status_stopped(status, sigval);
60201.1Skamil
60211.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
60221.1Skamil	    child);
60231.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
60241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60251.1Skamil
60261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60271.1Skamil	    "without signal to be sent\n");
60281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60291.1Skamil
60301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60321.1Skamil
60331.1Skamil	validate_status_stopped(status, sigmasked);
60341.1Skamil
60351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60361.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
60371.1Skamil
60381.1Skamil	child2 = state.pe_other_pid;
60391.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
60401.1Skamil
60411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60421.1Skamil	    "without signal to be sent\n");
60431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60441.1Skamil
60451.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60461.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
60471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60481.1Skamil
60491.1Skamil	validate_status_stopped(status, SIGCHLD);
60501.1Skamil
60511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60521.1Skamil	    "without signal to be sent\n");
60531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60541.1Skamil
60551.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60561.1Skamil	    TWAIT_FNAME);
60571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60581.1Skamil
60591.1Skamil	validate_status_exited(status, exitval);
60601.1Skamil
60611.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60621.1Skamil	    TWAIT_FNAME);
60631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60641.1Skamil}
60651.1Skamil
60661.1SkamilATF_TC(signal9);
60671.1SkamilATF_TC_HEAD(signal9, tc)
60681.1Skamil{
60691.1Skamil	atf_tc_set_md_var(tc, "descr",
60701.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
60711.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
60721.1Skamil}
60731.1Skamil
60741.1SkamilATF_TC_BODY(signal9, tc)
60751.1Skamil{
60761.1Skamil	const int exitval = 5;
60771.1Skamil	const int sigval = SIGSTOP;
60781.1Skamil	const int sigmasked = SIGTRAP;
60791.1Skamil	pid_t child, wpid;
60801.1Skamil#if defined(TWAIT_HAVE_STATUS)
60811.1Skamil	int status;
60821.1Skamil#endif
60831.1Skamil	sigset_t intmask;
60841.1Skamil	ptrace_state_t state;
60851.1Skamil	const int slen = sizeof(state);
60861.1Skamil	ptrace_event_t event;
60871.1Skamil	const int elen = sizeof(event);
60881.1Skamil	ucontext_t uc;
60891.1Skamil	lwpid_t lid;
60901.1Skamil	static const size_t ssize = 16*1024;
60911.1Skamil	void *stack;
60921.1Skamil
60931.14Schristos	atf_tc_expect_fail("PR kern/51918");
60941.14Schristos
60951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60971.1Skamil	if (child == 0) {
60981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61001.1Skamil
61011.1Skamil		sigemptyset(&intmask);
61021.1Skamil		sigaddset(&intmask, sigmasked);
61031.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61041.1Skamil
61051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61071.1Skamil
61081.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
61091.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
61101.1Skamil
61111.13Schristos		DPRINTF("Before making context for new lwp in child\n");
61121.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
61131.1Skamil
61141.13Schristos		DPRINTF("Before creating new in child\n");
61151.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
61161.1Skamil
61171.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
61181.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
61191.1Skamil
61201.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
61211.1Skamil		    "are the same\n", lid, the_lwp_id);
61221.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
61231.1Skamil
61241.13Schristos		DPRINTF("Before exiting of the child process\n");
61251.1Skamil		_exit(exitval);
61261.1Skamil	}
61271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61281.1Skamil
61291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61311.1Skamil
61321.1Skamil	validate_status_stopped(status, sigval);
61331.1Skamil
61341.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
61351.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
61361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
61371.1Skamil
61381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61391.1Skamil	    "without signal to be sent\n");
61401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61411.1Skamil
61421.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61431.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
61441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61451.1Skamil
61461.1Skamil	validate_status_stopped(status, sigmasked);
61471.1Skamil
61481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61491.1Skamil
61501.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
61511.1Skamil
61521.1Skamil	lid = state.pe_lwp;
61531.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
61541.1Skamil
61551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61561.1Skamil	    "without signal to be sent\n");
61571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61581.1Skamil
61591.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61601.1Skamil	    TWAIT_FNAME);
61611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61621.1Skamil
61631.1Skamil	validate_status_exited(status, exitval);
61641.1Skamil
61651.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61661.1Skamil	    TWAIT_FNAME);
61671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61681.1Skamil}
61691.1Skamil
61701.1SkamilATF_TC(signal10);
61711.1SkamilATF_TC_HEAD(signal10, tc)
61721.1Skamil{
61731.1Skamil	atf_tc_set_md_var(tc, "descr",
61741.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61751.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
61761.1Skamil}
61771.1Skamil
61781.1SkamilATF_TC_BODY(signal10, tc)
61791.1Skamil{
61801.1Skamil	const int exitval = 5;
61811.1Skamil	const int sigval = SIGSTOP;
61821.1Skamil	const int sigmasked = SIGTRAP;
61831.1Skamil	pid_t child, wpid;
61841.1Skamil#if defined(TWAIT_HAVE_STATUS)
61851.1Skamil	int status;
61861.1Skamil#endif
61871.1Skamil	sigset_t intmask;
61881.1Skamil	ptrace_state_t state;
61891.1Skamil	const int slen = sizeof(state);
61901.1Skamil	ptrace_event_t event;
61911.1Skamil	const int elen = sizeof(event);
61921.1Skamil	ucontext_t uc;
61931.1Skamil	lwpid_t lid;
61941.1Skamil	static const size_t ssize = 16*1024;
61951.1Skamil	void *stack;
61961.1Skamil
61971.14Schristos	atf_tc_expect_fail("PR kern/51918");
61981.14Schristos
61991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62011.1Skamil	if (child == 0) {
62021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62041.1Skamil
62051.1Skamil		sigemptyset(&intmask);
62061.1Skamil		sigaddset(&intmask, sigmasked);
62071.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62081.1Skamil
62091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62111.1Skamil
62121.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
62131.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
62141.1Skamil
62151.13Schristos		DPRINTF("Before making context for new lwp in child\n");
62161.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
62171.1Skamil
62181.13Schristos		DPRINTF("Before creating new in child\n");
62191.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
62201.1Skamil
62211.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
62221.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
62231.1Skamil
62241.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
62251.1Skamil		    "are the same\n", lid, the_lwp_id);
62261.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
62271.1Skamil
62281.13Schristos		DPRINTF("Before exiting of the child process\n");
62291.1Skamil		_exit(exitval);
62301.1Skamil	}
62311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62321.1Skamil
62331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62351.1Skamil
62361.1Skamil	validate_status_stopped(status, sigval);
62371.1Skamil
62381.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
62391.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
62401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
62411.1Skamil
62421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62431.1Skamil	    "without signal to be sent\n");
62441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62451.1Skamil
62461.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62471.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
62481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62491.1Skamil
62501.1Skamil	validate_status_stopped(status, sigmasked);
62511.1Skamil
62521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
62531.1Skamil
62541.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
62551.1Skamil
62561.1Skamil	lid = state.pe_lwp;
62571.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
62581.1Skamil
62591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62601.1Skamil	    "without signal to be sent\n");
62611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62621.1Skamil
62631.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62641.1Skamil	    TWAIT_FNAME);
62651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62661.1Skamil
62671.1Skamil	validate_status_exited(status, exitval);
62681.1Skamil
62691.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62701.1Skamil	    TWAIT_FNAME);
62711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62721.1Skamil}
62731.1Skamil
62741.1Skamilstatic void
62751.1Skamillwp_main_stop(void *arg)
62761.1Skamil{
62771.1Skamil	the_lwp_id = _lwp_self();
62781.1Skamil
62791.1Skamil	raise(SIGTRAP);
62801.1Skamil
62811.1Skamil	_lwp_exit();
62821.1Skamil}
62831.1Skamil
62841.1SkamilATF_TC(suspend1);
62851.1SkamilATF_TC_HEAD(suspend1, tc)
62861.1Skamil{
62871.1Skamil	atf_tc_set_md_var(tc, "descr",
62881.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
62891.1Skamil	    "resumed by a tracee");
62901.1Skamil}
62911.1Skamil
62921.1SkamilATF_TC_BODY(suspend1, tc)
62931.1Skamil{
62941.1Skamil	const int exitval = 5;
62951.1Skamil	const int sigval = SIGSTOP;
62961.1Skamil	pid_t child, wpid;
62971.1Skamil#if defined(TWAIT_HAVE_STATUS)
62981.1Skamil	int status;
62991.1Skamil#endif
63001.1Skamil	ucontext_t uc;
63011.1Skamil	lwpid_t lid;
63021.1Skamil	static const size_t ssize = 16*1024;
63031.1Skamil	void *stack;
63041.1Skamil	struct ptrace_lwpinfo pl;
63051.1Skamil	struct ptrace_siginfo psi;
63061.1Skamil	volatile int go = 0;
63071.1Skamil
63081.17Skamil	// Feature pending for refactoring
63091.17Skamil	atf_tc_expect_fail("PR kern/51995");
63101.17Skamil
63111.16Skamil	// Hangs with qemu
63121.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
63131.16Skamil
63141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63161.1Skamil	if (child == 0) {
63171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63191.1Skamil
63201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63221.1Skamil
63231.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63241.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
63251.1Skamil
63261.13Schristos		DPRINTF("Before making context for new lwp in child\n");
63271.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
63281.1Skamil
63291.13Schristos		DPRINTF("Before creating new in child\n");
63301.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
63311.1Skamil
63321.1Skamil		while (go == 0)
63331.1Skamil			continue;
63341.1Skamil
63351.1Skamil		raise(SIGINT);
63361.1Skamil
63371.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
63381.1Skamil
63391.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
63401.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
63411.1Skamil
63421.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
63431.1Skamil		    "are the same\n", lid, the_lwp_id);
63441.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
63451.1Skamil
63461.13Schristos		DPRINTF("Before exiting of the child process\n");
63471.1Skamil		_exit(exitval);
63481.1Skamil	}
63491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63501.1Skamil
63511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63531.1Skamil
63541.1Skamil	validate_status_stopped(status, sigval);
63551.1Skamil
63561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63571.1Skamil	    "without signal to be sent\n");
63581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63591.1Skamil
63601.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63611.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
63621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63631.1Skamil
63641.1Skamil	validate_status_stopped(status, SIGTRAP);
63651.1Skamil
63661.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
63671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
63681.1Skamil
63691.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
63701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
63711.1Skamil
63721.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
63731.1Skamil	    child, getpid());
63741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
63751.1Skamil
63761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63771.1Skamil	    "without signal to be sent\n");
63781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63791.1Skamil
63801.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63811.1Skamil	    "SIGINT\n", TWAIT_FNAME);
63821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63831.1Skamil
63841.1Skamil	validate_status_stopped(status, SIGINT);
63851.1Skamil
63861.1Skamil	pl.pl_lwpid = 0;
63871.1Skamil
63881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
63891.1Skamil	while (pl.pl_lwpid != 0) {
63901.1Skamil
63911.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
63921.1Skamil		switch (pl.pl_lwpid) {
63931.1Skamil		case 1:
63941.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
63951.1Skamil			break;
63961.1Skamil		case 2:
63971.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
63981.1Skamil			break;
63991.1Skamil		}
64001.1Skamil	}
64011.1Skamil
64021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64031.1Skamil	    "without signal to be sent\n");
64041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64051.1Skamil
64061.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64071.1Skamil	    TWAIT_FNAME);
64081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64091.1Skamil
64101.1Skamil	validate_status_exited(status, exitval);
64111.1Skamil
64121.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64131.1Skamil	    TWAIT_FNAME);
64141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64151.1Skamil}
64161.1Skamil
64171.1SkamilATF_TC(suspend2);
64181.1SkamilATF_TC_HEAD(suspend2, tc)
64191.1Skamil{
64201.1Skamil	atf_tc_set_md_var(tc, "descr",
64211.1Skamil	    "Verify that the while the only thread within a process is "
64221.1Skamil	    "suspended, the whole process cannot be unstopped");
64231.1Skamil}
64241.1Skamil
64251.1SkamilATF_TC_BODY(suspend2, tc)
64261.1Skamil{
64271.1Skamil	const int exitval = 5;
64281.1Skamil	const int sigval = SIGSTOP;
64291.1Skamil	pid_t child, wpid;
64301.1Skamil#if defined(TWAIT_HAVE_STATUS)
64311.1Skamil	int status;
64321.1Skamil#endif
64331.1Skamil	struct ptrace_siginfo psi;
64341.1Skamil
64351.17Skamil	// Feature pending for refactoring
64361.17Skamil	atf_tc_expect_fail("PR kern/51995");
64371.17Skamil
64381.16Skamil	// Hangs with qemu
64391.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
64401.16Skamil
64411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64431.1Skamil	if (child == 0) {
64441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64461.1Skamil
64471.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64481.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64491.1Skamil
64501.13Schristos		DPRINTF("Before exiting of the child process\n");
64511.1Skamil		_exit(exitval);
64521.1Skamil	}
64531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64541.1Skamil
64551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64571.1Skamil
64581.1Skamil	validate_status_stopped(status, sigval);
64591.1Skamil
64601.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
64611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
64621.1Skamil
64631.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
64641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
64651.1Skamil
64661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64671.1Skamil	    "without signal to be sent\n");
64681.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
64691.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
64701.1Skamil
64711.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
64721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
64731.1Skamil
64741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64751.1Skamil	    "without signal to be sent\n");
64761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64771.1Skamil
64781.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64791.1Skamil	    TWAIT_FNAME);
64801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64811.1Skamil
64821.1Skamil	validate_status_exited(status, exitval);
64831.1Skamil
64841.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64851.1Skamil	    TWAIT_FNAME);
64861.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64871.1Skamil}
64881.1Skamil
64891.1SkamilATF_TC(resume1);
64901.1SkamilATF_TC_HEAD(resume1, tc)
64911.1Skamil{
64921.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
64931.1Skamil	atf_tc_set_md_var(tc, "descr",
64941.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
64951.1Skamil	    "resumed by the debugger");
64961.1Skamil}
64971.1Skamil
64981.1SkamilATF_TC_BODY(resume1, tc)
64991.1Skamil{
65001.1Skamil	struct msg_fds fds;
65011.1Skamil	const int exitval = 5;
65021.1Skamil	const int sigval = SIGSTOP;
65031.1Skamil	pid_t child, wpid;
65041.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
65051.1Skamil#if defined(TWAIT_HAVE_STATUS)
65061.1Skamil	int status;
65071.1Skamil#endif
65081.1Skamil	ucontext_t uc;
65091.1Skamil	lwpid_t lid;
65101.1Skamil	static const size_t ssize = 16*1024;
65111.1Skamil	void *stack;
65121.1Skamil	struct ptrace_lwpinfo pl;
65131.1Skamil	struct ptrace_siginfo psi;
65141.1Skamil
65151.17Skamil	// Feature pending for refactoring
65161.17Skamil	atf_tc_expect_fail("PR kern/51995");
65171.17Skamil
65181.15Schristos	// Hangs with qemu
65191.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
65201.1Skamil
65211.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
65221.1Skamil
65231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65251.1Skamil	if (child == 0) {
65261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65281.1Skamil
65291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65311.1Skamil
65321.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
65331.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
65341.1Skamil
65351.13Schristos		DPRINTF("Before making context for new lwp in child\n");
65361.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
65371.1Skamil
65381.13Schristos		DPRINTF("Before creating new in child\n");
65391.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
65401.1Skamil
65411.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
65421.1Skamil
65431.1Skamil		raise(SIGINT);
65441.1Skamil
65451.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
65461.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
65471.1Skamil
65481.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
65491.1Skamil		    "are the same\n", lid, the_lwp_id);
65501.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
65511.1Skamil
65521.13Schristos		DPRINTF("Before exiting of the child process\n");
65531.1Skamil		_exit(exitval);
65541.1Skamil	}
65551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65561.1Skamil
65571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65591.1Skamil
65601.1Skamil	validate_status_stopped(status, sigval);
65611.1Skamil
65621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65631.1Skamil	    "without signal to be sent\n");
65641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65651.1Skamil
65661.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65671.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65691.1Skamil
65701.1Skamil	validate_status_stopped(status, SIGTRAP);
65711.1Skamil
65721.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
65731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
65741.1Skamil
65751.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
65761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
65771.1Skamil
65781.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
65791.1Skamil
65801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65811.1Skamil	    "without signal to be sent\n");
65821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65831.1Skamil
65841.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65851.1Skamil	    "SIGINT\n", TWAIT_FNAME);
65861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65871.1Skamil
65881.1Skamil	validate_status_stopped(status, SIGINT);
65891.1Skamil
65901.1Skamil	pl.pl_lwpid = 0;
65911.1Skamil
65921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
65931.1Skamil	while (pl.pl_lwpid != 0) {
65941.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
65951.1Skamil		switch (pl.pl_lwpid) {
65961.1Skamil		case 1:
65971.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
65981.1Skamil			break;
65991.1Skamil		case 2:
66001.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
66011.1Skamil			break;
66021.1Skamil		}
66031.1Skamil	}
66041.1Skamil
66051.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
66061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
66071.1Skamil
66081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66091.1Skamil	    "without signal to be sent\n");
66101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66111.1Skamil
66121.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
66131.1Skamil	    TWAIT_FNAME);
66141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66151.1Skamil
66161.1Skamil	validate_status_exited(status, exitval);
66171.1Skamil
66181.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
66191.1Skamil	    TWAIT_FNAME);
66201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66211.1Skamil
66221.1Skamil	msg_close(&fds);
66231.1Skamil
66241.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
66251.1Skamil	sleep(10);
66261.1Skamil}
66271.1Skamil
66281.1SkamilATF_TC(syscall1);
66291.1SkamilATF_TC_HEAD(syscall1, tc)
66301.1Skamil{
66311.1Skamil	atf_tc_set_md_var(tc, "descr",
66321.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
66331.1Skamil}
66341.1Skamil
66351.1SkamilATF_TC_BODY(syscall1, tc)
66361.1Skamil{
66371.1Skamil	const int exitval = 5;
66381.1Skamil	const int sigval = SIGSTOP;
66391.1Skamil	pid_t child, wpid;
66401.1Skamil#if defined(TWAIT_HAVE_STATUS)
66411.1Skamil	int status;
66421.1Skamil#endif
66431.1Skamil	struct ptrace_siginfo info;
66441.1Skamil	memset(&info, 0, sizeof(info));
66451.1Skamil
66461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66481.1Skamil	if (child == 0) {
66491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66511.1Skamil
66521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66541.1Skamil
66551.1Skamil		syscall(SYS_getpid);
66561.1Skamil
66571.13Schristos		DPRINTF("Before exiting of the child process\n");
66581.1Skamil		_exit(exitval);
66591.1Skamil	}
66601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66611.1Skamil
66621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66641.1Skamil
66651.1Skamil	validate_status_stopped(status, sigval);
66661.1Skamil
66671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66681.1Skamil	    "without signal to be sent\n");
66691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66701.1Skamil
66711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66731.1Skamil
66741.1Skamil	validate_status_stopped(status, SIGTRAP);
66751.1Skamil
66761.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
66771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
66781.1Skamil
66791.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
66801.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
66811.1Skamil
66821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66831.1Skamil	    "without signal to be sent\n");
66841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66851.1Skamil
66861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66881.1Skamil
66891.1Skamil	validate_status_stopped(status, SIGTRAP);
66901.1Skamil
66911.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
66921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
66931.1Skamil
66941.13Schristos	DPRINTF("Before checking siginfo_t\n");
66951.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
66961.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
66971.1Skamil
66981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66991.1Skamil	    "without signal to be sent\n");
67001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67011.1Skamil
67021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67041.1Skamil
67051.1Skamil	validate_status_exited(status, exitval);
67061.1Skamil
67071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67091.1Skamil}
67101.1Skamil
67111.1SkamilATF_TC(syscallemu1);
67121.1SkamilATF_TC_HEAD(syscallemu1, tc)
67131.1Skamil{
67141.1Skamil	atf_tc_set_md_var(tc, "descr",
67151.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
67161.1Skamil}
67171.1Skamil
67181.1SkamilATF_TC_BODY(syscallemu1, tc)
67191.1Skamil{
67201.1Skamil	const int exitval = 5;
67211.1Skamil	const int sigval = SIGSTOP;
67221.1Skamil	pid_t child, wpid;
67231.1Skamil#if defined(TWAIT_HAVE_STATUS)
67241.1Skamil	int status;
67251.1Skamil#endif
67261.1Skamil
67271.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
67281.6Skamil	/* syscallemu does not work on sparc (32-bit) */
67291.6Skamil	atf_tc_expect_fail("PR kern/52166");
67301.6Skamil#endif
67311.6Skamil
67321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67341.1Skamil	if (child == 0) {
67351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67371.1Skamil
67381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67401.1Skamil
67411.1Skamil		syscall(SYS_exit, 100);
67421.1Skamil
67431.13Schristos		DPRINTF("Before exiting of the child process\n");
67441.1Skamil		_exit(exitval);
67451.1Skamil	}
67461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67471.1Skamil
67481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67501.1Skamil
67511.1Skamil	validate_status_stopped(status, sigval);
67521.1Skamil
67531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67541.1Skamil	    "without signal to be sent\n");
67551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
67561.1Skamil
67571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67591.1Skamil
67601.1Skamil	validate_status_stopped(status, SIGTRAP);
67611.1Skamil
67621.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
67631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
67641.1Skamil
67651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67661.1Skamil	    "without signal to be sent\n");
67671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
67681.1Skamil
67691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67711.1Skamil
67721.1Skamil	validate_status_stopped(status, SIGTRAP);
67731.1Skamil
67741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67751.1Skamil	    "without signal to be sent\n");
67761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67771.1Skamil
67781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67801.1Skamil
67811.1Skamil	validate_status_exited(status, exitval);
67821.1Skamil
67831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67841.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67851.1Skamil}
67861.1Skamil
67871.26Skamil#if defined(TWAIT_HAVE_PID)
67881.26SkamilATF_TC(race1);
67891.26SkamilATF_TC_HEAD(race1, tc)
67901.26Skamil{
67911.26Skamil	atf_tc_set_md_var(tc, "descr",
67921.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
67931.26Skamil	    "process and no other error is reported");
67941.26Skamil}
67951.26Skamil
67961.26SkamilATF_TC_BODY(race1, tc)
67971.26Skamil{
67981.26Skamil	time_t start, end;
67991.26Skamil	double diff;
68001.26Skamil	unsigned long N = 0;
68011.26Skamil
68021.26Skamil	/* Reuse this test with attach1 */
68031.26Skamil
68041.26Skamil	start = time(NULL);
68051.26Skamil	while (true) {
68061.26Skamil		DPRINTF("Step: %lu\n", N);
68071.26Skamil		attach1_raw(true);
68081.26Skamil		end = time(NULL);
68091.26Skamil		diff = difftime(end, start);
68101.26Skamil		if (diff >= 5.0)
68111.26Skamil			break;
68121.26Skamil		++N;
68131.26Skamil	}
68141.26Skamil	DPRINTF("Iterations: %lu\n", N);
68151.26Skamil}
68161.26Skamil#endif
68171.26Skamil
68181.1Skamil#include "t_ptrace_amd64_wait.h"
68191.1Skamil#include "t_ptrace_i386_wait.h"
68201.1Skamil#include "t_ptrace_x86_wait.h"
68211.1Skamil
68221.1SkamilATF_TP_ADD_TCS(tp)
68231.1Skamil{
68241.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
68251.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
68261.33Skamil
68271.36Skamil	ATF_TP_ADD_TC(tp, traceme_raise1);
68281.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
68291.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
68301.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
68311.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
68321.33Skamil
68331.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
68341.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
68351.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
68361.34Skamil
68371.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler1);
68381.35Skamil//	ATF_TP_ADD_TC(tp, traceme_signal_nohandler2); // not yet
68391.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler3);
68401.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler4);
68411.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);
68421.1Skamil
68431.37Skamil	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
68441.37Skamil
68451.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
68461.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
68471.1Skamil	ATF_TP_ADD_TC(tp, attach3);
68481.1Skamil	ATF_TP_ADD_TC(tp, attach4);
68491.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
68501.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
68511.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
68521.1Skamil
68531.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
68541.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
68551.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
68561.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
68571.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
68581.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
68591.1Skamil
68601.31Skamil	ATF_TP_ADD_TC(tp, fork1);
68611.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
68621.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
68631.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
68641.31Skamil	ATF_TP_ADD_TC(tp, fork5);
68651.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
68661.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
68671.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
68681.31Skamil
68691.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
68701.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
68711.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
68721.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
68731.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
68741.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
68751.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
68761.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
68771.1Skamil
68781.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
68791.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
68801.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
68811.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
68821.1Skamil
68831.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
68841.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
68851.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
68861.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
68871.1Skamil
68881.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
68891.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
68901.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
68911.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
68921.1Skamil
68931.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
68941.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
68951.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
68961.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
68971.1Skamil
68981.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
68991.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
69001.1Skamil
69011.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
69021.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
69031.1Skamil
69041.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
69051.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
69061.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
69071.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
69081.1Skamil
69091.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
69101.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
69111.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
69121.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
69131.1Skamil
69141.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
69151.1Skamil
69161.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
69171.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
69181.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
69191.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
69201.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
69211.1Skamil
69221.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
69231.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
69241.1Skamil
69251.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
69261.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
69271.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
69281.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
69291.1Skamil
69301.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
69311.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
69321.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
69331.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
69341.2Skamil
69351.1Skamil	ATF_TP_ADD_TC(tp, kill1);
69361.1Skamil	ATF_TP_ADD_TC(tp, kill2);
69371.1Skamil
69381.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
69391.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
69401.1Skamil
69411.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
69421.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
69431.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
69441.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
69451.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
69461.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
69471.1Skamil
69481.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
69491.1Skamil
69501.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
69511.1Skamil
69521.1Skamil	ATF_TP_ADD_TC(tp, signal1);
69531.1Skamil	ATF_TP_ADD_TC(tp, signal2);
69541.1Skamil	ATF_TP_ADD_TC(tp, signal3);
69551.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
69561.1Skamil	ATF_TP_ADD_TC(tp, signal5);
69571.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
69581.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
69591.1Skamil	ATF_TP_ADD_TC(tp, signal8);
69601.1Skamil	ATF_TP_ADD_TC(tp, signal9);
69611.1Skamil	ATF_TP_ADD_TC(tp, signal10);
69621.1Skamil
69631.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
69641.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
69651.1Skamil
69661.1Skamil	ATF_TP_ADD_TC(tp, resume1);
69671.1Skamil
69681.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
69691.1Skamil
69701.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
69711.1Skamil
69721.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
69731.26Skamil
69741.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
69751.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
69761.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
69771.1Skamil
69781.1Skamil	return atf_no_error();
69791.1Skamil}
6980