t_ptrace_wait.c revision 1.35
11.35Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.35 2018/04/28 18:07:15 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.35Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.35 2018/04/28 18:07:15 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.13Schristos		DPRINTF("Before exiting of the child process\n");
1051.1Skamil		_exit(exitval);
1061.1Skamil	}
1071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1081.1Skamil
1091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1111.1Skamil
1121.1Skamil	validate_status_stopped(status, sigval);
1131.1Skamil
1141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
1151.1Skamil	    "without signal to be sent\n");
1161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1171.1Skamil
1181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1201.1Skamil
1211.1Skamil	validate_status_exited(status, exitval);
1221.1Skamil
1231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1251.1Skamil}
1261.1Skamil
1271.33Skamil#define TRACEME_RAISE(test, sig)						\
1281.33SkamilATF_TC(test);									\
1291.33SkamilATF_TC_HEAD(test, tc)								\
1301.33Skamil{										\
1311.33Skamil	atf_tc_set_md_var(tc, "descr",						\
1321.33Skamil	    "Verify " #sig " followed by _exit(2) in a child");			\
1331.33Skamil}										\
1341.33Skamil										\
1351.33SkamilATF_TC_BODY(test, tc)								\
1361.33Skamil{										\
1371.33Skamil										\
1381.33Skamil	traceme_raise(sig);							\
1391.33Skamil}
1401.33Skamil
1411.33Skamil//TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ // not yet
1421.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
1431.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
1441.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
1451.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
1461.33Skamil
1471.34Skamil/// ----------------------------------------------------------------------------
1481.1Skamil
1491.1Skamilstatic void
1501.34Skamiltraceme_sighandler_catch(int sigsent, void (*sah)(int arg), int *traceme_caught)
1511.1Skamil{
1521.1Skamil	const int exitval = 5;
1531.34Skamil	const int sigval = SIGSTOP;
1541.1Skamil	pid_t child, wpid;
1551.1Skamil	struct sigaction sa;
1561.1Skamil#if defined(TWAIT_HAVE_STATUS)
1571.1Skamil	int status;
1581.1Skamil#endif
1591.1Skamil
1601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1621.1Skamil	if (child == 0) {
1631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1651.1Skamil
1661.34Skamil		sa.sa_handler = sah;
1671.1Skamil		sa.sa_flags = SA_SIGINFO;
1681.1Skamil		sigemptyset(&sa.sa_mask);
1691.1Skamil
1701.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1711.1Skamil
1721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1741.1Skamil
1751.34Skamil		FORKEE_ASSERT_EQ(*traceme_caught, 1);
1761.1Skamil
1771.13Schristos		DPRINTF("Before exiting of the child process\n");
1781.1Skamil		_exit(exitval);
1791.1Skamil	}
1801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1811.1Skamil
1821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1841.1Skamil
1851.1Skamil	validate_status_stopped(status, sigval);
1861.1Skamil
1871.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
1881.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
1891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1901.1Skamil
1911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1931.1Skamil
1941.1Skamil	validate_status_exited(status, exitval);
1951.1Skamil
1961.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1981.1Skamil}
1991.1Skamil
2001.34Skamil#define TRACEME_SIGHANDLER_CATCH(test, sig)					\
2011.34SkamilATF_TC(test);									\
2021.34SkamilATF_TC_HEAD(test, tc)								\
2031.34Skamil{										\
2041.34Skamil	atf_tc_set_md_var(tc, "descr",						\
2051.34Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
2061.34Skamil	    "handled correctly and caught by a signal handler");		\
2071.34Skamil}										\
2081.34Skamil										\
2091.34Skamilstatic int test##_caught = 0;							\
2101.34Skamil										\
2111.34Skamilstatic void									\
2121.34Skamiltest##_sighandler(int arg)							\
2131.34Skamil{										\
2141.34Skamil	FORKEE_ASSERT_EQ(arg, sig);						\
2151.34Skamil										\
2161.34Skamil	++ test##_caught;							\
2171.34Skamil}										\
2181.34Skamil										\
2191.34SkamilATF_TC_BODY(test, tc)								\
2201.34Skamil{										\
2211.34Skamil										\
2221.34Skamil	traceme_sighandler_catch(sig, test##_sighandler, & test##_caught);	\
2231.34Skamil}
2241.34Skamil
2251.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered.
2261.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch1, SIGABRT) /* abort trap */
2271.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch2, SIGHUP)  /* hangup */
2281.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch3, SIGCONT) /* continued? */
2291.34Skamil
2301.34Skamil/// ----------------------------------------------------------------------------
2311.34Skamil
2321.35Skamilstatic void
2331.35Skamiltraceme_signal_nohandler(int sigsent)
2341.1Skamil{
2351.35Skamil	const int sigval = SIGSTOP;
2361.35Skamil	int exitval = 0;
2371.1Skamil	pid_t child, wpid;
2381.1Skamil#if defined(TWAIT_HAVE_STATUS)
2391.1Skamil	int status;
2401.35Skamil	int expect_core = (sigsent == SIGABRT) ? 1 : 0;
2411.1Skamil#endif
2421.1Skamil
2431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2451.1Skamil	if (child == 0) {
2461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2481.1Skamil
2491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2511.1Skamil
2521.35Skamil		switch (sigsent) {
2531.35Skamil		case SIGCONT:
2541.35Skamil			_exit(exitval);
2551.35Skamil		default:
2561.35Skamil			/* NOTREACHED */
2571.35Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
2581.35Skamil		}
2591.1Skamil	}
2601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2611.1Skamil
2621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2641.1Skamil
2651.1Skamil	validate_status_stopped(status, sigval);
2661.1Skamil
2671.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2681.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2701.1Skamil
2711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2731.1Skamil
2741.35Skamil	switch (sigsent) {
2751.35Skamil	case SIGCONT:
2761.35Skamil		validate_status_exited(status, exitval);
2771.35Skamil		break;
2781.35Skamil	default:
2791.35Skamil		validate_status_signaled(status, sigsent, expect_core);
2801.35Skamil		break;
2811.35Skamil	}
2821.1Skamil
2831.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2841.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2851.1Skamil}
2861.1Skamil
2871.35Skamil#define TRACEME_SIGNAL_NOHANDLER(test, sig)					\
2881.35SkamilATF_TC(test);									\
2891.35SkamilATF_TC_HEAD(test, tc)								\
2901.35Skamil{										\
2911.35Skamil	atf_tc_set_md_var(tc, "descr",						\
2921.35Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
2931.35Skamil	    "handled correctly in a child without a signal handler");		\
2941.35Skamil}										\
2951.35Skamil										\
2961.35SkamilATF_TC_BODY(test, tc)								\
2971.35Skamil{										\
2981.35Skamil										\
2991.35Skamil	traceme_signal_nohandler(sig);						\
3001.35Skamil}
3011.35Skamil
3021.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */
3031.35Skamil//TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */
3041.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */
3051.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP)  /* hangup */
3061.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */
3071.35Skamil
3081.35Skamil/// ----------------------------------------------------------------------------
3091.35Skamil
3101.1Skamil#if defined(TWAIT_HAVE_PID)
3111.1SkamilATF_TC(attach1);
3121.1SkamilATF_TC_HEAD(attach1, tc)
3131.1Skamil{
3141.1Skamil	atf_tc_set_md_var(tc, "descr",
3151.1Skamil	    "Assert that tracer sees process termination before the parent");
3161.1Skamil}
3171.1Skamil
3181.26Skamilstatic void
3191.26Skamilattach1_raw(bool raw)
3201.1Skamil{
3211.1Skamil	struct msg_fds parent_tracee, parent_tracer;
3221.1Skamil	const int exitval_tracee = 5;
3231.1Skamil	const int exitval_tracer = 10;
3241.1Skamil	pid_t tracee, tracer, wpid;
3251.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3261.1Skamil#if defined(TWAIT_HAVE_STATUS)
3271.1Skamil	int status;
3281.1Skamil#endif
3291.1Skamil
3301.13Schristos	DPRINTF("Spawn tracee\n");
3311.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3321.1Skamil	tracee = atf_utils_fork();
3331.1Skamil	if (tracee == 0) {
3341.1Skamil		// Wait for parent to let us exit
3351.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3361.1Skamil		_exit(exitval_tracee);
3371.1Skamil	}
3381.1Skamil
3391.13Schristos	DPRINTF("Spawn debugger\n");
3401.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3411.1Skamil	tracer = atf_utils_fork();
3421.1Skamil	if (tracer == 0) {
3431.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3441.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3451.1Skamil
3461.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3471.1Skamil		FORKEE_REQUIRE_SUCCESS(
3481.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3491.1Skamil
3501.1Skamil		forkee_status_stopped(status, SIGSTOP);
3511.1Skamil
3521.1Skamil		/* Resume tracee with PT_CONTINUE */
3531.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3541.1Skamil
3551.1Skamil		/* Inform parent that tracer has attached to tracee */
3561.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3571.1Skamil
3581.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3591.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3601.1Skamil
3611.1Skamil		/* Wait for tracee and assert that it exited */
3621.1Skamil		FORKEE_REQUIRE_SUCCESS(
3631.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3641.1Skamil
3651.1Skamil		forkee_status_exited(status, exitval_tracee);
3661.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3671.1Skamil
3681.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3691.1Skamil		_exit(exitval_tracer);
3701.1Skamil	}
3711.1Skamil
3721.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3731.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3741.1Skamil
3751.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3761.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3771.1Skamil
3781.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3791.26Skamil	if (raw)
3801.26Skamil		await_zombie_raw(tracee, 0);
3811.26Skamil	else
3821.26Skamil		await_zombie(tracee);
3831.1Skamil
3841.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3851.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3861.1Skamil	    TWAIT_FNAME);
3871.1Skamil	TWAIT_REQUIRE_SUCCESS(
3881.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
3891.1Skamil
3901.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
3911.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
3921.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3931.1Skamil	    TWAIT_FNAME);
3941.1Skamil
3951.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
3961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3971.1Skamil	    tracer);
3981.1Skamil
3991.1Skamil	validate_status_exited(status, exitval_tracer);
4001.1Skamil
4011.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4021.1Skamil	    TWAIT_FNAME);
4031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4041.1Skamil	    tracee);
4051.1Skamil
4061.1Skamil	validate_status_exited(status, exitval_tracee);
4071.1Skamil
4081.1Skamil	msg_close(&parent_tracer);
4091.1Skamil	msg_close(&parent_tracee);
4101.1Skamil}
4111.26Skamil
4121.26SkamilATF_TC_BODY(attach1, tc)
4131.26Skamil{
4141.26Skamil
4151.26Skamil	/* Reuse this test with race1 */
4161.26Skamil	attach1_raw(false);
4171.26Skamil}
4181.26Skamil
4191.1Skamil#endif
4201.1Skamil
4211.1Skamil#if defined(TWAIT_HAVE_PID)
4221.1SkamilATF_TC(attach2);
4231.1SkamilATF_TC_HEAD(attach2, tc)
4241.1Skamil{
4251.1Skamil	atf_tc_set_md_var(tc, "descr",
4261.1Skamil	    "Assert that any tracer sees process termination before its "
4271.1Skamil	    "parent");
4281.1Skamil}
4291.1Skamil
4301.1SkamilATF_TC_BODY(attach2, tc)
4311.1Skamil{
4321.1Skamil	struct msg_fds parent_tracer, parent_tracee;
4331.1Skamil	const int exitval_tracee = 5;
4341.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
4351.1Skamil	pid_t tracee, tracer, wpid;
4361.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4371.1Skamil#if defined(TWAIT_HAVE_STATUS)
4381.1Skamil	int status;
4391.1Skamil#endif
4401.1Skamil
4411.13Schristos	DPRINTF("Spawn tracee\n");
4421.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4431.1Skamil	tracee = atf_utils_fork();
4441.1Skamil	if (tracee == 0) {
4451.1Skamil		/* Wait for message from the parent */
4461.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4471.1Skamil		_exit(exitval_tracee);
4481.1Skamil	}
4491.1Skamil
4501.13Schristos	DPRINTF("Spawn debugger\n");
4511.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4521.1Skamil	tracer = atf_utils_fork();
4531.1Skamil	if (tracer == 0) {
4541.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4551.1Skamil		tracer = atf_utils_fork();
4561.1Skamil		if (tracer != 0)
4571.1Skamil			_exit(exitval_tracer1);
4581.1Skamil
4591.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4601.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4611.1Skamil
4621.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4631.1Skamil		FORKEE_REQUIRE_SUCCESS(
4641.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4651.1Skamil
4661.1Skamil		forkee_status_stopped(status, SIGSTOP);
4671.1Skamil
4681.1Skamil		/* Resume tracee with PT_CONTINUE */
4691.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4701.1Skamil
4711.1Skamil		/* Inform parent that tracer has attached to tracee */
4721.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4731.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4741.1Skamil
4751.1Skamil		/* Wait for tracee and assert that it exited */
4761.1Skamil		FORKEE_REQUIRE_SUCCESS(
4771.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4781.1Skamil
4791.1Skamil		forkee_status_exited(status, exitval_tracee);
4801.1Skamil
4811.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4821.1Skamil		_exit(exitval_tracer2);
4831.1Skamil	}
4841.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4851.1Skamil	    "%s()\n", TWAIT_FNAME);
4861.1Skamil	TWAIT_REQUIRE_SUCCESS(
4871.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4881.1Skamil
4891.1Skamil	validate_status_exited(status, exitval_tracer1);
4901.1Skamil
4911.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4921.1Skamil	    TWAIT_FNAME);
4931.1Skamil	TWAIT_REQUIRE_SUCCESS(
4941.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4951.1Skamil
4961.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4971.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
4981.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4991.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5001.1Skamil
5011.13Schristos	DPRINTF("Detect that tracee is zombie\n");
5021.1Skamil	await_zombie(tracee);
5031.1Skamil
5041.13Schristos	DPRINTF("Assert that there is no status about tracee - "
5051.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
5061.1Skamil	TWAIT_REQUIRE_SUCCESS(
5071.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
5081.1Skamil
5091.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
5101.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
5111.1Skamil
5121.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5131.1Skamil	    TWAIT_FNAME);
5141.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
5151.1Skamil	    tracee);
5161.1Skamil
5171.1Skamil	validate_status_exited(status, exitval_tracee);
5181.1Skamil
5191.1Skamil	msg_close(&parent_tracer);
5201.1Skamil	msg_close(&parent_tracee);
5211.1Skamil}
5221.1Skamil#endif
5231.1Skamil
5241.1SkamilATF_TC(attach3);
5251.1SkamilATF_TC_HEAD(attach3, tc)
5261.1Skamil{
5271.1Skamil	atf_tc_set_md_var(tc, "descr",
5281.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
5291.1Skamil}
5301.1Skamil
5311.1SkamilATF_TC_BODY(attach3, tc)
5321.1Skamil{
5331.1Skamil	struct msg_fds parent_tracee;
5341.1Skamil	const int exitval_tracee = 5;
5351.1Skamil	pid_t tracee, wpid;
5361.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5371.1Skamil#if defined(TWAIT_HAVE_STATUS)
5381.1Skamil	int status;
5391.1Skamil#endif
5401.1Skamil
5411.13Schristos	DPRINTF("Spawn tracee\n");
5421.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5431.1Skamil	tracee = atf_utils_fork();
5441.1Skamil	if (tracee == 0) {
5451.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5461.13Schristos		DPRINTF("Parent should now attach to tracee\n");
5471.1Skamil
5481.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5491.1Skamil		/* Wait for message from the parent */
5501.1Skamil		_exit(exitval_tracee);
5511.1Skamil	}
5521.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5531.1Skamil
5541.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5561.1Skamil
5571.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5581.1Skamil	    TWAIT_FNAME);
5591.1Skamil	TWAIT_REQUIRE_SUCCESS(
5601.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5611.1Skamil
5621.1Skamil	validate_status_stopped(status, SIGSTOP);
5631.1Skamil
5641.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5661.1Skamil
5671.13Schristos	DPRINTF("Let the tracee exit now\n");
5681.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5691.1Skamil
5701.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5711.1Skamil	TWAIT_REQUIRE_SUCCESS(
5721.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5731.1Skamil
5741.1Skamil	validate_status_exited(status, exitval_tracee);
5751.1Skamil
5761.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5781.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5791.1Skamil
5801.1Skamil	msg_close(&parent_tracee);
5811.1Skamil}
5821.1Skamil
5831.1SkamilATF_TC(attach4);
5841.1SkamilATF_TC_HEAD(attach4, tc)
5851.1Skamil{
5861.1Skamil	atf_tc_set_md_var(tc, "descr",
5871.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
5881.1Skamil}
5891.1Skamil
5901.1SkamilATF_TC_BODY(attach4, tc)
5911.1Skamil{
5921.1Skamil	struct msg_fds parent_tracee;
5931.1Skamil	const int exitval_tracer = 5;
5941.1Skamil	pid_t tracer, wpid;
5951.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5961.1Skamil#if defined(TWAIT_HAVE_STATUS)
5971.1Skamil	int status;
5981.1Skamil#endif
5991.1Skamil
6001.13Schristos	DPRINTF("Spawn tracer\n");
6011.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6021.1Skamil	tracer = atf_utils_fork();
6031.1Skamil	if (tracer == 0) {
6041.1Skamil
6051.1Skamil		/* Wait for message from the parent */
6061.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
6071.1Skamil
6081.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
6091.1Skamil		    getppid());
6101.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
6111.1Skamil
6121.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
6131.1Skamil		    TWAIT_FNAME);
6141.1Skamil		FORKEE_REQUIRE_SUCCESS(
6151.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
6161.1Skamil
6171.1Skamil		forkee_status_stopped(status, SIGSTOP);
6181.1Skamil
6191.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
6201.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
6211.1Skamil		    != -1);
6221.1Skamil
6231.1Skamil		/* Tell parent we are ready */
6241.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
6251.1Skamil
6261.1Skamil		_exit(exitval_tracer);
6271.1Skamil	}
6281.1Skamil
6291.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
6301.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6311.13Schristos	DPRINTF("Allow the tracer to exit now\n");
6321.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
6331.1Skamil
6341.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
6351.1Skamil	TWAIT_REQUIRE_SUCCESS(
6361.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6371.1Skamil
6381.1Skamil	validate_status_exited(status, exitval_tracer);
6391.1Skamil
6401.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
6411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6421.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
6431.1Skamil
6441.1Skamil	msg_close(&parent_tracee);
6451.1Skamil}
6461.1Skamil
6471.1Skamil#if defined(TWAIT_HAVE_PID)
6481.1SkamilATF_TC(attach5);
6491.1SkamilATF_TC_HEAD(attach5, tc)
6501.1Skamil{
6511.1Skamil	atf_tc_set_md_var(tc, "descr",
6521.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6531.1Skamil	    "(check getppid(2))");
6541.1Skamil}
6551.1Skamil
6561.1SkamilATF_TC_BODY(attach5, tc)
6571.1Skamil{
6581.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6591.1Skamil	const int exitval_tracee = 5;
6601.1Skamil	const int exitval_tracer = 10;
6611.1Skamil	pid_t parent, tracee, tracer, wpid;
6621.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6631.1Skamil#if defined(TWAIT_HAVE_STATUS)
6641.1Skamil	int status;
6651.1Skamil#endif
6661.1Skamil
6671.13Schristos	DPRINTF("Spawn tracee\n");
6681.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6691.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6701.1Skamil	tracee = atf_utils_fork();
6711.1Skamil	if (tracee == 0) {
6721.1Skamil		parent = getppid();
6731.1Skamil
6741.1Skamil		/* Emit message to the parent */
6751.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6761.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6771.1Skamil
6781.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6791.1Skamil
6801.1Skamil		_exit(exitval_tracee);
6811.1Skamil	}
6821.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6831.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6841.1Skamil
6851.13Schristos	DPRINTF("Spawn debugger\n");
6861.1Skamil	tracer = atf_utils_fork();
6871.1Skamil	if (tracer == 0) {
6881.1Skamil		/* No IPC to communicate with the child */
6891.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6901.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6911.1Skamil
6921.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6931.1Skamil		FORKEE_REQUIRE_SUCCESS(
6941.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6951.1Skamil
6961.1Skamil		forkee_status_stopped(status, SIGSTOP);
6971.1Skamil
6981.1Skamil		/* Resume tracee with PT_CONTINUE */
6991.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7001.1Skamil
7011.1Skamil		/* Inform parent that tracer has attached to tracee */
7021.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
7031.1Skamil
7041.1Skamil		/* Wait for parent to tell use that tracee should have exited */
7051.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
7061.1Skamil
7071.1Skamil		/* Wait for tracee and assert that it exited */
7081.1Skamil		FORKEE_REQUIRE_SUCCESS(
7091.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7101.1Skamil
7111.1Skamil		forkee_status_exited(status, exitval_tracee);
7121.1Skamil
7131.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7141.1Skamil		_exit(exitval_tracer);
7151.1Skamil	}
7161.1Skamil
7171.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7181.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
7191.1Skamil
7201.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7211.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
7221.1Skamil
7231.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7241.1Skamil	await_zombie(tracee);
7251.1Skamil
7261.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7271.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7281.1Skamil	TWAIT_REQUIRE_SUCCESS(
7291.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7301.1Skamil
7311.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7321.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
7331.1Skamil
7341.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7361.1Skamil	    tracer);
7371.1Skamil
7381.1Skamil	validate_status_exited(status, exitval_tracer);
7391.1Skamil
7401.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7411.1Skamil	    TWAIT_FNAME);
7421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7431.1Skamil	    tracee);
7441.1Skamil
7451.1Skamil	validate_status_exited(status, exitval_tracee);
7461.1Skamil
7471.1Skamil	msg_close(&parent_tracer);
7481.1Skamil	msg_close(&parent_tracee);
7491.1Skamil}
7501.1Skamil#endif
7511.1Skamil
7521.1Skamil#if defined(TWAIT_HAVE_PID)
7531.1SkamilATF_TC(attach6);
7541.1SkamilATF_TC_HEAD(attach6, tc)
7551.1Skamil{
7561.1Skamil	atf_tc_set_md_var(tc, "descr",
7571.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7581.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7591.1Skamil}
7601.1Skamil
7611.1SkamilATF_TC_BODY(attach6, tc)
7621.1Skamil{
7631.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7641.1Skamil	const int exitval_tracee = 5;
7651.1Skamil	const int exitval_tracer = 10;
7661.1Skamil	pid_t parent, tracee, tracer, wpid;
7671.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7681.1Skamil#if defined(TWAIT_HAVE_STATUS)
7691.1Skamil	int status;
7701.1Skamil#endif
7711.1Skamil	int name[CTL_MAXNAME];
7721.1Skamil	struct kinfo_proc2 kp;
7731.1Skamil	size_t len = sizeof(kp);
7741.1Skamil	unsigned int namelen;
7751.1Skamil
7761.13Schristos	DPRINTF("Spawn tracee\n");
7771.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7781.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7791.1Skamil	tracee = atf_utils_fork();
7801.1Skamil	if (tracee == 0) {
7811.1Skamil		parent = getppid();
7821.1Skamil
7831.1Skamil		/* Emit message to the parent */
7841.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7851.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7861.1Skamil
7871.1Skamil		namelen = 0;
7881.1Skamil		name[namelen++] = CTL_KERN;
7891.1Skamil		name[namelen++] = KERN_PROC2;
7901.1Skamil		name[namelen++] = KERN_PROC_PID;
7911.1Skamil		name[namelen++] = getpid();
7921.1Skamil		name[namelen++] = len;
7931.1Skamil		name[namelen++] = 1;
7941.1Skamil
7951.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
7961.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
7971.1Skamil
7981.1Skamil		_exit(exitval_tracee);
7991.1Skamil	}
8001.1Skamil
8011.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
8021.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
8031.1Skamil
8041.13Schristos	DPRINTF("Spawn debugger\n");
8051.1Skamil	tracer = atf_utils_fork();
8061.1Skamil	if (tracer == 0) {
8071.1Skamil		/* No IPC to communicate with the child */
8081.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8091.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8101.1Skamil
8111.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8121.1Skamil		FORKEE_REQUIRE_SUCCESS(
8131.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8141.1Skamil
8151.1Skamil		forkee_status_stopped(status, SIGSTOP);
8161.1Skamil
8171.1Skamil		/* Resume tracee with PT_CONTINUE */
8181.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8191.1Skamil
8201.1Skamil		/* Inform parent that tracer has attached to tracee */
8211.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8221.1Skamil
8231.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8241.1Skamil
8251.1Skamil		/* Wait for tracee and assert that it exited */
8261.1Skamil		FORKEE_REQUIRE_SUCCESS(
8271.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8281.1Skamil
8291.1Skamil		forkee_status_exited(status, exitval_tracee);
8301.1Skamil
8311.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8321.1Skamil		_exit(exitval_tracer);
8331.1Skamil	}
8341.1Skamil
8351.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8361.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8371.1Skamil
8381.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8391.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8401.1Skamil
8411.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8421.1Skamil	await_zombie(tracee);
8431.1Skamil
8441.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8451.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8461.1Skamil	TWAIT_REQUIRE_SUCCESS(
8471.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8481.1Skamil
8491.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8501.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8511.1Skamil
8521.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8531.1Skamil	    TWAIT_FNAME);
8541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8551.1Skamil	    tracer);
8561.1Skamil
8571.1Skamil	validate_status_exited(status, exitval_tracer);
8581.1Skamil
8591.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8601.1Skamil	    TWAIT_FNAME);
8611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8621.1Skamil	    tracee);
8631.1Skamil
8641.1Skamil	validate_status_exited(status, exitval_tracee);
8651.1Skamil
8661.1Skamil	msg_close(&parent_tracee);
8671.1Skamil	msg_close(&parent_tracer);
8681.1Skamil}
8691.1Skamil#endif
8701.1Skamil
8711.1Skamil#if defined(TWAIT_HAVE_PID)
8721.1SkamilATF_TC(attach7);
8731.1SkamilATF_TC_HEAD(attach7, tc)
8741.1Skamil{
8751.1Skamil	atf_tc_set_md_var(tc, "descr",
8761.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8771.1Skamil	    "(check /proc/curproc/status 3rd column)");
8781.1Skamil}
8791.1Skamil
8801.1SkamilATF_TC_BODY(attach7, tc)
8811.1Skamil{
8821.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8831.1Skamil	int rv;
8841.1Skamil	const int exitval_tracee = 5;
8851.1Skamil	const int exitval_tracer = 10;
8861.1Skamil	pid_t parent, tracee, tracer, wpid;
8871.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8881.1Skamil#if defined(TWAIT_HAVE_STATUS)
8891.1Skamil	int status;
8901.1Skamil#endif
8911.1Skamil	FILE *fp;
8921.1Skamil	struct stat st;
8931.1Skamil	const char *fname = "/proc/curproc/status";
8941.1Skamil	char s_executable[MAXPATHLEN];
8951.1Skamil	int s_pid, s_ppid;
8961.1Skamil	/*
8971.1Skamil	 * Format:
8981.1Skamil	 *  EXECUTABLE PID PPID ...
8991.1Skamil	 */
9001.1Skamil
9011.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
9021.1Skamil	if (rv != 0) {
9031.1Skamil		atf_tc_skip("/proc/curproc/status not found");
9041.1Skamil	}
9051.1Skamil
9061.13Schristos	DPRINTF("Spawn tracee\n");
9071.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9081.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
9091.1Skamil	tracee = atf_utils_fork();
9101.1Skamil	if (tracee == 0) {
9111.1Skamil		parent = getppid();
9121.1Skamil
9131.1Skamil		// Wait for parent to let us exit
9141.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
9151.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
9161.1Skamil
9171.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
9181.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
9191.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
9201.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
9211.1Skamil
9221.1Skamil		_exit(exitval_tracee);
9231.1Skamil	}
9241.1Skamil
9251.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9261.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
9271.1Skamil
9281.13Schristos	DPRINTF("Spawn debugger\n");
9291.1Skamil	tracer = atf_utils_fork();
9301.1Skamil	if (tracer == 0) {
9311.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9321.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9331.1Skamil
9341.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9351.1Skamil		FORKEE_REQUIRE_SUCCESS(
9361.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9371.1Skamil
9381.1Skamil		forkee_status_stopped(status, SIGSTOP);
9391.1Skamil
9401.1Skamil		/* Resume tracee with PT_CONTINUE */
9411.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9421.1Skamil
9431.1Skamil		/* Inform parent that tracer has attached to tracee */
9441.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9451.1Skamil
9461.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9471.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9481.1Skamil
9491.1Skamil		/* Wait for tracee and assert that it exited */
9501.1Skamil		FORKEE_REQUIRE_SUCCESS(
9511.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9521.1Skamil
9531.1Skamil		forkee_status_exited(status, exitval_tracee);
9541.1Skamil
9551.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9561.1Skamil		_exit(exitval_tracer);
9571.1Skamil	}
9581.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9591.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9601.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9611.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9621.1Skamil
9631.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9641.1Skamil	await_zombie(tracee);
9651.1Skamil
9661.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9671.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9681.1Skamil	TWAIT_REQUIRE_SUCCESS(
9691.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9701.1Skamil
9711.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9721.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9731.1Skamil
9741.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9751.1Skamil	    TWAIT_FNAME);
9761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9771.1Skamil	    tracer);
9781.1Skamil
9791.1Skamil	validate_status_exited(status, exitval_tracer);
9801.1Skamil
9811.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9821.1Skamil	    TWAIT_FNAME);
9831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9841.1Skamil	    tracee);
9851.1Skamil
9861.1Skamil	validate_status_exited(status, exitval_tracee);
9871.1Skamil
9881.1Skamil	msg_close(&parent_tracee);
9891.1Skamil	msg_close(&parent_tracer);
9901.1Skamil}
9911.1Skamil#endif
9921.1Skamil
9931.1SkamilATF_TC(eventmask1);
9941.1SkamilATF_TC_HEAD(eventmask1, tc)
9951.1Skamil{
9961.1Skamil	atf_tc_set_md_var(tc, "descr",
9971.1Skamil	    "Verify that empty EVENT_MASK is preserved");
9981.1Skamil}
9991.1Skamil
10001.1SkamilATF_TC_BODY(eventmask1, tc)
10011.1Skamil{
10021.1Skamil	const int exitval = 5;
10031.1Skamil	const int sigval = SIGSTOP;
10041.1Skamil	pid_t child, wpid;
10051.1Skamil#if defined(TWAIT_HAVE_STATUS)
10061.1Skamil	int status;
10071.1Skamil#endif
10081.1Skamil	ptrace_event_t set_event, get_event;
10091.1Skamil	const int len = sizeof(ptrace_event_t);
10101.1Skamil
10111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10131.1Skamil	if (child == 0) {
10141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10161.1Skamil
10171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10191.1Skamil
10201.13Schristos		DPRINTF("Before exiting of the child process\n");
10211.1Skamil		_exit(exitval);
10221.1Skamil	}
10231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10241.1Skamil
10251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10271.1Skamil
10281.1Skamil	validate_status_stopped(status, sigval);
10291.1Skamil
10301.1Skamil	set_event.pe_set_event = 0;
10311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10331.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10341.1Skamil
10351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10361.1Skamil	    "without signal to be sent\n");
10371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10381.1Skamil
10391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10411.1Skamil
10421.1Skamil	validate_status_exited(status, exitval);
10431.1Skamil
10441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10461.1Skamil}
10471.1Skamil
10481.1SkamilATF_TC(eventmask2);
10491.1SkamilATF_TC_HEAD(eventmask2, tc)
10501.1Skamil{
10511.1Skamil	atf_tc_set_md_var(tc, "descr",
10521.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10531.1Skamil}
10541.1Skamil
10551.1SkamilATF_TC_BODY(eventmask2, tc)
10561.1Skamil{
10571.1Skamil	const int exitval = 5;
10581.1Skamil	const int sigval = SIGSTOP;
10591.1Skamil	pid_t child, wpid;
10601.1Skamil#if defined(TWAIT_HAVE_STATUS)
10611.1Skamil	int status;
10621.1Skamil#endif
10631.1Skamil	ptrace_event_t set_event, get_event;
10641.1Skamil	const int len = sizeof(ptrace_event_t);
10651.1Skamil
10661.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10671.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10681.1Skamil	if (child == 0) {
10691.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10701.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10711.1Skamil
10721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10741.1Skamil
10751.13Schristos		DPRINTF("Before exiting of the child process\n");
10761.1Skamil		_exit(exitval);
10771.1Skamil	}
10781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10791.1Skamil
10801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10821.1Skamil
10831.1Skamil	validate_status_stopped(status, sigval);
10841.1Skamil
10851.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10881.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10891.1Skamil
10901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10911.1Skamil	    "without signal to be sent\n");
10921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10931.1Skamil
10941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10961.1Skamil
10971.1Skamil	validate_status_exited(status, exitval);
10981.1Skamil
10991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11011.1Skamil}
11021.1Skamil
11031.1SkamilATF_TC(eventmask3);
11041.1SkamilATF_TC_HEAD(eventmask3, tc)
11051.1Skamil{
11061.1Skamil	atf_tc_set_md_var(tc, "descr",
11071.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
11081.1Skamil}
11091.1Skamil
11101.1SkamilATF_TC_BODY(eventmask3, tc)
11111.1Skamil{
11121.1Skamil	const int exitval = 5;
11131.1Skamil	const int sigval = SIGSTOP;
11141.1Skamil	pid_t child, wpid;
11151.1Skamil#if defined(TWAIT_HAVE_STATUS)
11161.1Skamil	int status;
11171.1Skamil#endif
11181.1Skamil	ptrace_event_t set_event, get_event;
11191.1Skamil	const int len = sizeof(ptrace_event_t);
11201.1Skamil
11211.14Schristos	atf_tc_expect_fail("PR kern/51630");
11221.14Schristos
11231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11251.1Skamil	if (child == 0) {
11261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11281.1Skamil
11291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11311.1Skamil
11321.13Schristos		DPRINTF("Before exiting of the child process\n");
11331.1Skamil		_exit(exitval);
11341.1Skamil	}
11351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11361.1Skamil
11371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11391.1Skamil
11401.1Skamil	validate_status_stopped(status, sigval);
11411.1Skamil
11421.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
11431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
11441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11451.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11461.1Skamil
11471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11481.1Skamil	    "without signal to be sent\n");
11491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
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_exited(status, exitval);
11551.1Skamil
11561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11581.1Skamil}
11591.1Skamil
11601.1SkamilATF_TC(eventmask4);
11611.1SkamilATF_TC_HEAD(eventmask4, tc)
11621.1Skamil{
11631.1Skamil	atf_tc_set_md_var(tc, "descr",
11641.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11651.1Skamil}
11661.1Skamil
11671.1SkamilATF_TC_BODY(eventmask4, tc)
11681.1Skamil{
11691.1Skamil	const int exitval = 5;
11701.1Skamil	const int sigval = SIGSTOP;
11711.1Skamil	pid_t child, wpid;
11721.1Skamil#if defined(TWAIT_HAVE_STATUS)
11731.1Skamil	int status;
11741.1Skamil#endif
11751.1Skamil	ptrace_event_t set_event, get_event;
11761.1Skamil	const int len = sizeof(ptrace_event_t);
11771.1Skamil
11781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11801.1Skamil	if (child == 0) {
11811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11831.1Skamil
11841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11861.1Skamil
11871.13Schristos		DPRINTF("Before exiting of the child process\n");
11881.1Skamil		_exit(exitval);
11891.1Skamil	}
11901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11911.1Skamil
11921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11941.1Skamil
11951.1Skamil	validate_status_stopped(status, sigval);
11961.1Skamil
11971.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
11981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12001.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12011.1Skamil
12021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12031.1Skamil	    "without signal to be sent\n");
12041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12051.1Skamil
12061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12081.1Skamil
12091.1Skamil	validate_status_exited(status, exitval);
12101.1Skamil
12111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12131.1Skamil}
12141.1Skamil
12151.1SkamilATF_TC(eventmask5);
12161.1SkamilATF_TC_HEAD(eventmask5, tc)
12171.1Skamil{
12181.1Skamil	atf_tc_set_md_var(tc, "descr",
12191.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
12201.1Skamil}
12211.1Skamil
12221.1SkamilATF_TC_BODY(eventmask5, tc)
12231.1Skamil{
12241.1Skamil	const int exitval = 5;
12251.1Skamil	const int sigval = SIGSTOP;
12261.1Skamil	pid_t child, wpid;
12271.1Skamil#if defined(TWAIT_HAVE_STATUS)
12281.1Skamil	int status;
12291.1Skamil#endif
12301.1Skamil	ptrace_event_t set_event, get_event;
12311.1Skamil	const int len = sizeof(ptrace_event_t);
12321.1Skamil
12331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12351.1Skamil	if (child == 0) {
12361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12381.1Skamil
12391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12411.1Skamil
12421.13Schristos		DPRINTF("Before exiting of the child process\n");
12431.1Skamil		_exit(exitval);
12441.1Skamil	}
12451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12461.1Skamil
12471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12491.1Skamil
12501.1Skamil	validate_status_stopped(status, sigval);
12511.1Skamil
12521.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12551.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12561.1Skamil
12571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12581.1Skamil	    "without signal to be sent\n");
12591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12601.1Skamil
12611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12631.1Skamil
12641.1Skamil	validate_status_exited(status, exitval);
12651.1Skamil
12661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12681.1Skamil}
12691.1Skamil
12701.1SkamilATF_TC(eventmask6);
12711.1SkamilATF_TC_HEAD(eventmask6, tc)
12721.1Skamil{
12731.1Skamil	atf_tc_set_md_var(tc, "descr",
12741.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12751.1Skamil}
12761.1Skamil
12771.1SkamilATF_TC_BODY(eventmask6, tc)
12781.1Skamil{
12791.1Skamil	const int exitval = 5;
12801.1Skamil	const int sigval = SIGSTOP;
12811.1Skamil	pid_t child, wpid;
12821.1Skamil#if defined(TWAIT_HAVE_STATUS)
12831.1Skamil	int status;
12841.1Skamil#endif
12851.1Skamil	ptrace_event_t set_event, get_event;
12861.1Skamil	const int len = sizeof(ptrace_event_t);
12871.1Skamil
12881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12901.1Skamil	if (child == 0) {
12911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12931.1Skamil
12941.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12951.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12961.1Skamil
12971.13Schristos		DPRINTF("Before exiting of the child process\n");
12981.1Skamil		_exit(exitval);
12991.1Skamil	}
13001.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13011.1Skamil
13021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13041.1Skamil
13051.1Skamil	validate_status_stopped(status, sigval);
13061.1Skamil
13071.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
13081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13101.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13111.1Skamil
13121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13131.1Skamil	    "without signal to be sent\n");
13141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13151.1Skamil
13161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13181.1Skamil
13191.1Skamil	validate_status_exited(status, exitval);
13201.1Skamil
13211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13231.1Skamil}
13241.1Skamil
13251.28Skamilstatic void
13261.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
13271.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
13281.1Skamil{
13291.1Skamil	const int exitval = 5;
13301.1Skamil	const int exitval2 = 15;
13311.1Skamil	const int sigval = SIGSTOP;
13321.31Skamil	pid_t child, child2 = 0, wpid;
13331.1Skamil#if defined(TWAIT_HAVE_STATUS)
13341.1Skamil	int status;
13351.1Skamil#endif
13361.1Skamil	ptrace_state_t state;
13371.1Skamil	const int slen = sizeof(state);
13381.1Skamil	ptrace_event_t event;
13391.1Skamil	const int elen = sizeof(event);
13401.1Skamil
13411.30Skamil	if (trackvfork) {
13421.28Skamil		atf_tc_expect_fail("PR kern/51630");
13431.28Skamil	}
13441.28Skamil
13451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13471.1Skamil	if (child == 0) {
13481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13501.1Skamil
13511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13531.1Skamil
13541.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
13551.1Skamil
13561.1Skamil		if (child2 == 0)
13571.1Skamil			_exit(exitval2);
13581.1Skamil
13591.1Skamil		FORKEE_REQUIRE_SUCCESS
13601.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13611.1Skamil
13621.1Skamil		forkee_status_exited(status, exitval2);
13631.1Skamil
13641.13Schristos		DPRINTF("Before exiting of the child process\n");
13651.1Skamil		_exit(exitval);
13661.1Skamil	}
13671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13681.1Skamil
13691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13711.1Skamil
13721.1Skamil	validate_status_stopped(status, sigval);
13731.1Skamil
13741.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
13751.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
13761.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
13771.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
13781.30Skamil	event.pe_set_event = 0;
13791.30Skamil	if (trackfork)
13801.30Skamil		event.pe_set_event |= PTRACE_FORK;
13811.30Skamil	if (trackvfork)
13821.30Skamil		event.pe_set_event |= PTRACE_VFORK;
13831.30Skamil	if (trackvforkdone)
13841.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
13851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13861.1Skamil
13871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13881.1Skamil	    "without signal to be sent\n");
13891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13901.1Skamil
13911.29Skamil#if defined(TWAIT_HAVE_PID)
13921.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
13931.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
13941.29Skamil		        child);
13951.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
13961.29Skamil		                      child);
13971.1Skamil
13981.29Skamil		validate_status_stopped(status, SIGTRAP);
13991.1Skamil
14001.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
14011.29Skamil		                       slen) != -1);
14021.31Skamil		if (trackfork && fn == fork) {
14031.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
14041.30Skamil			       PTRACE_FORK);
14051.30Skamil		}
14061.31Skamil		if (trackvfork && fn == vfork) {
14071.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
14081.30Skamil			       PTRACE_VFORK);
14091.30Skamil		}
14101.29Skamil
14111.29Skamil		child2 = state.pe_other_pid;
14121.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
14131.29Skamil
14141.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
14151.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
14161.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14171.29Skamil		    child2);
14181.1Skamil
14191.29Skamil		validate_status_stopped(status, SIGTRAP);
14201.1Skamil
14211.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
14221.29Skamil		                       slen) != -1);
14231.31Skamil		if (trackfork && fn == fork) {
14241.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
14251.30Skamil			       PTRACE_FORK);
14261.30Skamil		}
14271.31Skamil		if (trackvfork && fn == vfork) {
14281.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
14291.30Skamil			       PTRACE_VFORK);
14301.30Skamil		}
14311.30Skamil
14321.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
14331.29Skamil
14341.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
14351.29Skamil		    "and without signal to be sent\n");
14361.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
14371.29Skamil		                != -1);
14381.29Skamil
14391.29Skamil		DPRINTF("Before resuming the child process where it left off "
14401.29Skamil		        "and without signal to be sent\n");
14411.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14421.30Skamil	}
14431.30Skamil#endif
14441.30Skamil
14451.31Skamil	if (trackvforkdone && fn == vfork) {
14461.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
14471.30Skamil		        child);
14481.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
14491.30Skamil		                      child);
14501.30Skamil
14511.30Skamil		validate_status_stopped(status, SIGTRAP);
14521.30Skamil
14531.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
14541.30Skamil		                       slen) != -1);
14551.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
14561.30Skamil
14571.30Skamil		child2 = state.pe_other_pid;
14581.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
14591.30Skamil		        child2);
14601.30Skamil
14611.30Skamil		DPRINTF("Before resuming the child process where it left off "
14621.30Skamil		        "and without signal to be sent\n");
14631.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14641.30Skamil	}
14651.29Skamil
14661.30Skamil#if defined(TWAIT_HAVE_PID)
14671.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
14681.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
14691.29Skamil		        "\n", TWAIT_FNAME);
14701.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14711.29Skamil		    child2);
14721.29Skamil
14731.29Skamil		validate_status_exited(status, exitval2);
14741.29Skamil
14751.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
14761.29Skamil		        "process\n", TWAIT_FNAME);
14771.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
14781.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
14791.29Skamil	}
14801.29Skamil#endif
14811.1Skamil
14821.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14831.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14851.1Skamil
14861.1Skamil	validate_status_stopped(status, SIGCHLD);
14871.1Skamil
14881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14891.1Skamil	    "without signal to be sent\n");
14901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14911.1Skamil
14921.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
14931.1Skamil	    TWAIT_FNAME);
14941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14951.1Skamil
14961.1Skamil	validate_status_exited(status, exitval);
14971.1Skamil
14981.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
14991.1Skamil	    TWAIT_FNAME);
15001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15011.1Skamil}
15021.28Skamil
15031.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
15041.32SkamilATF_TC(name);									\
15051.32SkamilATF_TC_HEAD(name, tc)								\
15061.32Skamil{										\
15071.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
15081.32Skamil}										\
15091.32Skamil										\
15101.32SkamilATF_TC_BODY(name, tc)								\
15111.32Skamil{										\
15121.32Skamil										\
15131.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
15141.32Skamil}
15151.32Skamil
15161.32Skamil#define F false
15171.32Skamil#define T true
15181.32Skamil
15191.32Skamil#define F_IF__0(x)
15201.32Skamil#define F_IF__1(x) x
15211.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
15221.32Skamil#define F_IF_(x,y) F_IF__(x,y)
15231.32Skamil#define F_IF(x,y) F_IF_(x,y)
15241.32Skamil
15251.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
15261.32Skamil        "Verify " #function "(2) called with 0"					\
15271.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
15281.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
15291.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
15301.32Skamil        " in EVENT_MASK."							\
15311.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
15321.32Skamil        F_IF(dparentbit," Detach parent in this test.")
15331.1Skamil
15341.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
15351.31Skamil#if defined(TWAIT_HAVE_PID)
15361.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
15371.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
15381.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
15391.31Skamil#endif
15401.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
15411.31Skamil#if defined(TWAIT_HAVE_PID)
15421.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
15431.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
15441.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
15451.31Skamil#endif
15461.1Skamil
15471.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
15481.31Skamil#if defined(TWAIT_HAVE_PID)
15491.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
15501.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
15511.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
15521.31Skamil#endif
15531.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
15541.31Skamil#if defined(TWAIT_HAVE_PID)
15551.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
15561.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
15571.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
15581.31Skamil#endif
15591.31Skamil
15601.31Skamil
15611.31Skamil
15621.1Skamil
15631.1SkamilATF_TC(io_read_d1);
15641.1SkamilATF_TC_HEAD(io_read_d1, tc)
15651.1Skamil{
15661.1Skamil	atf_tc_set_md_var(tc, "descr",
15671.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
15681.1Skamil}
15691.1Skamil
15701.1SkamilATF_TC_BODY(io_read_d1, tc)
15711.1Skamil{
15721.1Skamil	const int exitval = 5;
15731.1Skamil	const int sigval = SIGSTOP;
15741.1Skamil	pid_t child, wpid;
15751.1Skamil	uint8_t lookup_me = 0;
15761.1Skamil	const uint8_t magic = 0xab;
15771.1Skamil	struct ptrace_io_desc io = {
15781.1Skamil		.piod_op = PIOD_READ_D,
15791.1Skamil		.piod_offs = &lookup_me,
15801.1Skamil		.piod_addr = &lookup_me,
15811.1Skamil		.piod_len = sizeof(lookup_me)
15821.1Skamil	};
15831.1Skamil#if defined(TWAIT_HAVE_STATUS)
15841.1Skamil	int status;
15851.1Skamil#endif
15861.1Skamil
15871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15891.1Skamil	if (child == 0) {
15901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15921.1Skamil
15931.1Skamil		lookup_me = magic;
15941.1Skamil
15951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15971.1Skamil
15981.13Schristos		DPRINTF("Before exiting of the child process\n");
15991.1Skamil		_exit(exitval);
16001.1Skamil	}
16011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16021.1Skamil
16031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16051.1Skamil
16061.1Skamil	validate_status_stopped(status, sigval);
16071.1Skamil
16081.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16091.1Skamil	    child, getpid());
16101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16111.1Skamil
16121.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16131.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
16141.1Skamil
16151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16161.1Skamil	    "without signal to be sent\n");
16171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16181.1Skamil
16191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16211.1Skamil
16221.1Skamil	validate_status_exited(status, exitval);
16231.1Skamil
16241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16261.1Skamil}
16271.1Skamil
16281.1SkamilATF_TC(io_read_d2);
16291.1SkamilATF_TC_HEAD(io_read_d2, tc)
16301.1Skamil{
16311.1Skamil	atf_tc_set_md_var(tc, "descr",
16321.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
16331.1Skamil}
16341.1Skamil
16351.1SkamilATF_TC_BODY(io_read_d2, tc)
16361.1Skamil{
16371.1Skamil	const int exitval = 5;
16381.1Skamil	const int sigval = SIGSTOP;
16391.1Skamil	pid_t child, wpid;
16401.1Skamil	uint16_t lookup_me = 0;
16411.1Skamil	const uint16_t magic = 0x1234;
16421.1Skamil	struct ptrace_io_desc io = {
16431.1Skamil		.piod_op = PIOD_READ_D,
16441.1Skamil		.piod_offs = &lookup_me,
16451.1Skamil		.piod_addr = &lookup_me,
16461.1Skamil		.piod_len = sizeof(lookup_me)
16471.1Skamil	};
16481.1Skamil#if defined(TWAIT_HAVE_STATUS)
16491.1Skamil	int status;
16501.1Skamil#endif
16511.1Skamil
16521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16541.1Skamil	if (child == 0) {
16551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16571.1Skamil
16581.1Skamil		lookup_me = magic;
16591.1Skamil
16601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16621.1Skamil
16631.13Schristos		DPRINTF("Before exiting of the child process\n");
16641.1Skamil		_exit(exitval);
16651.1Skamil	}
16661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16671.1Skamil
16681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16701.1Skamil
16711.1Skamil	validate_status_stopped(status, sigval);
16721.1Skamil
16731.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16741.1Skamil	    child, getpid());
16751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16761.1Skamil
16771.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16781.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
16791.1Skamil
16801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16811.1Skamil	    "without signal to be sent\n");
16821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16831.1Skamil
16841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16861.1Skamil
16871.1Skamil	validate_status_exited(status, exitval);
16881.1Skamil
16891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16911.1Skamil}
16921.1Skamil
16931.1SkamilATF_TC(io_read_d3);
16941.1SkamilATF_TC_HEAD(io_read_d3, tc)
16951.1Skamil{
16961.1Skamil	atf_tc_set_md_var(tc, "descr",
16971.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
16981.1Skamil}
16991.1Skamil
17001.1SkamilATF_TC_BODY(io_read_d3, tc)
17011.1Skamil{
17021.1Skamil	const int exitval = 5;
17031.1Skamil	const int sigval = SIGSTOP;
17041.1Skamil	pid_t child, wpid;
17051.1Skamil	uint32_t lookup_me = 0;
17061.1Skamil	const uint32_t magic = 0x1234abcd;
17071.1Skamil	struct ptrace_io_desc io = {
17081.1Skamil		.piod_op = PIOD_READ_D,
17091.1Skamil		.piod_offs = &lookup_me,
17101.1Skamil		.piod_addr = &lookup_me,
17111.1Skamil		.piod_len = sizeof(lookup_me)
17121.1Skamil	};
17131.1Skamil#if defined(TWAIT_HAVE_STATUS)
17141.1Skamil	int status;
17151.1Skamil#endif
17161.1Skamil
17171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17191.1Skamil	if (child == 0) {
17201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17221.1Skamil
17231.1Skamil		lookup_me = magic;
17241.1Skamil
17251.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17261.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17271.1Skamil
17281.13Schristos		DPRINTF("Before exiting of the child process\n");
17291.1Skamil		_exit(exitval);
17301.1Skamil	}
17311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17321.1Skamil
17331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17351.1Skamil
17361.1Skamil	validate_status_stopped(status, sigval);
17371.1Skamil
17381.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
17391.1Skamil	    child, getpid());
17401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
17411.1Skamil
17421.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
17431.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
17441.1Skamil
17451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17461.1Skamil	    "without signal to be sent\n");
17471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17481.1Skamil
17491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17511.1Skamil
17521.1Skamil	validate_status_exited(status, exitval);
17531.1Skamil
17541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17561.1Skamil}
17571.1Skamil
17581.1SkamilATF_TC(io_read_d4);
17591.1SkamilATF_TC_HEAD(io_read_d4, tc)
17601.1Skamil{
17611.1Skamil	atf_tc_set_md_var(tc, "descr",
17621.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
17631.1Skamil}
17641.1Skamil
17651.1SkamilATF_TC_BODY(io_read_d4, tc)
17661.1Skamil{
17671.1Skamil	const int exitval = 5;
17681.1Skamil	const int sigval = SIGSTOP;
17691.1Skamil	pid_t child, wpid;
17701.1Skamil	uint64_t lookup_me = 0;
17711.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
17721.1Skamil	struct ptrace_io_desc io = {
17731.1Skamil		.piod_op = PIOD_READ_D,
17741.1Skamil		.piod_offs = &lookup_me,
17751.1Skamil		.piod_addr = &lookup_me,
17761.1Skamil		.piod_len = sizeof(lookup_me)
17771.1Skamil	};
17781.1Skamil#if defined(TWAIT_HAVE_STATUS)
17791.1Skamil	int status;
17801.1Skamil#endif
17811.1Skamil
17821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17841.1Skamil	if (child == 0) {
17851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17871.1Skamil
17881.1Skamil		lookup_me = magic;
17891.1Skamil
17901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17921.1Skamil
17931.13Schristos		DPRINTF("Before exiting of the child process\n");
17941.1Skamil		_exit(exitval);
17951.1Skamil	}
17961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17971.1Skamil
17981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18001.1Skamil
18011.1Skamil	validate_status_stopped(status, sigval);
18021.1Skamil
18031.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
18041.1Skamil	    child, getpid());
18051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18061.1Skamil
18071.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
18081.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
18091.1Skamil
18101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18111.1Skamil	    "without signal to be sent\n");
18121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18131.1Skamil
18141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18161.1Skamil
18171.1Skamil	validate_status_exited(status, exitval);
18181.1Skamil
18191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18211.1Skamil}
18221.1Skamil
18231.1SkamilATF_TC(io_write_d1);
18241.1SkamilATF_TC_HEAD(io_write_d1, tc)
18251.1Skamil{
18261.1Skamil	atf_tc_set_md_var(tc, "descr",
18271.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
18281.1Skamil}
18291.1Skamil
18301.1SkamilATF_TC_BODY(io_write_d1, tc)
18311.1Skamil{
18321.1Skamil	const int exitval = 5;
18331.1Skamil	const int sigval = SIGSTOP;
18341.1Skamil	pid_t child, wpid;
18351.1Skamil	uint8_t lookup_me = 0;
18361.1Skamil	const uint8_t magic = 0xab;
18371.1Skamil	struct ptrace_io_desc io = {
18381.1Skamil		.piod_op = PIOD_WRITE_D,
18391.1Skamil		.piod_offs = &lookup_me,
18401.1Skamil		.piod_addr = &lookup_me,
18411.1Skamil		.piod_len = sizeof(lookup_me)
18421.1Skamil	};
18431.1Skamil#if defined(TWAIT_HAVE_STATUS)
18441.1Skamil	int status;
18451.1Skamil#endif
18461.1Skamil
18471.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18481.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18491.1Skamil	if (child == 0) {
18501.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18511.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18521.1Skamil
18531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18551.1Skamil
18561.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
18571.1Skamil
18581.13Schristos		DPRINTF("Before exiting of the child process\n");
18591.1Skamil		_exit(exitval);
18601.1Skamil	}
18611.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18621.1Skamil
18631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18651.1Skamil
18661.1Skamil	validate_status_stopped(status, sigval);
18671.1Skamil
18681.1Skamil	lookup_me = magic;
18691.1Skamil
18701.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
18711.1Skamil	    child, getpid());
18721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18731.1Skamil
18741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18751.1Skamil	    "without signal to be sent\n");
18761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18771.1Skamil
18781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18801.1Skamil
18811.1Skamil	validate_status_exited(status, exitval);
18821.1Skamil
18831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18841.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18851.1Skamil}
18861.1Skamil
18871.1SkamilATF_TC(io_write_d2);
18881.1SkamilATF_TC_HEAD(io_write_d2, tc)
18891.1Skamil{
18901.1Skamil	atf_tc_set_md_var(tc, "descr",
18911.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
18921.1Skamil}
18931.1Skamil
18941.1SkamilATF_TC_BODY(io_write_d2, tc)
18951.1Skamil{
18961.1Skamil	const int exitval = 5;
18971.1Skamil	const int sigval = SIGSTOP;
18981.1Skamil	pid_t child, wpid;
18991.1Skamil	uint16_t lookup_me = 0;
19001.1Skamil	const uint16_t magic = 0xab12;
19011.1Skamil	struct ptrace_io_desc io = {
19021.1Skamil		.piod_op = PIOD_WRITE_D,
19031.1Skamil		.piod_offs = &lookup_me,
19041.1Skamil		.piod_addr = &lookup_me,
19051.1Skamil		.piod_len = sizeof(lookup_me)
19061.1Skamil	};
19071.1Skamil#if defined(TWAIT_HAVE_STATUS)
19081.1Skamil	int status;
19091.1Skamil#endif
19101.1Skamil
19111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19131.1Skamil	if (child == 0) {
19141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19161.1Skamil
19171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19191.1Skamil
19201.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19211.1Skamil
19221.13Schristos		DPRINTF("Before exiting of the child process\n");
19231.1Skamil		_exit(exitval);
19241.1Skamil	}
19251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19261.1Skamil
19271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19291.1Skamil
19301.1Skamil	validate_status_stopped(status, sigval);
19311.1Skamil
19321.1Skamil	lookup_me = magic;
19331.1Skamil
19341.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
19351.1Skamil	    child, getpid());
19361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19371.1Skamil
19381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19391.1Skamil	    "without signal to be sent\n");
19401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19411.1Skamil
19421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19441.1Skamil
19451.1Skamil	validate_status_exited(status, exitval);
19461.1Skamil
19471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19481.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19491.1Skamil}
19501.1Skamil
19511.1SkamilATF_TC(io_write_d3);
19521.1SkamilATF_TC_HEAD(io_write_d3, tc)
19531.1Skamil{
19541.1Skamil	atf_tc_set_md_var(tc, "descr",
19551.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
19561.1Skamil}
19571.1Skamil
19581.1SkamilATF_TC_BODY(io_write_d3, tc)
19591.1Skamil{
19601.1Skamil	const int exitval = 5;
19611.1Skamil	const int sigval = SIGSTOP;
19621.1Skamil	pid_t child, wpid;
19631.1Skamil	uint32_t lookup_me = 0;
19641.1Skamil	const uint32_t magic = 0xab127643;
19651.1Skamil	struct ptrace_io_desc io = {
19661.1Skamil		.piod_op = PIOD_WRITE_D,
19671.1Skamil		.piod_offs = &lookup_me,
19681.1Skamil		.piod_addr = &lookup_me,
19691.1Skamil		.piod_len = sizeof(lookup_me)
19701.1Skamil	};
19711.1Skamil#if defined(TWAIT_HAVE_STATUS)
19721.1Skamil	int status;
19731.1Skamil#endif
19741.1Skamil
19751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19771.1Skamil	if (child == 0) {
19781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19801.1Skamil
19811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19831.1Skamil
19841.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19851.1Skamil
19861.13Schristos		DPRINTF("Before exiting of the child process\n");
19871.1Skamil		_exit(exitval);
19881.1Skamil	}
19891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19901.1Skamil
19911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19931.1Skamil
19941.1Skamil	validate_status_stopped(status, sigval);
19951.1Skamil
19961.1Skamil	lookup_me = magic;
19971.1Skamil
19981.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
19991.1Skamil	    child, getpid());
20001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20011.1Skamil
20021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20031.1Skamil	    "without signal to be sent\n");
20041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20051.1Skamil
20061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20081.1Skamil
20091.1Skamil	validate_status_exited(status, exitval);
20101.1Skamil
20111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20131.1Skamil}
20141.1Skamil
20151.1SkamilATF_TC(io_write_d4);
20161.1SkamilATF_TC_HEAD(io_write_d4, tc)
20171.1Skamil{
20181.1Skamil	atf_tc_set_md_var(tc, "descr",
20191.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
20201.1Skamil}
20211.1Skamil
20221.1SkamilATF_TC_BODY(io_write_d4, tc)
20231.1Skamil{
20241.1Skamil	const int exitval = 5;
20251.1Skamil	const int sigval = SIGSTOP;
20261.1Skamil	pid_t child, wpid;
20271.1Skamil	uint64_t lookup_me = 0;
20281.1Skamil	const uint64_t magic = 0xab12764376490123;
20291.1Skamil	struct ptrace_io_desc io = {
20301.1Skamil		.piod_op = PIOD_WRITE_D,
20311.1Skamil		.piod_offs = &lookup_me,
20321.1Skamil		.piod_addr = &lookup_me,
20331.1Skamil		.piod_len = sizeof(lookup_me)
20341.1Skamil	};
20351.1Skamil#if defined(TWAIT_HAVE_STATUS)
20361.1Skamil	int status;
20371.1Skamil#endif
20381.1Skamil
20391.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20401.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20411.1Skamil	if (child == 0) {
20421.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20431.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20441.1Skamil
20451.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20461.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20471.1Skamil
20481.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
20491.1Skamil
20501.13Schristos		DPRINTF("Before exiting of the child process\n");
20511.1Skamil		_exit(exitval);
20521.1Skamil	}
20531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20541.1Skamil
20551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20571.1Skamil
20581.1Skamil	validate_status_stopped(status, sigval);
20591.1Skamil
20601.1Skamil	lookup_me = magic;
20611.1Skamil
20621.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20631.1Skamil	    child, getpid());
20641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20651.1Skamil
20661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20671.1Skamil	    "without signal to be sent\n");
20681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20691.1Skamil
20701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20721.1Skamil
20731.1Skamil	validate_status_exited(status, exitval);
20741.1Skamil
20751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20771.1Skamil}
20781.1Skamil
20791.1SkamilATF_TC(io_read_auxv1);
20801.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
20811.1Skamil{
20821.1Skamil	atf_tc_set_md_var(tc, "descr",
20831.1Skamil	    "Verify PT_READ_AUXV called for tracee");
20841.1Skamil}
20851.1Skamil
20861.1SkamilATF_TC_BODY(io_read_auxv1, tc)
20871.1Skamil{
20881.1Skamil	const int exitval = 5;
20891.1Skamil	const int sigval = SIGSTOP;
20901.1Skamil	pid_t child, wpid;
20911.1Skamil#if defined(TWAIT_HAVE_STATUS)
20921.1Skamil	int status;
20931.1Skamil#endif
20941.1Skamil	AuxInfo ai[100], *aip;
20951.1Skamil	struct ptrace_io_desc io = {
20961.1Skamil		.piod_op = PIOD_READ_AUXV,
20971.1Skamil		.piod_offs = 0,
20981.1Skamil		.piod_addr = ai,
20991.1Skamil		.piod_len = sizeof(ai)
21001.1Skamil	};
21011.1Skamil
21021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21041.1Skamil	if (child == 0) {
21051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21071.1Skamil
21081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21101.1Skamil
21111.13Schristos		DPRINTF("Before exiting of the child process\n");
21121.1Skamil		_exit(exitval);
21131.1Skamil	}
21141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21151.1Skamil
21161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21181.1Skamil
21191.1Skamil	validate_status_stopped(status, sigval);
21201.1Skamil
21211.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
21221.1Skamil	    child, getpid());
21231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21241.1Skamil
21251.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
21261.1Skamil	ATF_REQUIRE(io.piod_len > 0);
21271.1Skamil
21281.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
21291.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
21301.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
21311.1Skamil
21321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21331.1Skamil	    "without signal to be sent\n");
21341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21351.1Skamil
21361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21381.1Skamil
21391.1Skamil	validate_status_exited(status, exitval);
21401.1Skamil
21411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21431.1Skamil}
21441.1Skamil
21451.1SkamilATF_TC(read_d1);
21461.1SkamilATF_TC_HEAD(read_d1, tc)
21471.1Skamil{
21481.1Skamil	atf_tc_set_md_var(tc, "descr",
21491.1Skamil	    "Verify PT_READ_D called once");
21501.1Skamil}
21511.1Skamil
21521.1SkamilATF_TC_BODY(read_d1, tc)
21531.1Skamil{
21541.1Skamil	const int exitval = 5;
21551.1Skamil	const int sigval = SIGSTOP;
21561.1Skamil	pid_t child, wpid;
21571.1Skamil	int lookup_me = 0;
21581.1Skamil	const int magic = (int)random();
21591.1Skamil#if defined(TWAIT_HAVE_STATUS)
21601.1Skamil	int status;
21611.1Skamil#endif
21621.1Skamil
21631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21651.1Skamil	if (child == 0) {
21661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21681.1Skamil
21691.1Skamil		lookup_me = magic;
21701.1Skamil
21711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21731.1Skamil
21741.13Schristos		DPRINTF("Before exiting of the child process\n");
21751.1Skamil		_exit(exitval);
21761.1Skamil	}
21771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21781.1Skamil
21791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21811.1Skamil
21821.1Skamil	validate_status_stopped(status, sigval);
21831.1Skamil
21841.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21851.1Skamil	    child, getpid());
21861.1Skamil	errno = 0;
21871.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
21881.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
21891.1Skamil
21901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21911.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
21921.1Skamil
21931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21941.1Skamil	    "without signal to be sent\n");
21951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21961.1Skamil
21971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21991.1Skamil
22001.1Skamil	validate_status_exited(status, exitval);
22011.1Skamil
22021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22041.1Skamil}
22051.1Skamil
22061.1SkamilATF_TC(read_d2);
22071.1SkamilATF_TC_HEAD(read_d2, tc)
22081.1Skamil{
22091.1Skamil	atf_tc_set_md_var(tc, "descr",
22101.1Skamil	    "Verify PT_READ_D called twice");
22111.1Skamil}
22121.1Skamil
22131.1SkamilATF_TC_BODY(read_d2, tc)
22141.1Skamil{
22151.1Skamil	const int exitval = 5;
22161.1Skamil	const int sigval = SIGSTOP;
22171.1Skamil	pid_t child, wpid;
22181.1Skamil	int lookup_me1 = 0;
22191.1Skamil	int lookup_me2 = 0;
22201.1Skamil	const int magic1 = (int)random();
22211.1Skamil	const int magic2 = (int)random();
22221.1Skamil#if defined(TWAIT_HAVE_STATUS)
22231.1Skamil	int status;
22241.1Skamil#endif
22251.1Skamil
22261.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22271.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22281.1Skamil	if (child == 0) {
22291.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22301.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22311.1Skamil
22321.1Skamil		lookup_me1 = magic1;
22331.1Skamil		lookup_me2 = magic2;
22341.1Skamil
22351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22371.1Skamil
22381.13Schristos		DPRINTF("Before exiting of the child process\n");
22391.1Skamil		_exit(exitval);
22401.1Skamil	}
22411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22421.1Skamil
22431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22451.1Skamil
22461.1Skamil	validate_status_stopped(status, sigval);
22471.1Skamil
22481.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
22491.1Skamil	    child, getpid());
22501.1Skamil	errno = 0;
22511.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
22521.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22531.1Skamil
22541.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
22551.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
22561.1Skamil
22571.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
22581.1Skamil	    child, getpid());
22591.1Skamil	errno = 0;
22601.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
22611.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22621.1Skamil
22631.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
22641.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
22651.1Skamil
22661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22671.1Skamil	    "without signal to be sent\n");
22681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22691.1Skamil
22701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22721.1Skamil
22731.1Skamil	validate_status_exited(status, exitval);
22741.1Skamil
22751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22771.1Skamil}
22781.1Skamil
22791.1SkamilATF_TC(read_d3);
22801.1SkamilATF_TC_HEAD(read_d3, tc)
22811.1Skamil{
22821.1Skamil	atf_tc_set_md_var(tc, "descr",
22831.1Skamil	    "Verify PT_READ_D called three times");
22841.1Skamil}
22851.1Skamil
22861.1SkamilATF_TC_BODY(read_d3, tc)
22871.1Skamil{
22881.1Skamil	const int exitval = 5;
22891.1Skamil	const int sigval = SIGSTOP;
22901.1Skamil	pid_t child, wpid;
22911.1Skamil	int lookup_me1 = 0;
22921.1Skamil	int lookup_me2 = 0;
22931.1Skamil	int lookup_me3 = 0;
22941.1Skamil	const int magic1 = (int)random();
22951.1Skamil	const int magic2 = (int)random();
22961.1Skamil	const int magic3 = (int)random();
22971.1Skamil#if defined(TWAIT_HAVE_STATUS)
22981.1Skamil	int status;
22991.1Skamil#endif
23001.1Skamil
23011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23031.1Skamil	if (child == 0) {
23041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23061.1Skamil
23071.1Skamil		lookup_me1 = magic1;
23081.1Skamil		lookup_me2 = magic2;
23091.1Skamil		lookup_me3 = magic3;
23101.1Skamil
23111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23131.1Skamil
23141.13Schristos		DPRINTF("Before exiting of the child process\n");
23151.1Skamil		_exit(exitval);
23161.1Skamil	}
23171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23181.1Skamil
23191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23211.1Skamil
23221.1Skamil	validate_status_stopped(status, sigval);
23231.1Skamil
23241.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
23251.1Skamil	    child, getpid());
23261.1Skamil	errno = 0;
23271.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
23281.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23291.1Skamil
23301.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
23311.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
23321.1Skamil
23331.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
23341.1Skamil	    child, getpid());
23351.1Skamil	errno = 0;
23361.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
23371.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23381.1Skamil
23391.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
23401.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
23411.1Skamil
23421.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
23431.1Skamil	    child, getpid());
23441.1Skamil	errno = 0;
23451.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
23461.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23471.1Skamil
23481.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
23491.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
23501.1Skamil
23511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23521.1Skamil	    "without signal to be sent\n");
23531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23541.1Skamil
23551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23571.1Skamil
23581.1Skamil	validate_status_exited(status, exitval);
23591.1Skamil
23601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23621.1Skamil}
23631.1Skamil
23641.1SkamilATF_TC(read_d4);
23651.1SkamilATF_TC_HEAD(read_d4, tc)
23661.1Skamil{
23671.1Skamil	atf_tc_set_md_var(tc, "descr",
23681.1Skamil	    "Verify PT_READ_D called four times");
23691.1Skamil}
23701.1Skamil
23711.1SkamilATF_TC_BODY(read_d4, tc)
23721.1Skamil{
23731.1Skamil	const int exitval = 5;
23741.1Skamil	const int sigval = SIGSTOP;
23751.1Skamil	pid_t child, wpid;
23761.1Skamil	int lookup_me1 = 0;
23771.1Skamil	int lookup_me2 = 0;
23781.1Skamil	int lookup_me3 = 0;
23791.1Skamil	int lookup_me4 = 0;
23801.1Skamil	const int magic1 = (int)random();
23811.1Skamil	const int magic2 = (int)random();
23821.1Skamil	const int magic3 = (int)random();
23831.1Skamil	const int magic4 = (int)random();
23841.1Skamil#if defined(TWAIT_HAVE_STATUS)
23851.1Skamil	int status;
23861.1Skamil#endif
23871.1Skamil
23881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23901.1Skamil	if (child == 0) {
23911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23931.1Skamil
23941.1Skamil		lookup_me1 = magic1;
23951.1Skamil		lookup_me2 = magic2;
23961.1Skamil		lookup_me3 = magic3;
23971.1Skamil		lookup_me4 = magic4;
23981.1Skamil
23991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24011.1Skamil
24021.13Schristos		DPRINTF("Before exiting of the child process\n");
24031.1Skamil		_exit(exitval);
24041.1Skamil	}
24051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24061.1Skamil
24071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24091.1Skamil
24101.1Skamil	validate_status_stopped(status, sigval);
24111.1Skamil
24121.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
24131.1Skamil	    child, getpid());
24141.1Skamil	errno = 0;
24151.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
24161.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24171.1Skamil
24181.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
24191.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
24201.1Skamil
24211.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
24221.1Skamil	    child, getpid());
24231.1Skamil	errno = 0;
24241.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
24251.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24261.1Skamil
24271.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
24281.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
24291.1Skamil
24301.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
24311.1Skamil	    child, getpid());
24321.1Skamil	errno = 0;
24331.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
24341.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24351.1Skamil
24361.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
24371.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
24381.1Skamil
24391.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
24401.1Skamil	    child, getpid());
24411.1Skamil	errno = 0;
24421.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
24431.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24441.1Skamil
24451.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
24461.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
24471.1Skamil
24481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24491.1Skamil	    "without signal to be sent\n");
24501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24511.1Skamil
24521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24541.1Skamil
24551.1Skamil	validate_status_exited(status, exitval);
24561.1Skamil
24571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24591.1Skamil}
24601.1Skamil
24611.1SkamilATF_TC(write_d1);
24621.1SkamilATF_TC_HEAD(write_d1, tc)
24631.1Skamil{
24641.1Skamil	atf_tc_set_md_var(tc, "descr",
24651.1Skamil	    "Verify PT_WRITE_D called once");
24661.1Skamil}
24671.1Skamil
24681.1SkamilATF_TC_BODY(write_d1, tc)
24691.1Skamil{
24701.1Skamil	const int exitval = 5;
24711.1Skamil	const int sigval = SIGSTOP;
24721.1Skamil	pid_t child, wpid;
24731.1Skamil	int lookup_me = 0;
24741.1Skamil	const int magic = (int)random();
24751.1Skamil#if defined(TWAIT_HAVE_STATUS)
24761.1Skamil	int status;
24771.1Skamil#endif
24781.1Skamil
24791.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24801.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24811.1Skamil	if (child == 0) {
24821.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24831.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24841.1Skamil
24851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24871.1Skamil
24881.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
24891.1Skamil
24901.13Schristos		DPRINTF("Before exiting of the child process\n");
24911.1Skamil		_exit(exitval);
24921.1Skamil	}
24931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24941.1Skamil
24951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24971.1Skamil
24981.1Skamil	validate_status_stopped(status, sigval);
24991.1Skamil
25001.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
25011.1Skamil	    child, getpid());
25021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
25031.1Skamil
25041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25051.1Skamil	    "without signal to be sent\n");
25061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25071.1Skamil
25081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25101.1Skamil
25111.1Skamil	validate_status_exited(status, exitval);
25121.1Skamil
25131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25151.1Skamil}
25161.1Skamil
25171.1SkamilATF_TC(write_d2);
25181.1SkamilATF_TC_HEAD(write_d2, tc)
25191.1Skamil{
25201.1Skamil	atf_tc_set_md_var(tc, "descr",
25211.1Skamil	    "Verify PT_WRITE_D called twice");
25221.1Skamil}
25231.1Skamil
25241.1SkamilATF_TC_BODY(write_d2, tc)
25251.1Skamil{
25261.1Skamil	const int exitval = 5;
25271.1Skamil	const int sigval = SIGSTOP;
25281.1Skamil	pid_t child, wpid;
25291.1Skamil	int lookup_me1 = 0;
25301.1Skamil	int lookup_me2 = 0;
25311.1Skamil	const int magic1 = (int)random();
25321.1Skamil	const int magic2 = (int)random();
25331.1Skamil#if defined(TWAIT_HAVE_STATUS)
25341.1Skamil	int status;
25351.1Skamil#endif
25361.1Skamil
25371.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25381.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25391.1Skamil	if (child == 0) {
25401.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25411.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25421.1Skamil
25431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25451.1Skamil
25461.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
25471.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
25481.1Skamil
25491.13Schristos		DPRINTF("Before exiting of the child process\n");
25501.1Skamil		_exit(exitval);
25511.1Skamil	}
25521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25531.1Skamil
25541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25561.1Skamil
25571.1Skamil	validate_status_stopped(status, sigval);
25581.1Skamil
25591.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
25601.1Skamil	    child, getpid());
25611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
25621.1Skamil
25631.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
25641.1Skamil	    child, getpid());
25651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
25661.1Skamil
25671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25681.1Skamil	    "without signal to be sent\n");
25691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25701.1Skamil
25711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25731.1Skamil
25741.1Skamil	validate_status_exited(status, exitval);
25751.1Skamil
25761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25781.1Skamil}
25791.1Skamil
25801.1SkamilATF_TC(write_d3);
25811.1SkamilATF_TC_HEAD(write_d3, tc)
25821.1Skamil{
25831.1Skamil	atf_tc_set_md_var(tc, "descr",
25841.1Skamil	    "Verify PT_WRITE_D called three times");
25851.1Skamil}
25861.1Skamil
25871.1SkamilATF_TC_BODY(write_d3, tc)
25881.1Skamil{
25891.1Skamil	const int exitval = 5;
25901.1Skamil	const int sigval = SIGSTOP;
25911.1Skamil	pid_t child, wpid;
25921.1Skamil	int lookup_me1 = 0;
25931.1Skamil	int lookup_me2 = 0;
25941.1Skamil	int lookup_me3 = 0;
25951.1Skamil	const int magic1 = (int)random();
25961.1Skamil	const int magic2 = (int)random();
25971.1Skamil	const int magic3 = (int)random();
25981.1Skamil#if defined(TWAIT_HAVE_STATUS)
25991.1Skamil	int status;
26001.1Skamil#endif
26011.1Skamil
26021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26041.1Skamil	if (child == 0) {
26051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26071.1Skamil
26081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26101.1Skamil
26111.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26121.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26131.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
26141.1Skamil
26151.13Schristos		DPRINTF("Before exiting of the child process\n");
26161.1Skamil		_exit(exitval);
26171.1Skamil	}
26181.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26191.1Skamil
26201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26221.1Skamil
26231.1Skamil	validate_status_stopped(status, sigval);
26241.1Skamil
26251.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
26261.1Skamil	    child, getpid());
26271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
26281.1Skamil
26291.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
26301.1Skamil	    child, getpid());
26311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
26321.1Skamil
26331.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
26341.1Skamil	    child, getpid());
26351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
26361.1Skamil
26371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26381.1Skamil	    "without signal to be sent\n");
26391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26401.1Skamil
26411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26431.1Skamil
26441.1Skamil	validate_status_exited(status, exitval);
26451.1Skamil
26461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26481.1Skamil}
26491.1Skamil
26501.1SkamilATF_TC(write_d4);
26511.1SkamilATF_TC_HEAD(write_d4, tc)
26521.1Skamil{
26531.1Skamil	atf_tc_set_md_var(tc, "descr",
26541.1Skamil	    "Verify PT_WRITE_D called four times");
26551.1Skamil}
26561.1Skamil
26571.1SkamilATF_TC_BODY(write_d4, tc)
26581.1Skamil{
26591.1Skamil	const int exitval = 5;
26601.1Skamil	const int sigval = SIGSTOP;
26611.1Skamil	pid_t child, wpid;
26621.1Skamil	int lookup_me1 = 0;
26631.1Skamil	int lookup_me2 = 0;
26641.1Skamil	int lookup_me3 = 0;
26651.1Skamil	int lookup_me4 = 0;
26661.1Skamil	const int magic1 = (int)random();
26671.1Skamil	const int magic2 = (int)random();
26681.1Skamil	const int magic3 = (int)random();
26691.1Skamil	const int magic4 = (int)random();
26701.1Skamil#if defined(TWAIT_HAVE_STATUS)
26711.1Skamil	int status;
26721.1Skamil#endif
26731.1Skamil
26741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26761.1Skamil	if (child == 0) {
26771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26791.1Skamil
26801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26821.1Skamil
26831.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26841.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26851.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
26861.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
26871.1Skamil
26881.13Schristos		DPRINTF("Before exiting of the child process\n");
26891.1Skamil		_exit(exitval);
26901.1Skamil	}
26911.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26921.1Skamil
26931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26951.1Skamil
26961.1Skamil	validate_status_stopped(status, sigval);
26971.1Skamil
26981.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
26991.1Skamil	    child, getpid());
27001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
27011.1Skamil
27021.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
27031.1Skamil	    child, getpid());
27041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
27051.1Skamil
27061.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
27071.1Skamil	    child, getpid());
27081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
27091.1Skamil
27101.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
27111.1Skamil	    child, getpid());
27121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
27131.1Skamil
27141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27151.1Skamil	    "without signal to be sent\n");
27161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27171.1Skamil
27181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27201.1Skamil
27211.1Skamil	validate_status_exited(status, exitval);
27221.1Skamil
27231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27251.1Skamil}
27261.1Skamil
27271.1SkamilATF_TC(io_read_d_write_d_handshake1);
27281.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
27291.1Skamil{
27301.1Skamil	atf_tc_set_md_var(tc, "descr",
27311.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
27321.1Skamil}
27331.1Skamil
27341.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
27351.1Skamil{
27361.1Skamil	const int exitval = 5;
27371.1Skamil	const int sigval = SIGSTOP;
27381.1Skamil	pid_t child, wpid;
27391.1Skamil	uint8_t lookup_me_fromtracee = 0;
27401.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
27411.1Skamil	uint8_t lookup_me_totracee = 0;
27421.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
27431.1Skamil	struct ptrace_io_desc io_fromtracee = {
27441.1Skamil		.piod_op = PIOD_READ_D,
27451.1Skamil		.piod_offs = &lookup_me_fromtracee,
27461.1Skamil		.piod_addr = &lookup_me_fromtracee,
27471.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
27481.1Skamil	};
27491.1Skamil	struct ptrace_io_desc io_totracee = {
27501.1Skamil		.piod_op = PIOD_WRITE_D,
27511.1Skamil		.piod_offs = &lookup_me_totracee,
27521.1Skamil		.piod_addr = &lookup_me_totracee,
27531.1Skamil		.piod_len = sizeof(lookup_me_totracee)
27541.1Skamil	};
27551.1Skamil#if defined(TWAIT_HAVE_STATUS)
27561.1Skamil	int status;
27571.1Skamil#endif
27581.1Skamil
27591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27611.1Skamil	if (child == 0) {
27621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27641.1Skamil
27651.1Skamil		lookup_me_fromtracee = magic_fromtracee;
27661.1Skamil
27671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27691.1Skamil
27701.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
27711.1Skamil
27721.13Schristos		DPRINTF("Before exiting of the child process\n");
27731.1Skamil		_exit(exitval);
27741.1Skamil	}
27751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27761.1Skamil
27771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27791.1Skamil
27801.1Skamil	validate_status_stopped(status, sigval);
27811.1Skamil
27821.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
27831.1Skamil	    child, getpid());
27841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
27851.1Skamil
27861.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
27871.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
27881.1Skamil	    magic_fromtracee);
27891.1Skamil
27901.1Skamil	lookup_me_totracee = magic_totracee;
27911.1Skamil
27921.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
27931.1Skamil	    child, getpid());
27941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
27951.1Skamil
27961.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
27971.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
27981.1Skamil	    magic_totracee);
27991.1Skamil
28001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28011.1Skamil	    "without signal to be sent\n");
28021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28031.1Skamil
28041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28061.1Skamil
28071.1Skamil	validate_status_exited(status, exitval);
28081.1Skamil
28091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28111.1Skamil}
28121.1Skamil
28131.1SkamilATF_TC(io_read_d_write_d_handshake2);
28141.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
28151.1Skamil{
28161.1Skamil	atf_tc_set_md_var(tc, "descr",
28171.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
28181.1Skamil}
28191.1Skamil
28201.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
28211.1Skamil{
28221.1Skamil	const int exitval = 5;
28231.1Skamil	const int sigval = SIGSTOP;
28241.1Skamil	pid_t child, wpid;
28251.1Skamil	uint8_t lookup_me_fromtracee = 0;
28261.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
28271.1Skamil	uint8_t lookup_me_totracee = 0;
28281.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
28291.1Skamil	struct ptrace_io_desc io_fromtracee = {
28301.1Skamil		.piod_op = PIOD_READ_D,
28311.1Skamil		.piod_offs = &lookup_me_fromtracee,
28321.1Skamil		.piod_addr = &lookup_me_fromtracee,
28331.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
28341.1Skamil	};
28351.1Skamil	struct ptrace_io_desc io_totracee = {
28361.1Skamil		.piod_op = PIOD_WRITE_D,
28371.1Skamil		.piod_offs = &lookup_me_totracee,
28381.1Skamil		.piod_addr = &lookup_me_totracee,
28391.1Skamil		.piod_len = sizeof(lookup_me_totracee)
28401.1Skamil	};
28411.1Skamil#if defined(TWAIT_HAVE_STATUS)
28421.1Skamil	int status;
28431.1Skamil#endif
28441.1Skamil
28451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28471.1Skamil	if (child == 0) {
28481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28501.1Skamil
28511.1Skamil		lookup_me_fromtracee = magic_fromtracee;
28521.1Skamil
28531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28551.1Skamil
28561.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
28571.1Skamil
28581.13Schristos		DPRINTF("Before exiting of the child process\n");
28591.1Skamil		_exit(exitval);
28601.1Skamil	}
28611.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28621.1Skamil
28631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28651.1Skamil
28661.1Skamil	validate_status_stopped(status, sigval);
28671.1Skamil
28681.1Skamil	lookup_me_totracee = magic_totracee;
28691.1Skamil
28701.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
28711.1Skamil	    child, getpid());
28721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
28731.1Skamil
28741.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
28751.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
28761.1Skamil	    magic_totracee);
28771.1Skamil
28781.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
28791.1Skamil	    child, getpid());
28801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
28811.1Skamil
28821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
28831.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
28841.1Skamil	    magic_fromtracee);
28851.1Skamil
28861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28871.1Skamil	    "without signal to be sent\n");
28881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28891.1Skamil
28901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28921.1Skamil
28931.1Skamil	validate_status_exited(status, exitval);
28941.1Skamil
28951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28971.1Skamil}
28981.1Skamil
28991.1SkamilATF_TC(read_d_write_d_handshake1);
29001.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
29011.1Skamil{
29021.1Skamil	atf_tc_set_md_var(tc, "descr",
29031.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
29041.1Skamil}
29051.1Skamil
29061.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
29071.1Skamil{
29081.1Skamil	const int exitval = 5;
29091.1Skamil	const int sigval = SIGSTOP;
29101.1Skamil	pid_t child, wpid;
29111.1Skamil	int lookup_me_fromtracee = 0;
29121.1Skamil	const int magic_fromtracee = (int)random();
29131.1Skamil	int lookup_me_totracee = 0;
29141.1Skamil	const int magic_totracee = (int)random();
29151.1Skamil#if defined(TWAIT_HAVE_STATUS)
29161.1Skamil	int status;
29171.1Skamil#endif
29181.1Skamil
29191.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29201.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29211.1Skamil	if (child == 0) {
29221.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29231.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29241.1Skamil
29251.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29261.1Skamil
29271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29291.1Skamil
29301.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
29311.1Skamil
29321.13Schristos		DPRINTF("Before exiting of the child process\n");
29331.1Skamil		_exit(exitval);
29341.1Skamil	}
29351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29361.1Skamil
29371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29391.1Skamil
29401.1Skamil	validate_status_stopped(status, sigval);
29411.1Skamil
29421.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
29431.1Skamil	    child, getpid());
29441.1Skamil	errno = 0;
29451.1Skamil	lookup_me_fromtracee =
29461.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
29471.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
29481.1Skamil
29491.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29501.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
29511.1Skamil	    magic_fromtracee);
29521.1Skamil
29531.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
29541.1Skamil	    child, getpid());
29551.1Skamil	ATF_REQUIRE
29561.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
29571.1Skamil	    != -1);
29581.1Skamil
29591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29601.1Skamil	    "without signal to be sent\n");
29611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29621.1Skamil
29631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29651.1Skamil
29661.1Skamil	validate_status_exited(status, exitval);
29671.1Skamil
29681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29701.1Skamil}
29711.1Skamil
29721.1SkamilATF_TC(read_d_write_d_handshake2);
29731.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
29741.1Skamil{
29751.1Skamil	atf_tc_set_md_var(tc, "descr",
29761.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
29771.1Skamil}
29781.1Skamil
29791.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
29801.1Skamil{
29811.1Skamil	const int exitval = 5;
29821.1Skamil	const int sigval = SIGSTOP;
29831.1Skamil	pid_t child, wpid;
29841.1Skamil	int lookup_me_fromtracee = 0;
29851.1Skamil	const int magic_fromtracee = (int)random();
29861.1Skamil	int lookup_me_totracee = 0;
29871.1Skamil	const int magic_totracee = (int)random();
29881.1Skamil#if defined(TWAIT_HAVE_STATUS)
29891.1Skamil	int status;
29901.1Skamil#endif
29911.1Skamil
29921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29941.1Skamil	if (child == 0) {
29951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29971.1Skamil
29981.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29991.1Skamil
30001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30021.1Skamil
30031.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
30041.1Skamil
30051.13Schristos		DPRINTF("Before exiting of the child process\n");
30061.1Skamil		_exit(exitval);
30071.1Skamil	}
30081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30091.1Skamil
30101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30121.1Skamil
30131.1Skamil	validate_status_stopped(status, sigval);
30141.1Skamil
30151.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
30161.1Skamil	    child, getpid());
30171.1Skamil	ATF_REQUIRE
30181.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
30191.1Skamil	    != -1);
30201.1Skamil
30211.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
30221.1Skamil	    child, getpid());
30231.1Skamil	errno = 0;
30241.1Skamil	lookup_me_fromtracee =
30251.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
30261.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
30271.1Skamil
30281.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
30291.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
30301.1Skamil	    magic_fromtracee);
30311.1Skamil
30321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30331.1Skamil	    "without signal to be sent\n");
30341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30351.1Skamil
30361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30381.1Skamil
30391.1Skamil	validate_status_exited(status, exitval);
30401.1Skamil
30411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30431.1Skamil}
30441.1Skamil
30451.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
30461.1Skamilstatic int __used
30471.1Skamildummy_fn1(int a, int b, int c, int d)
30481.1Skamil{
30491.1Skamil
30501.1Skamil	a *= 1;
30511.1Skamil	b += 2;
30521.1Skamil	c -= 3;
30531.1Skamil	d /= 4;
30541.1Skamil
30551.1Skamil	return a + b * c - d;
30561.1Skamil}
30571.1Skamil
30581.1Skamilstatic int __used
30591.1Skamildummy_fn2(int a, int b, int c, int d)
30601.1Skamil{
30611.1Skamil
30621.1Skamil	a *= 4;
30631.1Skamil	b += 3;
30641.1Skamil	c -= 2;
30651.1Skamil	d /= 1;
30661.1Skamil
30671.1Skamil	return a + b * c - d;
30681.1Skamil}
30691.1Skamil
30701.1Skamilstatic int __used
30711.1Skamildummy_fn3(int a, int b, int c, int d)
30721.1Skamil{
30731.1Skamil
30741.1Skamil	a *= 10;
30751.1Skamil	b += 20;
30761.1Skamil	c -= 30;
30771.1Skamil	d /= 40;
30781.1Skamil
30791.1Skamil	return a + b * c - d;
30801.1Skamil}
30811.1Skamil
30821.1Skamilstatic int __used
30831.1Skamildummy_fn4(int a, int b, int c, int d)
30841.1Skamil{
30851.1Skamil
30861.1Skamil	a *= 40;
30871.1Skamil	b += 30;
30881.1Skamil	c -= 20;
30891.1Skamil	d /= 10;
30901.1Skamil
30911.1Skamil	return a + b * c - d;
30921.1Skamil}
30931.1Skamil
30941.1SkamilATF_TC(io_read_i1);
30951.1SkamilATF_TC_HEAD(io_read_i1, tc)
30961.1Skamil{
30971.1Skamil	atf_tc_set_md_var(tc, "descr",
30981.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
30991.1Skamil}
31001.1Skamil
31011.1SkamilATF_TC_BODY(io_read_i1, tc)
31021.1Skamil{
31031.1Skamil	const int exitval = 5;
31041.1Skamil	const int sigval = SIGSTOP;
31051.1Skamil	pid_t child, wpid;
31061.1Skamil	uint8_t lookup_me = 0;
31071.1Skamil	uint8_t magic;
31081.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31091.1Skamil	struct ptrace_io_desc io = {
31101.1Skamil		.piod_op = PIOD_READ_I,
31111.1Skamil		.piod_offs = dummy_fn1,
31121.1Skamil		.piod_addr = &lookup_me,
31131.1Skamil		.piod_len = sizeof(lookup_me)
31141.1Skamil	};
31151.1Skamil#if defined(TWAIT_HAVE_STATUS)
31161.1Skamil	int status;
31171.1Skamil#endif
31181.1Skamil
31191.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31201.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31211.1Skamil	if (child == 0) {
31221.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31231.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31241.1Skamil
31251.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31261.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31271.1Skamil
31281.13Schristos		DPRINTF("Before exiting of the child process\n");
31291.1Skamil		_exit(exitval);
31301.1Skamil	}
31311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31321.1Skamil
31331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31351.1Skamil
31361.1Skamil	validate_status_stopped(status, sigval);
31371.1Skamil
31381.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
31391.1Skamil	    child, getpid());
31401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
31411.1Skamil
31421.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
31431.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
31441.1Skamil
31451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31461.1Skamil	    "without signal to be sent\n");
31471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31481.1Skamil
31491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31511.1Skamil
31521.1Skamil	validate_status_exited(status, exitval);
31531.1Skamil
31541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31561.1Skamil}
31571.1Skamil
31581.1SkamilATF_TC(io_read_i2);
31591.1SkamilATF_TC_HEAD(io_read_i2, tc)
31601.1Skamil{
31611.1Skamil	atf_tc_set_md_var(tc, "descr",
31621.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
31631.1Skamil}
31641.1Skamil
31651.1SkamilATF_TC_BODY(io_read_i2, tc)
31661.1Skamil{
31671.1Skamil	const int exitval = 5;
31681.1Skamil	const int sigval = SIGSTOP;
31691.1Skamil	pid_t child, wpid;
31701.1Skamil	uint16_t lookup_me = 0;
31711.1Skamil	uint16_t magic;
31721.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31731.1Skamil	struct ptrace_io_desc io = {
31741.1Skamil		.piod_op = PIOD_READ_I,
31751.1Skamil		.piod_offs = dummy_fn1,
31761.1Skamil		.piod_addr = &lookup_me,
31771.1Skamil		.piod_len = sizeof(lookup_me)
31781.1Skamil	};
31791.1Skamil#if defined(TWAIT_HAVE_STATUS)
31801.1Skamil	int status;
31811.1Skamil#endif
31821.1Skamil
31831.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31841.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31851.1Skamil	if (child == 0) {
31861.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31871.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31881.1Skamil
31891.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31901.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31911.1Skamil
31921.13Schristos		DPRINTF("Before exiting of the child process\n");
31931.1Skamil		_exit(exitval);
31941.1Skamil	}
31951.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31961.1Skamil
31971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31991.1Skamil
32001.1Skamil	validate_status_stopped(status, sigval);
32011.1Skamil
32021.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32031.1Skamil	    child, getpid());
32041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32051.1Skamil
32061.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32071.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
32081.1Skamil
32091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32101.1Skamil	    "without signal to be sent\n");
32111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32121.1Skamil
32131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32151.1Skamil
32161.1Skamil	validate_status_exited(status, exitval);
32171.1Skamil
32181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32201.1Skamil}
32211.1Skamil
32221.1SkamilATF_TC(io_read_i3);
32231.1SkamilATF_TC_HEAD(io_read_i3, tc)
32241.1Skamil{
32251.1Skamil	atf_tc_set_md_var(tc, "descr",
32261.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
32271.1Skamil}
32281.1Skamil
32291.1SkamilATF_TC_BODY(io_read_i3, tc)
32301.1Skamil{
32311.1Skamil	const int exitval = 5;
32321.1Skamil	const int sigval = SIGSTOP;
32331.1Skamil	pid_t child, wpid;
32341.1Skamil	uint32_t lookup_me = 0;
32351.1Skamil	uint32_t magic;
32361.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
32371.1Skamil	struct ptrace_io_desc io = {
32381.1Skamil		.piod_op = PIOD_READ_I,
32391.1Skamil		.piod_offs = dummy_fn1,
32401.1Skamil		.piod_addr = &lookup_me,
32411.1Skamil		.piod_len = sizeof(lookup_me)
32421.1Skamil	};
32431.1Skamil#if defined(TWAIT_HAVE_STATUS)
32441.1Skamil	int status;
32451.1Skamil#endif
32461.1Skamil
32471.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32481.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32491.1Skamil	if (child == 0) {
32501.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32511.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32521.1Skamil
32531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32551.1Skamil
32561.13Schristos		DPRINTF("Before exiting of the child process\n");
32571.1Skamil		_exit(exitval);
32581.1Skamil	}
32591.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32601.1Skamil
32611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32631.1Skamil
32641.1Skamil	validate_status_stopped(status, sigval);
32651.1Skamil
32661.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32671.1Skamil	    child, getpid());
32681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32691.1Skamil
32701.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32711.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
32721.1Skamil
32731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32741.1Skamil	    "without signal to be sent\n");
32751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32761.1Skamil
32771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32791.1Skamil
32801.1Skamil	validate_status_exited(status, exitval);
32811.1Skamil
32821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32841.1Skamil}
32851.1Skamil
32861.1SkamilATF_TC(io_read_i4);
32871.1SkamilATF_TC_HEAD(io_read_i4, tc)
32881.1Skamil{
32891.1Skamil	atf_tc_set_md_var(tc, "descr",
32901.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
32911.1Skamil}
32921.1Skamil
32931.1SkamilATF_TC_BODY(io_read_i4, tc)
32941.1Skamil{
32951.1Skamil	const int exitval = 5;
32961.1Skamil	const int sigval = SIGSTOP;
32971.1Skamil	pid_t child, wpid;
32981.1Skamil	uint64_t lookup_me = 0;
32991.1Skamil	uint64_t magic;
33001.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33011.1Skamil	struct ptrace_io_desc io = {
33021.1Skamil		.piod_op = PIOD_READ_I,
33031.1Skamil		.piod_offs = dummy_fn1,
33041.1Skamil		.piod_addr = &lookup_me,
33051.1Skamil		.piod_len = sizeof(lookup_me)
33061.1Skamil	};
33071.1Skamil#if defined(TWAIT_HAVE_STATUS)
33081.1Skamil	int status;
33091.1Skamil#endif
33101.1Skamil
33111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33131.1Skamil	if (child == 0) {
33141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33161.1Skamil
33171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33191.1Skamil
33201.13Schristos		DPRINTF("Before exiting of the child process\n");
33211.1Skamil		_exit(exitval);
33221.1Skamil	}
33231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33241.1Skamil
33251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33271.1Skamil
33281.1Skamil	validate_status_stopped(status, sigval);
33291.1Skamil
33301.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33311.1Skamil	    child, getpid());
33321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
33331.1Skamil
33341.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33351.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
33361.1Skamil
33371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33381.1Skamil	    "without signal to be sent\n");
33391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33401.1Skamil
33411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33431.1Skamil
33441.1Skamil	validate_status_exited(status, exitval);
33451.1Skamil
33461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33481.1Skamil}
33491.1Skamil
33501.1SkamilATF_TC(read_i1);
33511.1SkamilATF_TC_HEAD(read_i1, tc)
33521.1Skamil{
33531.1Skamil	atf_tc_set_md_var(tc, "descr",
33541.1Skamil	    "Verify PT_READ_I called once");
33551.1Skamil}
33561.1Skamil
33571.1SkamilATF_TC_BODY(read_i1, tc)
33581.1Skamil{
33591.1Skamil	const int exitval = 5;
33601.1Skamil	const int sigval = SIGSTOP;
33611.1Skamil	pid_t child, wpid;
33621.1Skamil	int lookup_me = 0;
33631.1Skamil	int magic;
33641.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33651.1Skamil#if defined(TWAIT_HAVE_STATUS)
33661.1Skamil	int status;
33671.1Skamil#endif
33681.1Skamil
33691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33711.1Skamil	if (child == 0) {
33721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33741.1Skamil
33751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33771.1Skamil
33781.13Schristos		DPRINTF("Before exiting of the child process\n");
33791.1Skamil		_exit(exitval);
33801.1Skamil	}
33811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33821.1Skamil
33831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33851.1Skamil
33861.1Skamil	validate_status_stopped(status, sigval);
33871.1Skamil
33881.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33891.1Skamil	    child, getpid());
33901.1Skamil	errno = 0;
33911.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
33921.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33931.1Skamil
33941.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33951.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
33961.1Skamil
33971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33981.1Skamil	    "without signal to be sent\n");
33991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34001.1Skamil
34011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34031.1Skamil
34041.1Skamil	validate_status_exited(status, exitval);
34051.1Skamil
34061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34081.1Skamil}
34091.1Skamil
34101.1SkamilATF_TC(read_i2);
34111.1SkamilATF_TC_HEAD(read_i2, tc)
34121.1Skamil{
34131.1Skamil	atf_tc_set_md_var(tc, "descr",
34141.1Skamil	    "Verify PT_READ_I called twice");
34151.1Skamil}
34161.1Skamil
34171.1SkamilATF_TC_BODY(read_i2, tc)
34181.1Skamil{
34191.1Skamil	const int exitval = 5;
34201.1Skamil	const int sigval = SIGSTOP;
34211.1Skamil	pid_t child, wpid;
34221.1Skamil	int lookup_me1 = 0;
34231.1Skamil	int lookup_me2 = 0;
34241.1Skamil	int magic1;
34251.1Skamil	int magic2;
34261.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
34271.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
34281.1Skamil#if defined(TWAIT_HAVE_STATUS)
34291.1Skamil	int status;
34301.1Skamil#endif
34311.1Skamil
34321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34341.1Skamil	if (child == 0) {
34351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34371.1Skamil
34381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34401.1Skamil
34411.13Schristos		DPRINTF("Before exiting of the child process\n");
34421.1Skamil		_exit(exitval);
34431.1Skamil	}
34441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34451.1Skamil
34461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34481.1Skamil
34491.1Skamil	validate_status_stopped(status, sigval);
34501.1Skamil
34511.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
34521.1Skamil	    child, getpid());
34531.1Skamil	errno = 0;
34541.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
34551.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34561.1Skamil
34571.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
34581.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
34591.1Skamil
34601.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
34611.1Skamil	    child, getpid());
34621.1Skamil	errno = 0;
34631.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
34641.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34651.1Skamil
34661.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
34671.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
34681.1Skamil
34691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34701.1Skamil	    "without signal to be sent\n");
34711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34721.1Skamil
34731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34751.1Skamil
34761.1Skamil	validate_status_exited(status, exitval);
34771.1Skamil
34781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34801.1Skamil}
34811.1Skamil
34821.1SkamilATF_TC(read_i3);
34831.1SkamilATF_TC_HEAD(read_i3, tc)
34841.1Skamil{
34851.1Skamil	atf_tc_set_md_var(tc, "descr",
34861.1Skamil	    "Verify PT_READ_I called three times");
34871.1Skamil}
34881.1Skamil
34891.1SkamilATF_TC_BODY(read_i3, tc)
34901.1Skamil{
34911.1Skamil	const int exitval = 5;
34921.1Skamil	const int sigval = SIGSTOP;
34931.1Skamil	pid_t child, wpid;
34941.1Skamil	int lookup_me1 = 0;
34951.1Skamil	int lookup_me2 = 0;
34961.1Skamil	int lookup_me3 = 0;
34971.1Skamil	int magic1;
34981.1Skamil	int magic2;
34991.1Skamil	int magic3;
35001.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35011.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
35021.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
35031.1Skamil#if defined(TWAIT_HAVE_STATUS)
35041.1Skamil	int status;
35051.1Skamil#endif
35061.1Skamil
35071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35091.1Skamil	if (child == 0) {
35101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35121.1Skamil
35131.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35141.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35151.1Skamil
35161.13Schristos		DPRINTF("Before exiting of the child process\n");
35171.1Skamil		_exit(exitval);
35181.1Skamil	}
35191.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35201.1Skamil
35211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35231.1Skamil
35241.1Skamil	validate_status_stopped(status, sigval);
35251.1Skamil
35261.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
35271.1Skamil	    child, getpid());
35281.1Skamil	errno = 0;
35291.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
35301.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35311.1Skamil
35321.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
35331.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
35341.1Skamil
35351.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
35361.1Skamil	    child, getpid());
35371.1Skamil	errno = 0;
35381.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
35391.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35401.1Skamil
35411.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
35421.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
35431.1Skamil
35441.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
35451.1Skamil	    child, getpid());
35461.1Skamil	errno = 0;
35471.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
35481.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35491.1Skamil
35501.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
35511.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
35521.1Skamil
35531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35541.1Skamil	    "without signal to be sent\n");
35551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35561.1Skamil
35571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35591.1Skamil
35601.1Skamil	validate_status_exited(status, exitval);
35611.1Skamil
35621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35641.1Skamil}
35651.1Skamil
35661.1SkamilATF_TC(read_i4);
35671.1SkamilATF_TC_HEAD(read_i4, tc)
35681.1Skamil{
35691.1Skamil	atf_tc_set_md_var(tc, "descr",
35701.1Skamil	    "Verify PT_READ_I called four times");
35711.1Skamil}
35721.1Skamil
35731.1SkamilATF_TC_BODY(read_i4, tc)
35741.1Skamil{
35751.1Skamil	const int exitval = 5;
35761.1Skamil	const int sigval = SIGSTOP;
35771.1Skamil	pid_t child, wpid;
35781.1Skamil	int lookup_me1 = 0;
35791.1Skamil	int lookup_me2 = 0;
35801.1Skamil	int lookup_me3 = 0;
35811.1Skamil	int lookup_me4 = 0;
35821.1Skamil	int magic1;
35831.1Skamil	int magic2;
35841.1Skamil	int magic3;
35851.1Skamil	int magic4;
35861.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35871.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
35881.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
35891.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
35901.1Skamil#if defined(TWAIT_HAVE_STATUS)
35911.1Skamil	int status;
35921.1Skamil#endif
35931.1Skamil
35941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35961.1Skamil	if (child == 0) {
35971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35991.1Skamil
36001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36021.1Skamil
36031.13Schristos		DPRINTF("Before exiting of the child process\n");
36041.1Skamil		_exit(exitval);
36051.1Skamil	}
36061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36071.1Skamil
36081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36101.1Skamil
36111.1Skamil	validate_status_stopped(status, sigval);
36121.1Skamil
36131.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
36141.1Skamil	    child, getpid());
36151.1Skamil	errno = 0;
36161.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
36171.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36181.1Skamil
36191.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
36201.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
36211.1Skamil
36221.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
36231.1Skamil	    child, getpid());
36241.1Skamil	errno = 0;
36251.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
36261.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36271.1Skamil
36281.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
36291.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
36301.1Skamil
36311.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
36321.1Skamil	    child, getpid());
36331.1Skamil	errno = 0;
36341.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
36351.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36361.1Skamil
36371.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
36381.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
36391.1Skamil
36401.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
36411.1Skamil	    child, getpid());
36421.1Skamil	errno = 0;
36431.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
36441.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36451.1Skamil
36461.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
36471.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
36481.1Skamil
36491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36501.1Skamil	    "without signal to be sent\n");
36511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36521.1Skamil
36531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36551.1Skamil
36561.1Skamil	validate_status_exited(status, exitval);
36571.1Skamil
36581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36601.1Skamil}
36611.1Skamil
36621.1Skamil#if defined(HAVE_GPREGS)
36631.1SkamilATF_TC(regs1);
36641.1SkamilATF_TC_HEAD(regs1, tc)
36651.1Skamil{
36661.1Skamil	atf_tc_set_md_var(tc, "descr",
36671.1Skamil	    "Verify plain PT_GETREGS call without further steps");
36681.1Skamil}
36691.1Skamil
36701.1SkamilATF_TC_BODY(regs1, tc)
36711.1Skamil{
36721.1Skamil	const int exitval = 5;
36731.1Skamil	const int sigval = SIGSTOP;
36741.1Skamil	pid_t child, wpid;
36751.1Skamil#if defined(TWAIT_HAVE_STATUS)
36761.1Skamil	int status;
36771.1Skamil#endif
36781.1Skamil	struct reg r;
36791.1Skamil
36801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36821.1Skamil	if (child == 0) {
36831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36851.1Skamil
36861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36881.1Skamil
36891.13Schristos		DPRINTF("Before exiting of the child process\n");
36901.1Skamil		_exit(exitval);
36911.1Skamil	}
36921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36931.1Skamil
36941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36961.1Skamil
36971.1Skamil	validate_status_stopped(status, sigval);
36981.1Skamil
36991.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37011.1Skamil
37021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37031.1Skamil	    "without signal to be sent\n");
37041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37051.1Skamil
37061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37081.1Skamil
37091.1Skamil	validate_status_exited(status, exitval);
37101.1Skamil
37111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37131.1Skamil}
37141.1Skamil#endif
37151.1Skamil
37161.1Skamil#if defined(HAVE_GPREGS)
37171.1SkamilATF_TC(regs2);
37181.1SkamilATF_TC_HEAD(regs2, tc)
37191.1Skamil{
37201.1Skamil	atf_tc_set_md_var(tc, "descr",
37211.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
37221.1Skamil}
37231.1Skamil
37241.1SkamilATF_TC_BODY(regs2, tc)
37251.1Skamil{
37261.1Skamil	const int exitval = 5;
37271.1Skamil	const int sigval = SIGSTOP;
37281.1Skamil	pid_t child, wpid;
37291.1Skamil#if defined(TWAIT_HAVE_STATUS)
37301.1Skamil	int status;
37311.1Skamil#endif
37321.1Skamil	struct reg r;
37331.1Skamil
37341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37361.1Skamil	if (child == 0) {
37371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37391.1Skamil
37401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37421.1Skamil
37431.13Schristos		DPRINTF("Before exiting of the child process\n");
37441.1Skamil		_exit(exitval);
37451.1Skamil	}
37461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37471.1Skamil
37481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37501.1Skamil
37511.1Skamil	validate_status_stopped(status, sigval);
37521.1Skamil
37531.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37551.1Skamil
37561.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
37571.1Skamil
37581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37591.1Skamil	    "without signal to be sent\n");
37601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37611.1Skamil
37621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37641.1Skamil
37651.1Skamil	validate_status_exited(status, exitval);
37661.1Skamil
37671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37691.1Skamil}
37701.1Skamil#endif
37711.1Skamil
37721.1Skamil#if defined(HAVE_GPREGS)
37731.1SkamilATF_TC(regs3);
37741.1SkamilATF_TC_HEAD(regs3, tc)
37751.1Skamil{
37761.1Skamil	atf_tc_set_md_var(tc, "descr",
37771.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
37781.1Skamil}
37791.1Skamil
37801.1SkamilATF_TC_BODY(regs3, tc)
37811.1Skamil{
37821.1Skamil	const int exitval = 5;
37831.1Skamil	const int sigval = SIGSTOP;
37841.1Skamil	pid_t child, wpid;
37851.1Skamil#if defined(TWAIT_HAVE_STATUS)
37861.1Skamil	int status;
37871.1Skamil#endif
37881.1Skamil	struct reg r;
37891.1Skamil
37901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37921.1Skamil	if (child == 0) {
37931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37951.1Skamil
37961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37981.1Skamil
37991.13Schristos		DPRINTF("Before exiting of the child process\n");
38001.1Skamil		_exit(exitval);
38011.1Skamil	}
38021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38031.1Skamil
38041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38061.1Skamil
38071.1Skamil	validate_status_stopped(status, sigval);
38081.1Skamil
38091.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38111.1Skamil
38121.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
38131.1Skamil
38141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38151.1Skamil	    "without signal to be sent\n");
38161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38171.1Skamil
38181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38201.1Skamil
38211.1Skamil	validate_status_exited(status, exitval);
38221.1Skamil
38231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38251.1Skamil}
38261.1Skamil#endif
38271.1Skamil
38281.1Skamil#if defined(HAVE_GPREGS)
38291.1SkamilATF_TC(regs4);
38301.1SkamilATF_TC_HEAD(regs4, tc)
38311.1Skamil{
38321.1Skamil	atf_tc_set_md_var(tc, "descr",
38331.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
38341.1Skamil}
38351.1Skamil
38361.1SkamilATF_TC_BODY(regs4, tc)
38371.1Skamil{
38381.1Skamil	const int exitval = 5;
38391.1Skamil	const int sigval = SIGSTOP;
38401.1Skamil	pid_t child, wpid;
38411.1Skamil#if defined(TWAIT_HAVE_STATUS)
38421.1Skamil	int status;
38431.1Skamil#endif
38441.1Skamil	struct reg r;
38451.1Skamil
38461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38481.1Skamil	if (child == 0) {
38491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38511.1Skamil
38521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38541.1Skamil
38551.13Schristos		DPRINTF("Before exiting of the child process\n");
38561.1Skamil		_exit(exitval);
38571.1Skamil	}
38581.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38591.1Skamil
38601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38621.1Skamil
38631.1Skamil	validate_status_stopped(status, sigval);
38641.1Skamil
38651.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38671.1Skamil
38681.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
38691.1Skamil
38701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38711.1Skamil	    "without signal to be sent\n");
38721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38731.1Skamil
38741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38761.1Skamil
38771.1Skamil	validate_status_exited(status, exitval);
38781.1Skamil
38791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38811.1Skamil}
38821.1Skamil#endif
38831.1Skamil
38841.1Skamil#if defined(HAVE_GPREGS)
38851.1SkamilATF_TC(regs5);
38861.1SkamilATF_TC_HEAD(regs5, tc)
38871.1Skamil{
38881.1Skamil	atf_tc_set_md_var(tc, "descr",
38891.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
38901.1Skamil}
38911.1Skamil
38921.1SkamilATF_TC_BODY(regs5, tc)
38931.1Skamil{
38941.1Skamil	const int exitval = 5;
38951.1Skamil	const int sigval = SIGSTOP;
38961.1Skamil	pid_t child, wpid;
38971.1Skamil#if defined(TWAIT_HAVE_STATUS)
38981.1Skamil	int status;
38991.1Skamil#endif
39001.1Skamil	struct reg r;
39011.1Skamil
39021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39041.1Skamil	if (child == 0) {
39051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39071.1Skamil
39081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39101.1Skamil
39111.13Schristos		DPRINTF("Before exiting of the child process\n");
39121.1Skamil		_exit(exitval);
39131.1Skamil	}
39141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39151.1Skamil
39161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39181.1Skamil
39191.1Skamil	validate_status_stopped(status, sigval);
39201.1Skamil
39211.13Schristos	DPRINTF("Call GETREGS for the child process\n");
39221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39231.1Skamil
39241.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
39251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39261.1Skamil
39271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39281.1Skamil	    "without signal to be sent\n");
39291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
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_exited(status, exitval);
39351.1Skamil
39361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39381.1Skamil}
39391.1Skamil#endif
39401.1Skamil
39411.1Skamil#if defined(HAVE_FPREGS)
39421.1SkamilATF_TC(fpregs1);
39431.1SkamilATF_TC_HEAD(fpregs1, tc)
39441.1Skamil{
39451.1Skamil	atf_tc_set_md_var(tc, "descr",
39461.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
39471.1Skamil}
39481.1Skamil
39491.1SkamilATF_TC_BODY(fpregs1, tc)
39501.1Skamil{
39511.1Skamil	const int exitval = 5;
39521.1Skamil	const int sigval = SIGSTOP;
39531.1Skamil	pid_t child, wpid;
39541.1Skamil#if defined(TWAIT_HAVE_STATUS)
39551.1Skamil	int status;
39561.1Skamil#endif
39571.1Skamil	struct fpreg r;
39581.1Skamil
39591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39611.1Skamil	if (child == 0) {
39621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39641.1Skamil
39651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39671.1Skamil
39681.13Schristos		DPRINTF("Before exiting of the child process\n");
39691.1Skamil		_exit(exitval);
39701.1Skamil	}
39711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39721.1Skamil
39731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39751.1Skamil
39761.1Skamil	validate_status_stopped(status, sigval);
39771.1Skamil
39781.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
39791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
39801.1Skamil
39811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39821.1Skamil	    "without signal to be sent\n");
39831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39841.1Skamil
39851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39871.1Skamil
39881.1Skamil	validate_status_exited(status, exitval);
39891.1Skamil
39901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39921.1Skamil}
39931.1Skamil#endif
39941.1Skamil
39951.1Skamil#if defined(HAVE_FPREGS)
39961.1SkamilATF_TC(fpregs2);
39971.1SkamilATF_TC_HEAD(fpregs2, tc)
39981.1Skamil{
39991.1Skamil	atf_tc_set_md_var(tc, "descr",
40001.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
40011.1Skamil	    "regs");
40021.1Skamil}
40031.1Skamil
40041.1SkamilATF_TC_BODY(fpregs2, tc)
40051.1Skamil{
40061.1Skamil	const int exitval = 5;
40071.1Skamil	const int sigval = SIGSTOP;
40081.1Skamil	pid_t child, wpid;
40091.1Skamil#if defined(TWAIT_HAVE_STATUS)
40101.1Skamil	int status;
40111.1Skamil#endif
40121.1Skamil	struct fpreg r;
40131.1Skamil
40141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40161.1Skamil	if (child == 0) {
40171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40191.1Skamil
40201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40221.1Skamil
40231.13Schristos		DPRINTF("Before exiting of the child process\n");
40241.1Skamil		_exit(exitval);
40251.1Skamil	}
40261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40271.1Skamil
40281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40301.1Skamil
40311.1Skamil	validate_status_stopped(status, sigval);
40321.1Skamil
40331.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
40341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
40351.1Skamil
40361.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
40371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
40381.1Skamil
40391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40401.1Skamil	    "without signal to be sent\n");
40411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40421.1Skamil
40431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40451.1Skamil
40461.1Skamil	validate_status_exited(status, exitval);
40471.1Skamil
40481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40501.1Skamil}
40511.1Skamil#endif
40521.1Skamil
40531.1Skamil#if defined(PT_STEP)
40541.1Skamilstatic void
40551.2Skamilptrace_step(int N, int setstep)
40561.1Skamil{
40571.1Skamil	const int exitval = 5;
40581.1Skamil	const int sigval = SIGSTOP;
40591.1Skamil	pid_t child, wpid;
40601.1Skamil#if defined(TWAIT_HAVE_STATUS)
40611.1Skamil	int status;
40621.1Skamil#endif
40631.1Skamil	int happy;
40641.1Skamil
40651.1Skamil#if defined(__arm__)
40661.1Skamil	/* PT_STEP not supported on arm 32-bit */
40671.1Skamil	atf_tc_expect_fail("PR kern/52119");
40681.1Skamil#endif
40691.1Skamil
40701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40721.1Skamil	if (child == 0) {
40731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40751.1Skamil
40761.1Skamil		happy = check_happy(999);
40771.1Skamil
40781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40801.1Skamil
40811.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
40821.1Skamil
40831.13Schristos		DPRINTF("Before exiting of the child process\n");
40841.1Skamil		_exit(exitval);
40851.1Skamil	}
40861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40871.1Skamil
40881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40901.1Skamil
40911.1Skamil	validate_status_stopped(status, sigval);
40921.1Skamil
40931.1Skamil	while (N --> 0) {
40941.2Skamil		if (setstep) {
40951.13Schristos			DPRINTF("Before resuming the child process where it "
40961.2Skamil			    "left off and without signal to be sent (use "
40971.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
40981.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
40991.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
41001.2Skamil			    != -1);
41011.2Skamil		} else {
41021.13Schristos			DPRINTF("Before resuming the child process where it "
41031.2Skamil			    "left off and without signal to be sent (use "
41041.2Skamil			    "PT_STEP)\n");
41051.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
41061.2Skamil			    != -1);
41071.2Skamil		}
41081.1Skamil
41091.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41101.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
41111.1Skamil		    child);
41121.1Skamil
41131.1Skamil		validate_status_stopped(status, SIGTRAP);
41141.2Skamil
41151.2Skamil		if (setstep) {
41161.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
41171.2Skamil		}
41181.1Skamil	}
41191.1Skamil
41201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41211.1Skamil	    "without signal to be sent\n");
41221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41231.1Skamil
41241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41261.1Skamil
41271.1Skamil	validate_status_exited(status, exitval);
41281.1Skamil
41291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41311.1Skamil}
41321.1Skamil#endif
41331.1Skamil
41341.1Skamil#if defined(PT_STEP)
41351.1SkamilATF_TC(step1);
41361.1SkamilATF_TC_HEAD(step1, tc)
41371.1Skamil{
41381.1Skamil	atf_tc_set_md_var(tc, "descr",
41391.1Skamil	    "Verify single PT_STEP call");
41401.1Skamil}
41411.1Skamil
41421.1SkamilATF_TC_BODY(step1, tc)
41431.1Skamil{
41441.2Skamil	ptrace_step(1, 0);
41451.1Skamil}
41461.1Skamil#endif
41471.1Skamil
41481.1Skamil#if defined(PT_STEP)
41491.1SkamilATF_TC(step2);
41501.1SkamilATF_TC_HEAD(step2, tc)
41511.1Skamil{
41521.1Skamil	atf_tc_set_md_var(tc, "descr",
41531.1Skamil	    "Verify PT_STEP called twice");
41541.1Skamil}
41551.1Skamil
41561.1SkamilATF_TC_BODY(step2, tc)
41571.1Skamil{
41581.2Skamil	ptrace_step(2, 0);
41591.1Skamil}
41601.1Skamil#endif
41611.1Skamil
41621.1Skamil#if defined(PT_STEP)
41631.1SkamilATF_TC(step3);
41641.1SkamilATF_TC_HEAD(step3, tc)
41651.1Skamil{
41661.1Skamil	atf_tc_set_md_var(tc, "descr",
41671.1Skamil	    "Verify PT_STEP called three times");
41681.1Skamil}
41691.1Skamil
41701.1SkamilATF_TC_BODY(step3, tc)
41711.1Skamil{
41721.2Skamil	ptrace_step(3, 0);
41731.1Skamil}
41741.1Skamil#endif
41751.1Skamil
41761.1Skamil#if defined(PT_STEP)
41771.1SkamilATF_TC(step4);
41781.1SkamilATF_TC_HEAD(step4, tc)
41791.1Skamil{
41801.1Skamil	atf_tc_set_md_var(tc, "descr",
41811.1Skamil	    "Verify PT_STEP called four times");
41821.1Skamil}
41831.1Skamil
41841.1SkamilATF_TC_BODY(step4, tc)
41851.1Skamil{
41861.2Skamil	ptrace_step(4, 0);
41871.2Skamil}
41881.2Skamil#endif
41891.2Skamil
41901.2Skamil#if defined(PT_STEP)
41911.2SkamilATF_TC(setstep1);
41921.2SkamilATF_TC_HEAD(setstep1, tc)
41931.2Skamil{
41941.2Skamil	atf_tc_set_md_var(tc, "descr",
41951.2Skamil	    "Verify single PT_SETSTEP call");
41961.2Skamil}
41971.2Skamil
41981.2SkamilATF_TC_BODY(setstep1, tc)
41991.2Skamil{
42001.2Skamil	ptrace_step(1, 1);
42011.2Skamil}
42021.2Skamil#endif
42031.2Skamil
42041.2Skamil#if defined(PT_STEP)
42051.2SkamilATF_TC(setstep2);
42061.2SkamilATF_TC_HEAD(setstep2, tc)
42071.2Skamil{
42081.2Skamil	atf_tc_set_md_var(tc, "descr",
42091.2Skamil	    "Verify PT_SETSTEP called twice");
42101.2Skamil}
42111.2Skamil
42121.2SkamilATF_TC_BODY(setstep2, tc)
42131.2Skamil{
42141.2Skamil	ptrace_step(2, 1);
42151.2Skamil}
42161.2Skamil#endif
42171.2Skamil
42181.2Skamil#if defined(PT_STEP)
42191.2SkamilATF_TC(setstep3);
42201.2SkamilATF_TC_HEAD(setstep3, tc)
42211.2Skamil{
42221.2Skamil	atf_tc_set_md_var(tc, "descr",
42231.2Skamil	    "Verify PT_SETSTEP called three times");
42241.2Skamil}
42251.2Skamil
42261.2SkamilATF_TC_BODY(setstep3, tc)
42271.2Skamil{
42281.2Skamil	ptrace_step(3, 1);
42291.2Skamil}
42301.2Skamil#endif
42311.2Skamil
42321.2Skamil#if defined(PT_STEP)
42331.2SkamilATF_TC(setstep4);
42341.2SkamilATF_TC_HEAD(setstep4, tc)
42351.2Skamil{
42361.2Skamil	atf_tc_set_md_var(tc, "descr",
42371.2Skamil	    "Verify PT_SETSTEP called four times");
42381.2Skamil}
42391.2Skamil
42401.2SkamilATF_TC_BODY(setstep4, tc)
42411.2Skamil{
42421.2Skamil	ptrace_step(4, 1);
42431.1Skamil}
42441.1Skamil#endif
42451.1Skamil
42461.1SkamilATF_TC(kill1);
42471.1SkamilATF_TC_HEAD(kill1, tc)
42481.1Skamil{
42491.1Skamil	atf_tc_set_md_var(tc, "descr",
42501.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
42511.1Skamil}
42521.1Skamil
42531.1SkamilATF_TC_BODY(kill1, tc)
42541.1Skamil{
42551.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
42561.1Skamil	pid_t child, wpid;
42571.1Skamil#if defined(TWAIT_HAVE_STATUS)
42581.1Skamil	int status;
42591.1Skamil#endif
42601.1Skamil
42611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42631.1Skamil	if (child == 0) {
42641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42661.1Skamil
42671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42691.1Skamil
42701.1Skamil		/* NOTREACHED */
42711.1Skamil		FORKEE_ASSERTX(0 &&
42721.1Skamil		    "Child should be terminated by a signal from its parent");
42731.1Skamil	}
42741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42751.1Skamil
42761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42781.1Skamil
42791.1Skamil	validate_status_stopped(status, sigval);
42801.1Skamil
42811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42821.1Skamil	    "without signal to be sent\n");
42831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
42841.1Skamil
42851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42871.1Skamil
42881.1Skamil	validate_status_signaled(status, sigsent, 0);
42891.1Skamil
42901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42921.1Skamil}
42931.1Skamil
42941.1SkamilATF_TC(kill2);
42951.1SkamilATF_TC_HEAD(kill2, tc)
42961.1Skamil{
42971.1Skamil	atf_tc_set_md_var(tc, "descr",
42981.1Skamil	    "Verify that PT_KILL terminates child");
42991.1Skamil}
43001.1Skamil
43011.1SkamilATF_TC_BODY(kill2, tc)
43021.1Skamil{
43031.1Skamil	const int sigval = SIGSTOP;
43041.1Skamil	pid_t child, wpid;
43051.1Skamil#if defined(TWAIT_HAVE_STATUS)
43061.1Skamil	int status;
43071.1Skamil#endif
43081.1Skamil
43091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43111.1Skamil	if (child == 0) {
43121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43141.1Skamil
43151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43171.1Skamil
43181.1Skamil		/* NOTREACHED */
43191.1Skamil		FORKEE_ASSERTX(0 &&
43201.1Skamil		    "Child should be terminated by a signal from its parent");
43211.1Skamil	}
43221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43231.1Skamil
43241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43261.1Skamil
43271.1Skamil	validate_status_stopped(status, sigval);
43281.1Skamil
43291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43301.1Skamil	    "without signal to be sent\n");
43311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
43321.1Skamil
43331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43351.1Skamil
43361.1Skamil	validate_status_signaled(status, SIGKILL, 0);
43371.1Skamil
43381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43401.1Skamil}
43411.1Skamil
43421.1SkamilATF_TC(lwpinfo1);
43431.1SkamilATF_TC_HEAD(lwpinfo1, tc)
43441.1Skamil{
43451.1Skamil	atf_tc_set_md_var(tc, "descr",
43461.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
43471.1Skamil}
43481.1Skamil
43491.1SkamilATF_TC_BODY(lwpinfo1, tc)
43501.1Skamil{
43511.1Skamil	const int exitval = 5;
43521.1Skamil	const int sigval = SIGSTOP;
43531.1Skamil	pid_t child, wpid;
43541.1Skamil#if defined(TWAIT_HAVE_STATUS)
43551.1Skamil	int status;
43561.1Skamil#endif
43571.1Skamil	struct ptrace_lwpinfo info = {0, 0};
43581.1Skamil
43591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43611.1Skamil	if (child == 0) {
43621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43641.1Skamil
43651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43671.1Skamil
43681.13Schristos		DPRINTF("Before exiting of the child process\n");
43691.1Skamil		_exit(exitval);
43701.1Skamil	}
43711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43721.1Skamil
43731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43751.1Skamil
43761.1Skamil	validate_status_stopped(status, sigval);
43771.1Skamil
43781.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
43791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
43801.1Skamil
43811.13Schristos	DPRINTF("Assert that there exists a thread\n");
43821.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
43831.1Skamil
43841.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
43851.1Skamil	    info.pl_lwpid);
43861.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
43871.1Skamil	    "Received event %d != expected event %d",
43881.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
43891.1Skamil
43901.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
43911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
43921.1Skamil
43931.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
43941.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
43951.1Skamil
43961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43971.1Skamil	    "without signal to be sent\n");
43981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43991.1Skamil
44001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44021.1Skamil
44031.1Skamil	validate_status_exited(status, exitval);
44041.1Skamil
44051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44071.1Skamil}
44081.1Skamil
44091.1Skamil#if defined(TWAIT_HAVE_PID)
44101.1SkamilATF_TC(lwpinfo2);
44111.1SkamilATF_TC_HEAD(lwpinfo2, tc)
44121.1Skamil{
44131.1Skamil	atf_tc_set_md_var(tc, "descr",
44141.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
44151.1Skamil	    "tracer)");
44161.1Skamil}
44171.1Skamil
44181.1SkamilATF_TC_BODY(lwpinfo2, tc)
44191.1Skamil{
44201.1Skamil	struct msg_fds parent_tracee, parent_tracer;
44211.1Skamil	const int exitval_tracee = 5;
44221.1Skamil	const int exitval_tracer = 10;
44231.1Skamil	pid_t tracee, tracer, wpid;
44241.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
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("Spawn tracee\n");
44311.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
44321.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
44331.1Skamil	tracee = atf_utils_fork();
44341.1Skamil	if (tracee == 0) {
44351.1Skamil
44361.1Skamil		/* Wait for message from the parent */
44371.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
44381.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
44391.1Skamil
44401.1Skamil		_exit(exitval_tracee);
44411.1Skamil	}
44421.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
44431.1Skamil
44441.13Schristos	DPRINTF("Spawn debugger\n");
44451.1Skamil	tracer = atf_utils_fork();
44461.1Skamil	if (tracer == 0) {
44471.1Skamil		/* No IPC to communicate with the child */
44481.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
44491.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
44501.1Skamil
44511.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
44521.1Skamil		FORKEE_REQUIRE_SUCCESS(
44531.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44541.1Skamil
44551.1Skamil		forkee_status_stopped(status, SIGSTOP);
44561.1Skamil
44571.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44581.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44591.1Skamil		    != -1);
44601.1Skamil
44611.13Schristos		DPRINTF("Assert that there exists a thread\n");
44621.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
44631.1Skamil
44641.13Schristos		DPRINTF("Assert that lwp thread %d received event "
44651.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
44661.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
44671.1Skamil
44681.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44691.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44701.1Skamil		    != -1);
44711.1Skamil
44721.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
44731.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
44741.1Skamil
44751.1Skamil		/* Resume tracee with PT_CONTINUE */
44761.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
44771.1Skamil
44781.1Skamil		/* Inform parent that tracer has attached to tracee */
44791.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
44801.1Skamil		/* Wait for parent */
44811.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
44821.1Skamil
44831.1Skamil		/* Wait for tracee and assert that it exited */
44841.1Skamil		FORKEE_REQUIRE_SUCCESS(
44851.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44861.1Skamil
44871.1Skamil		forkee_status_exited(status, exitval_tracee);
44881.1Skamil
44891.13Schristos		DPRINTF("Before exiting of the tracer process\n");
44901.1Skamil		_exit(exitval_tracer);
44911.1Skamil	}
44921.1Skamil
44931.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
44941.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
44951.1Skamil
44961.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
44971.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
44981.1Skamil
44991.13Schristos	DPRINTF("Detect that tracee is zombie\n");
45001.1Skamil	await_zombie(tracee);
45011.1Skamil
45021.13Schristos	DPRINTF("Assert that there is no status about tracee - "
45031.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
45041.1Skamil	TWAIT_REQUIRE_SUCCESS(
45051.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
45061.1Skamil
45071.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
45081.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
45091.1Skamil
45101.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
45111.1Skamil	    TWAIT_FNAME);
45121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
45131.1Skamil	    tracer);
45141.1Skamil
45151.1Skamil	validate_status_exited(status, exitval_tracer);
45161.1Skamil
45171.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
45181.1Skamil	    TWAIT_FNAME);
45191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
45201.1Skamil	    tracee);
45211.1Skamil
45221.1Skamil	validate_status_exited(status, exitval_tracee);
45231.1Skamil
45241.1Skamil	msg_close(&parent_tracer);
45251.1Skamil	msg_close(&parent_tracee);
45261.1Skamil}
45271.1Skamil#endif
45281.1Skamil
45291.1SkamilATF_TC(siginfo1);
45301.1SkamilATF_TC_HEAD(siginfo1, tc)
45311.1Skamil{
45321.1Skamil	atf_tc_set_md_var(tc, "descr",
45331.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
45341.1Skamil}
45351.1Skamil
45361.1SkamilATF_TC_BODY(siginfo1, tc)
45371.1Skamil{
45381.1Skamil	const int exitval = 5;
45391.1Skamil	const int sigval = SIGTRAP;
45401.1Skamil	pid_t child, wpid;
45411.1Skamil#if defined(TWAIT_HAVE_STATUS)
45421.1Skamil	int status;
45431.1Skamil#endif
45441.1Skamil	struct ptrace_siginfo info;
45451.1Skamil	memset(&info, 0, sizeof(info));
45461.1Skamil
45471.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
45481.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
45491.1Skamil	if (child == 0) {
45501.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
45511.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
45521.1Skamil
45531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
45541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
45551.1Skamil
45561.13Schristos		DPRINTF("Before exiting of the child process\n");
45571.1Skamil		_exit(exitval);
45581.1Skamil	}
45591.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
45601.1Skamil
45611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45631.1Skamil
45641.1Skamil	validate_status_stopped(status, sigval);
45651.1Skamil
45661.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
45671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
45681.1Skamil
45691.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
45701.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
45711.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
45721.1Skamil	    info.psi_siginfo.si_errno);
45731.1Skamil
45741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
45751.1Skamil	    "without signal to be sent\n");
45761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
45771.1Skamil
45781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45801.1Skamil
45811.1Skamil	validate_status_exited(status, exitval);
45821.1Skamil
45831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45841.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
45851.1Skamil}
45861.1Skamil
45871.1SkamilATF_TC(siginfo2);
45881.1SkamilATF_TC_HEAD(siginfo2, tc)
45891.1Skamil{
45901.1Skamil	atf_tc_set_md_var(tc, "descr",
45911.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
45921.1Skamil	    "modification of SIGINT from tracee");
45931.1Skamil}
45941.1Skamil
45951.1Skamilstatic int siginfo2_caught = 0;
45961.1Skamil
45971.1Skamilstatic void
45981.1Skamilsiginfo2_sighandler(int sig)
45991.1Skamil{
46001.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
46011.1Skamil
46021.1Skamil	++siginfo2_caught;
46031.1Skamil}
46041.1Skamil
46051.1SkamilATF_TC_BODY(siginfo2, tc)
46061.1Skamil{
46071.1Skamil	const int exitval = 5;
46081.1Skamil	const int sigval = SIGINT;
46091.1Skamil	pid_t child, wpid;
46101.1Skamil	struct sigaction sa;
46111.1Skamil#if defined(TWAIT_HAVE_STATUS)
46121.1Skamil	int status;
46131.1Skamil#endif
46141.1Skamil	struct ptrace_siginfo info;
46151.1Skamil	memset(&info, 0, sizeof(info));
46161.1Skamil
46171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46191.1Skamil	if (child == 0) {
46201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46221.1Skamil
46231.1Skamil		sa.sa_handler = siginfo2_sighandler;
46241.1Skamil		sa.sa_flags = SA_SIGINFO;
46251.1Skamil		sigemptyset(&sa.sa_mask);
46261.1Skamil
46271.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
46281.1Skamil
46291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46311.1Skamil
46321.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
46331.1Skamil
46341.13Schristos		DPRINTF("Before exiting of the child process\n");
46351.1Skamil		_exit(exitval);
46361.1Skamil	}
46371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46381.1Skamil
46391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46411.1Skamil
46421.1Skamil	validate_status_stopped(status, sigval);
46431.1Skamil
46441.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
46451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
46461.1Skamil
46471.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
46481.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
46491.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
46501.1Skamil	    info.psi_siginfo.si_errno);
46511.1Skamil
46521.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
46531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
46541.1Skamil
46551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46561.1Skamil	    "without signal to be sent\n");
46571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
46581.1Skamil
46591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46611.1Skamil
46621.1Skamil	validate_status_exited(status, exitval);
46631.1Skamil
46641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46661.1Skamil}
46671.1Skamil
46681.1SkamilATF_TC(siginfo3);
46691.1SkamilATF_TC_HEAD(siginfo3, tc)
46701.1Skamil{
46711.1Skamil	atf_tc_set_md_var(tc, "descr",
46721.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
46731.1Skamil	    "setting signal to new value");
46741.1Skamil}
46751.1Skamil
46761.1Skamilstatic int siginfo3_caught = 0;
46771.1Skamil
46781.1Skamilstatic void
46791.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
46801.1Skamil{
46811.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
46821.1Skamil
46831.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
46841.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
46851.1Skamil
46861.1Skamil	++siginfo3_caught;
46871.1Skamil}
46881.1Skamil
46891.1SkamilATF_TC_BODY(siginfo3, tc)
46901.1Skamil{
46911.1Skamil	const int exitval = 5;
46921.1Skamil	const int sigval = SIGINT;
46931.1Skamil	const int sigfaked = SIGTRAP;
46941.1Skamil	const int sicodefaked = TRAP_BRKPT;
46951.1Skamil	pid_t child, wpid;
46961.1Skamil	struct sigaction sa;
46971.1Skamil#if defined(TWAIT_HAVE_STATUS)
46981.1Skamil	int status;
46991.1Skamil#endif
47001.1Skamil	struct ptrace_siginfo info;
47011.1Skamil	memset(&info, 0, sizeof(info));
47021.1Skamil
47031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47051.1Skamil	if (child == 0) {
47061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47081.1Skamil
47091.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
47101.1Skamil		sa.sa_flags = SA_SIGINFO;
47111.1Skamil		sigemptyset(&sa.sa_mask);
47121.1Skamil
47131.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
47141.1Skamil
47151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47171.1Skamil
47181.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
47191.1Skamil
47201.13Schristos		DPRINTF("Before exiting of the child process\n");
47211.1Skamil		_exit(exitval);
47221.1Skamil	}
47231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47241.1Skamil
47251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47271.1Skamil
47281.1Skamil	validate_status_stopped(status, sigval);
47291.1Skamil
47301.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47321.1Skamil
47331.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47341.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47351.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47361.1Skamil	    info.psi_siginfo.si_errno);
47371.1Skamil
47381.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
47391.1Skamil	    sigfaked, sicodefaked);
47401.1Skamil	info.psi_siginfo.si_signo = sigfaked;
47411.1Skamil	info.psi_siginfo.si_code = sicodefaked;
47421.1Skamil
47431.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
47441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
47451.1Skamil
47461.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47481.1Skamil
47491.13Schristos	DPRINTF("Before checking siginfo_t\n");
47501.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
47511.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
47521.1Skamil
47531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47541.1Skamil	    "without signal to be sent\n");
47551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
47561.1Skamil
47571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47591.1Skamil
47601.1Skamil	validate_status_exited(status, exitval);
47611.1Skamil
47621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47641.1Skamil}
47651.1Skamil
47661.1SkamilATF_TC(siginfo4);
47671.1SkamilATF_TC_HEAD(siginfo4, tc)
47681.1Skamil{
47691.1Skamil	atf_tc_set_md_var(tc, "descr",
47701.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
47711.1Skamil}
47721.1Skamil
47731.1SkamilATF_TC_BODY(siginfo4, tc)
47741.1Skamil{
47751.1Skamil	const int sigval = SIGTRAP;
47761.1Skamil	pid_t child, wpid;
47771.1Skamil#if defined(TWAIT_HAVE_STATUS)
47781.1Skamil	int status;
47791.1Skamil#endif
47801.1Skamil
47811.1Skamil	struct ptrace_siginfo info;
47821.1Skamil	memset(&info, 0, sizeof(info));
47831.1Skamil
47841.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47851.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47861.1Skamil	if (child == 0) {
47871.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47881.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47891.1Skamil
47901.13Schristos		DPRINTF("Before calling execve(2) from child\n");
47911.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
47921.1Skamil
47931.1Skamil		FORKEE_ASSERT(0 && "Not reached");
47941.1Skamil	}
47951.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47961.1Skamil
47971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47991.1Skamil
48001.1Skamil	validate_status_stopped(status, sigval);
48011.1Skamil
48021.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48041.1Skamil
48051.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
48061.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
48071.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
48081.1Skamil	    info.psi_siginfo.si_errno);
48091.1Skamil
48101.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
48111.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
48121.1Skamil
48131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48141.1Skamil	    "without signal to be sent\n");
48151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
48161.1Skamil
48171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48191.1Skamil
48201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48211.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
48221.1Skamil}
48231.1Skamil
48241.1Skamil#if defined(TWAIT_HAVE_PID)
48251.1SkamilATF_TC(siginfo5);
48261.1SkamilATF_TC_HEAD(siginfo5, tc)
48271.1Skamil{
48281.1Skamil	atf_tc_set_md_var(tc, "descr",
48291.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
48301.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
48311.1Skamil}
48321.1Skamil
48331.1SkamilATF_TC_BODY(siginfo5, tc)
48341.1Skamil{
48351.1Skamil	const int exitval = 5;
48361.1Skamil	const int exitval2 = 15;
48371.1Skamil	const int sigval = SIGSTOP;
48381.1Skamil	pid_t child, child2, wpid;
48391.1Skamil#if defined(TWAIT_HAVE_STATUS)
48401.1Skamil	int status;
48411.1Skamil#endif
48421.1Skamil	ptrace_state_t state;
48431.1Skamil	const int slen = sizeof(state);
48441.1Skamil	ptrace_event_t event;
48451.1Skamil	const int elen = sizeof(event);
48461.1Skamil	struct ptrace_siginfo info;
48471.1Skamil
48481.1Skamil	memset(&info, 0, sizeof(info));
48491.1Skamil
48501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48521.1Skamil	if (child == 0) {
48531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48551.1Skamil
48561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
48571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
48581.1Skamil
48591.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
48601.1Skamil
48611.1Skamil		if (child2 == 0)
48621.1Skamil			_exit(exitval2);
48631.1Skamil
48641.1Skamil		FORKEE_REQUIRE_SUCCESS
48651.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
48661.1Skamil
48671.1Skamil		forkee_status_exited(status, exitval2);
48681.1Skamil
48691.13Schristos		DPRINTF("Before exiting of the child process\n");
48701.1Skamil		_exit(exitval);
48711.1Skamil	}
48721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
48731.1Skamil
48741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48761.1Skamil
48771.1Skamil	validate_status_stopped(status, sigval);
48781.1Skamil
48791.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48811.1Skamil
48821.13Schristos	DPRINTF("Before checking siginfo_t\n");
48831.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
48841.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
48851.1Skamil
48861.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
48871.1Skamil	event.pe_set_event = PTRACE_FORK;
48881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
48891.1Skamil
48901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48911.1Skamil	    "without signal to be sent\n");
48921.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
48931.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
48941.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
48951.1Skamil                "state.pe_other_pid=child)\n", child);
48961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
48971.1Skamil
48981.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
48991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49001.1Skamil
49011.1Skamil	validate_status_stopped(status, SIGTRAP);
49021.1Skamil
49031.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49051.1Skamil
49061.13Schristos	DPRINTF("Before checking siginfo_t\n");
49071.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
49081.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
49091.1Skamil
49101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
49111.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
49121.1Skamil
49131.1Skamil	child2 = state.pe_other_pid;
49141.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
49151.1Skamil
49161.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
49171.1Skamil	    TWAIT_FNAME, child2, child);
49181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
49191.1Skamil	    child2);
49201.1Skamil
49211.1Skamil	validate_status_stopped(status, SIGTRAP);
49221.1Skamil
49231.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49251.1Skamil
49261.13Schristos	DPRINTF("Before checking siginfo_t\n");
49271.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
49281.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
49291.1Skamil
49301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
49311.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
49321.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
49331.1Skamil
49341.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
49351.1Skamil	    "without signal to be sent\n");
49361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
49371.1Skamil
49381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49391.1Skamil	    "without signal to be sent\n");
49401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49411.1Skamil
49421.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
49431.1Skamil	    TWAIT_FNAME);
49441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
49451.1Skamil	    child2);
49461.1Skamil
49471.1Skamil	validate_status_exited(status, exitval2);
49481.1Skamil
49491.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
49501.1Skamil	    TWAIT_FNAME);
49511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
49521.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
49531.1Skamil
49541.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
49551.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
49561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49571.1Skamil
49581.1Skamil	validate_status_stopped(status, SIGCHLD);
49591.1Skamil
49601.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49621.1Skamil
49631.13Schristos	DPRINTF("Before checking siginfo_t\n");
49641.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
49651.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
49661.1Skamil
49671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49681.1Skamil	    "without signal to be sent\n");
49691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49701.1Skamil
49711.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
49721.1Skamil	    TWAIT_FNAME);
49731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49741.1Skamil
49751.1Skamil	validate_status_exited(status, exitval);
49761.1Skamil
49771.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
49781.1Skamil	    TWAIT_FNAME);
49791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49801.1Skamil}
49811.1Skamil#endif
49821.1Skamil
49831.1Skamil#if defined(PT_STEP)
49841.1SkamilATF_TC(siginfo6);
49851.1SkamilATF_TC_HEAD(siginfo6, tc)
49861.1Skamil{
49871.1Skamil	atf_tc_set_md_var(tc, "descr",
49881.1Skamil	    "Verify single PT_STEP call with signal information check");
49891.1Skamil}
49901.1Skamil
49911.1SkamilATF_TC_BODY(siginfo6, tc)
49921.1Skamil{
49931.1Skamil	const int exitval = 5;
49941.1Skamil	const int sigval = SIGSTOP;
49951.1Skamil	pid_t child, wpid;
49961.1Skamil#if defined(TWAIT_HAVE_STATUS)
49971.1Skamil	int status;
49981.1Skamil#endif
49991.1Skamil	int happy;
50001.1Skamil	struct ptrace_siginfo info;
50011.1Skamil
50021.1Skamil#if defined(__arm__)
50031.1Skamil	/* PT_STEP not supported on arm 32-bit */
50041.1Skamil	atf_tc_expect_fail("PR kern/52119");
50051.1Skamil#endif
50061.1Skamil
50071.1Skamil	memset(&info, 0, sizeof(info));
50081.1Skamil
50091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50111.1Skamil	if (child == 0) {
50121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50141.1Skamil
50151.1Skamil		happy = check_happy(100);
50161.1Skamil
50171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50191.1Skamil
50201.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
50211.1Skamil
50221.13Schristos		DPRINTF("Before exiting of the child process\n");
50231.1Skamil		_exit(exitval);
50241.1Skamil	}
50251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50261.1Skamil
50271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50291.1Skamil
50301.1Skamil	validate_status_stopped(status, sigval);
50311.1Skamil
50321.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50341.1Skamil
50351.13Schristos	DPRINTF("Before checking siginfo_t\n");
50361.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
50371.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
50381.1Skamil
50391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50401.1Skamil	    "without signal to be sent (use PT_STEP)\n");
50411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
50421.1Skamil
50431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50451.1Skamil
50461.1Skamil	validate_status_stopped(status, SIGTRAP);
50471.1Skamil
50481.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50501.1Skamil
50511.13Schristos	DPRINTF("Before checking siginfo_t\n");
50521.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
50531.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
50541.1Skamil
50551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50561.1Skamil	    "without signal to be sent\n");
50571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50581.1Skamil
50591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50611.1Skamil
50621.1Skamil	validate_status_exited(status, exitval);
50631.1Skamil
50641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50661.1Skamil}
50671.1Skamil#endif
50681.1Skamil
50691.1Skamilvolatile lwpid_t the_lwp_id = 0;
50701.1Skamil
50711.1Skamilstatic void
50721.1Skamillwp_main_func(void *arg)
50731.1Skamil{
50741.1Skamil	the_lwp_id = _lwp_self();
50751.1Skamil	_lwp_exit();
50761.1Skamil}
50771.1Skamil
50781.1SkamilATF_TC(lwp_create1);
50791.1SkamilATF_TC_HEAD(lwp_create1, tc)
50801.1Skamil{
50811.1Skamil	atf_tc_set_md_var(tc, "descr",
50821.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
50831.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
50841.1Skamil}
50851.1Skamil
50861.1SkamilATF_TC_BODY(lwp_create1, tc)
50871.1Skamil{
50881.1Skamil	const int exitval = 5;
50891.1Skamil	const int sigval = SIGSTOP;
50901.1Skamil	pid_t child, wpid;
50911.1Skamil#if defined(TWAIT_HAVE_STATUS)
50921.1Skamil	int status;
50931.1Skamil#endif
50941.1Skamil	ptrace_state_t state;
50951.1Skamil	const int slen = sizeof(state);
50961.1Skamil	ptrace_event_t event;
50971.1Skamil	const int elen = sizeof(event);
50981.1Skamil	ucontext_t uc;
50991.1Skamil	lwpid_t lid;
51001.1Skamil	static const size_t ssize = 16*1024;
51011.1Skamil	void *stack;
51021.1Skamil
51031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51051.1Skamil	if (child == 0) {
51061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51081.1Skamil
51091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
51101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
51111.1Skamil
51121.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
51131.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
51141.1Skamil
51151.13Schristos		DPRINTF("Before making context for new lwp in child\n");
51161.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
51171.1Skamil
51181.13Schristos		DPRINTF("Before creating new in child\n");
51191.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
51201.1Skamil
51211.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
51221.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
51231.1Skamil
51241.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
51251.1Skamil		    "are the same\n", lid, the_lwp_id);
51261.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
51271.1Skamil
51281.13Schristos		DPRINTF("Before exiting of the child process\n");
51291.1Skamil		_exit(exitval);
51301.1Skamil	}
51311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51321.1Skamil
51331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51351.1Skamil
51361.1Skamil	validate_status_stopped(status, sigval);
51371.1Skamil
51381.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
51391.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
51401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
51411.1Skamil
51421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51431.1Skamil	    "without signal to be sent\n");
51441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51451.1Skamil
51461.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
51471.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
51481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51491.1Skamil
51501.1Skamil	validate_status_stopped(status, SIGTRAP);
51511.1Skamil
51521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
51531.1Skamil
51541.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
51551.1Skamil
51561.1Skamil	lid = state.pe_lwp;
51571.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
51581.1Skamil
51591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51601.1Skamil	    "without signal to be sent\n");
51611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51621.1Skamil
51631.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
51641.1Skamil	    TWAIT_FNAME);
51651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51661.1Skamil
51671.1Skamil	validate_status_exited(status, exitval);
51681.1Skamil
51691.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
51701.1Skamil	    TWAIT_FNAME);
51711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51721.1Skamil}
51731.1Skamil
51741.1SkamilATF_TC(lwp_exit1);
51751.1SkamilATF_TC_HEAD(lwp_exit1, tc)
51761.1Skamil{
51771.1Skamil	atf_tc_set_md_var(tc, "descr",
51781.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
51791.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
51801.1Skamil}
51811.1Skamil
51821.1SkamilATF_TC_BODY(lwp_exit1, tc)
51831.1Skamil{
51841.1Skamil	const int exitval = 5;
51851.1Skamil	const int sigval = SIGSTOP;
51861.1Skamil	pid_t child, wpid;
51871.1Skamil#if defined(TWAIT_HAVE_STATUS)
51881.1Skamil	int status;
51891.1Skamil#endif
51901.1Skamil	ptrace_state_t state;
51911.1Skamil	const int slen = sizeof(state);
51921.1Skamil	ptrace_event_t event;
51931.1Skamil	const int elen = sizeof(event);
51941.1Skamil	ucontext_t uc;
51951.1Skamil	lwpid_t lid;
51961.1Skamil	static const size_t ssize = 16*1024;
51971.1Skamil	void *stack;
51981.1Skamil
51991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52011.1Skamil	if (child == 0) {
52021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52041.1Skamil
52051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52071.1Skamil
52081.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
52091.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
52101.1Skamil
52111.13Schristos		DPRINTF("Before making context for new lwp in child\n");
52121.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
52131.1Skamil
52141.13Schristos		DPRINTF("Before creating new in child\n");
52151.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
52161.1Skamil
52171.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
52181.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
52191.1Skamil
52201.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
52211.1Skamil		    "are the same\n", lid, the_lwp_id);
52221.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
52231.1Skamil
52241.13Schristos		DPRINTF("Before exiting of the child process\n");
52251.1Skamil		_exit(exitval);
52261.1Skamil	}
52271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52281.1Skamil
52291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52311.1Skamil
52321.1Skamil	validate_status_stopped(status, sigval);
52331.1Skamil
52341.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
52351.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
52361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52371.1Skamil
52381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52391.1Skamil	    "without signal to be sent\n");
52401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52411.1Skamil
52421.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
52431.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
52441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52451.1Skamil
52461.1Skamil	validate_status_stopped(status, SIGTRAP);
52471.1Skamil
52481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52491.1Skamil
52501.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
52511.1Skamil
52521.1Skamil	lid = state.pe_lwp;
52531.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
52541.1Skamil
52551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52561.1Skamil	    "without signal to be sent\n");
52571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52581.1Skamil
52591.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
52601.1Skamil	    TWAIT_FNAME);
52611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52621.1Skamil
52631.1Skamil	validate_status_exited(status, exitval);
52641.1Skamil
52651.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
52661.1Skamil	    TWAIT_FNAME);
52671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
52681.1Skamil}
52691.1Skamil
52701.1SkamilATF_TC(signal1);
52711.1SkamilATF_TC_HEAD(signal1, tc)
52721.1Skamil{
52731.1Skamil	atf_tc_set_md_var(tc, "descr",
52741.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
52751.1Skamil	    "from catching other signals");
52761.1Skamil}
52771.1Skamil
52781.1SkamilATF_TC_BODY(signal1, tc)
52791.1Skamil{
52801.1Skamil	const int exitval = 5;
52811.1Skamil	const int sigval = SIGSTOP;
52821.1Skamil	const int sigmasked = SIGTRAP;
52831.1Skamil	const int signotmasked = SIGINT;
52841.1Skamil	pid_t child, wpid;
52851.1Skamil#if defined(TWAIT_HAVE_STATUS)
52861.1Skamil	int status;
52871.1Skamil#endif
52881.1Skamil	sigset_t intmask;
52891.1Skamil
52901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52921.1Skamil	if (child == 0) {
52931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52951.1Skamil
52961.1Skamil		sigemptyset(&intmask);
52971.1Skamil		sigaddset(&intmask, sigmasked);
52981.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
52991.1Skamil
53001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53021.1Skamil
53031.13Schristos		DPRINTF("Before raising %s from child\n",
53041.1Skamil		    strsignal(signotmasked));
53051.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
53061.1Skamil
53071.13Schristos		DPRINTF("Before exiting of the child process\n");
53081.1Skamil		_exit(exitval);
53091.1Skamil	}
53101.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53111.1Skamil
53121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53141.1Skamil
53151.1Skamil	validate_status_stopped(status, sigval);
53161.1Skamil
53171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53181.1Skamil	    "without signal to be sent\n");
53191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53201.1Skamil
53211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53231.1Skamil
53241.1Skamil	validate_status_stopped(status, signotmasked);
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\n", TWAIT_FNAME);
53311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53321.1Skamil
53331.1Skamil	validate_status_exited(status, exitval);
53341.1Skamil
53351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53371.1Skamil}
53381.1Skamil
53391.1SkamilATF_TC(signal2);
53401.1SkamilATF_TC_HEAD(signal2, tc)
53411.1Skamil{
53421.1Skamil	atf_tc_set_md_var(tc, "descr",
53431.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
53441.1Skamil	    "catching this raised signal");
53451.1Skamil}
53461.1Skamil
53471.1SkamilATF_TC_BODY(signal2, tc)
53481.1Skamil{
53491.1Skamil	const int exitval = 5;
53501.1Skamil	const int sigval = SIGSTOP;
53511.1Skamil	const int sigmasked = SIGTRAP;
53521.1Skamil	pid_t child, wpid;
53531.1Skamil#if defined(TWAIT_HAVE_STATUS)
53541.1Skamil	int status;
53551.1Skamil#endif
53561.1Skamil	sigset_t intmask;
53571.1Skamil
53581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53601.1Skamil	if (child == 0) {
53611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53631.1Skamil
53641.1Skamil		sigemptyset(&intmask);
53651.1Skamil		sigaddset(&intmask, sigmasked);
53661.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
53671.1Skamil
53681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53701.1Skamil
53711.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
53721.1Skamil		    strsignal(sigmasked));
53731.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
53741.1Skamil
53751.13Schristos		DPRINTF("Before exiting of the child process\n");
53761.1Skamil		_exit(exitval);
53771.1Skamil	}
53781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53791.1Skamil
53801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53821.1Skamil
53831.1Skamil	validate_status_stopped(status, sigval);
53841.1Skamil
53851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53861.1Skamil	    "without signal to be sent\n");
53871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53881.1Skamil
53891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53911.1Skamil
53921.1Skamil	validate_status_exited(status, exitval);
53931.1Skamil
53941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53961.1Skamil}
53971.1Skamil
53981.1SkamilATF_TC(signal3);
53991.1SkamilATF_TC_HEAD(signal3, tc)
54001.1Skamil{
54011.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
54021.1Skamil	atf_tc_set_md_var(tc, "descr",
54031.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
54041.1Skamil	    "catching software breakpoints");
54051.1Skamil}
54061.1Skamil
54071.1SkamilATF_TC_BODY(signal3, tc)
54081.1Skamil{
54091.1Skamil	const int exitval = 5;
54101.1Skamil	const int sigval = SIGSTOP;
54111.1Skamil	const int sigmasked = SIGTRAP;
54121.1Skamil	pid_t child, wpid;
54131.1Skamil#if defined(TWAIT_HAVE_STATUS)
54141.1Skamil	int status;
54151.1Skamil#endif
54161.1Skamil	sigset_t intmask;
54171.1Skamil
54181.20Skamil	atf_tc_expect_fail("PR kern/51918");
54191.20Skamil
54201.20Skamil	// This test breaks now on some ports, temporarily disable it
54211.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
54221.20Skamil
54231.10Smartin#if defined(__sparc__)
54241.7Skamil	atf_tc_expect_timeout("PR kern/52167");
54251.7Skamil
54261.7Skamil	// timeout wins, failure still valid
54271.7Skamil	// atf_tc_expect_fail("PR kern/51918");
54281.7Skamil#endif
54291.1Skamil
54301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54321.1Skamil	if (child == 0) {
54331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54351.1Skamil
54361.1Skamil		sigemptyset(&intmask);
54371.1Skamil		sigaddset(&intmask, sigmasked);
54381.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
54391.1Skamil
54401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54421.1Skamil
54431.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
54441.4Skamil
54451.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
54461.4Skamil		PTRACE_BREAKPOINT_ASM;
54471.1Skamil#else
54481.4Skamil		/* port me */
54491.1Skamil#endif
54501.1Skamil
54511.13Schristos		DPRINTF("Before exiting of the child process\n");
54521.1Skamil		_exit(exitval);
54531.1Skamil	}
54541.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54551.1Skamil
54561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54581.1Skamil
54591.1Skamil	validate_status_stopped(status, sigval);
54601.1Skamil
54611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54621.1Skamil	    "without signal to be sent\n");
54631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54641.1Skamil
54651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54671.1Skamil
54681.1Skamil	validate_status_stopped(status, sigmasked);
54691.1Skamil
54701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54711.1Skamil	    "without signal to be sent\n");
54721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54731.1Skamil
54741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54761.1Skamil
54771.1Skamil	validate_status_exited(status, exitval);
54781.1Skamil
54791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54811.1Skamil}
54821.1Skamil
54831.1Skamil#if defined(PT_STEP)
54841.1SkamilATF_TC(signal4);
54851.1SkamilATF_TC_HEAD(signal4, tc)
54861.1Skamil{
54871.1Skamil	atf_tc_set_md_var(tc, "descr",
54881.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
54891.1Skamil	    "catching single step trap");
54901.1Skamil}
54911.1Skamil
54921.1SkamilATF_TC_BODY(signal4, tc)
54931.1Skamil{
54941.1Skamil	const int exitval = 5;
54951.1Skamil	const int sigval = SIGSTOP;
54961.1Skamil	const int sigmasked = SIGTRAP;
54971.1Skamil	pid_t child, wpid;
54981.1Skamil#if defined(TWAIT_HAVE_STATUS)
54991.1Skamil	int status;
55001.1Skamil#endif
55011.1Skamil	sigset_t intmask;
55021.1Skamil	int happy;
55031.1Skamil
55041.1Skamil#if defined(__arm__)
55051.5Skamil	/* PT_STEP not supported on arm 32-bit */
55061.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
55071.1Skamil#endif
55081.1Skamil
55091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55111.1Skamil	if (child == 0) {
55121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55141.1Skamil
55151.1Skamil		happy = check_happy(100);
55161.1Skamil
55171.1Skamil		sigemptyset(&intmask);
55181.1Skamil		sigaddset(&intmask, sigmasked);
55191.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55201.1Skamil
55211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55231.1Skamil
55241.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
55251.1Skamil
55261.13Schristos		DPRINTF("Before exiting of the child process\n");
55271.1Skamil		_exit(exitval);
55281.1Skamil	}
55291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55301.1Skamil
55311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55331.1Skamil
55341.1Skamil	validate_status_stopped(status, sigval);
55351.1Skamil
55361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55371.1Skamil	    "without signal to be sent\n");
55381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
55391.1Skamil
55401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55421.1Skamil
55431.1Skamil	validate_status_stopped(status, sigmasked);
55441.1Skamil
55451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55461.1Skamil	    "without signal to be sent\n");
55471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55481.1Skamil
55491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55511.1Skamil
55521.1Skamil	validate_status_exited(status, exitval);
55531.1Skamil
55541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55561.1Skamil}
55571.1Skamil#endif
55581.1Skamil
55591.1SkamilATF_TC(signal5);
55601.1SkamilATF_TC_HEAD(signal5, tc)
55611.1Skamil{
55621.1Skamil	atf_tc_set_md_var(tc, "descr",
55631.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55641.1Skamil	    "catching exec() breakpoint");
55651.1Skamil}
55661.1Skamil
55671.1SkamilATF_TC_BODY(signal5, tc)
55681.1Skamil{
55691.1Skamil	const int exitval = 5;
55701.1Skamil	const int sigval = SIGSTOP;
55711.1Skamil	const int sigmasked = SIGTRAP;
55721.1Skamil	pid_t child, wpid;
55731.1Skamil#if defined(TWAIT_HAVE_STATUS)
55741.1Skamil	int status;
55751.1Skamil#endif
55761.1Skamil	sigset_t intmask;
55771.1Skamil
55781.14Schristos	atf_tc_expect_fail("wrong signal");
55791.14Schristos
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		sigemptyset(&intmask);
55871.1Skamil		sigaddset(&intmask, sigmasked);
55881.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55891.1Skamil
55901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55921.1Skamil
55931.13Schristos		DPRINTF("Before calling execve(2) from child\n");
55941.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
55951.1Skamil
55961.13Schristos		DPRINTF("Before exiting of the child process\n");
55971.1Skamil		_exit(exitval);
55981.1Skamil	}
55991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56001.1Skamil
56011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56031.1Skamil
56041.1Skamil	validate_status_stopped(status, sigval);
56051.1Skamil
56061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56071.1Skamil	    "without signal to be sent\n");
56081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56091.1Skamil
56101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56121.1Skamil
56131.1Skamil	validate_status_stopped(status, sigmasked);
56141.1Skamil
56151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56161.1Skamil	    "without signal to be sent\n");
56171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56181.1Skamil
56191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56211.1Skamil
56221.1Skamil	validate_status_exited(status, exitval);
56231.1Skamil
56241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56261.1Skamil}
56271.1Skamil
56281.1Skamil#if defined(TWAIT_HAVE_PID)
56291.1SkamilATF_TC(signal6);
56301.1SkamilATF_TC_HEAD(signal6, tc)
56311.1Skamil{
56321.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
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 PTRACE_FORK breakpoint");
56361.1Skamil}
56371.1Skamil
56381.1SkamilATF_TC_BODY(signal6, tc)
56391.1Skamil{
56401.1Skamil	const int exitval = 5;
56411.1Skamil	const int exitval2 = 15;
56421.1Skamil	const int sigval = SIGSTOP;
56431.1Skamil	const int sigmasked = SIGTRAP;
56441.1Skamil	pid_t child, child2, wpid;
56451.1Skamil#if defined(TWAIT_HAVE_STATUS)
56461.1Skamil	int status;
56471.1Skamil#endif
56481.1Skamil	sigset_t intmask;
56491.1Skamil	ptrace_state_t state;
56501.1Skamil	const int slen = sizeof(state);
56511.1Skamil	ptrace_event_t event;
56521.1Skamil	const int elen = sizeof(event);
56531.1Skamil
56541.14Schristos	atf_tc_expect_timeout("PR kern/51918");
56551.14Schristos
56561.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56571.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56581.1Skamil	if (child == 0) {
56591.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56601.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56611.1Skamil
56621.1Skamil		sigemptyset(&intmask);
56631.1Skamil		sigaddset(&intmask, sigmasked);
56641.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56651.1Skamil
56661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56681.1Skamil
56691.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
56701.1Skamil
56711.1Skamil		if (child2 == 0)
56721.1Skamil			_exit(exitval2);
56731.1Skamil
56741.1Skamil		FORKEE_REQUIRE_SUCCESS
56751.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
56761.1Skamil
56771.1Skamil		forkee_status_exited(status, exitval2);
56781.1Skamil
56791.13Schristos		DPRINTF("Before exiting of the child process\n");
56801.1Skamil		_exit(exitval);
56811.1Skamil	}
56821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56831.1Skamil
56841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56861.1Skamil
56871.1Skamil	validate_status_stopped(status, sigval);
56881.1Skamil
56891.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
56901.1Skamil	event.pe_set_event = PTRACE_FORK;
56911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
56921.1Skamil
56931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56941.1Skamil	    "without signal to be sent\n");
56951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56961.1Skamil
56971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56991.1Skamil
57001.1Skamil	validate_status_stopped(status, sigmasked);
57011.1Skamil
57021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
57031.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
57041.1Skamil
57051.1Skamil	child2 = state.pe_other_pid;
57061.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
57071.1Skamil
57081.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
57091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
57101.1Skamil	    child2);
57111.1Skamil
57121.1Skamil	validate_status_stopped(status, SIGTRAP);
57131.1Skamil
57141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
57151.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
57161.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
57171.1Skamil
57181.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
57191.1Skamil	    "without signal to be sent\n");
57201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
57211.1Skamil
57221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57231.1Skamil	    "without signal to be sent\n");
57241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57251.1Skamil
57261.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
57271.1Skamil	    TWAIT_FNAME);
57281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
57291.1Skamil	    child2);
57301.1Skamil
57311.1Skamil	validate_status_exited(status, exitval2);
57321.1Skamil
57331.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
57341.1Skamil	    TWAIT_FNAME);
57351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
57361.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
57371.1Skamil
57381.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
57391.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
57401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57411.1Skamil
57421.1Skamil	validate_status_stopped(status, SIGCHLD);
57431.1Skamil
57441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57451.1Skamil	    "without signal to be sent\n");
57461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57471.1Skamil
57481.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
57491.1Skamil	    TWAIT_FNAME);
57501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57511.1Skamil
57521.1Skamil	validate_status_exited(status, exitval);
57531.1Skamil
57541.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
57551.1Skamil	    TWAIT_FNAME);
57561.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57571.1Skamil}
57581.1Skamil#endif
57591.1Skamil
57601.1Skamil#if defined(TWAIT_HAVE_PID)
57611.1SkamilATF_TC(signal7);
57621.1SkamilATF_TC_HEAD(signal7, tc)
57631.1Skamil{
57641.1Skamil	atf_tc_set_md_var(tc, "descr",
57651.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57661.1Skamil	    "catching PTRACE_VFORK breakpoint");
57671.1Skamil}
57681.1Skamil
57691.1SkamilATF_TC_BODY(signal7, tc)
57701.1Skamil{
57711.1Skamil	const int exitval = 5;
57721.1Skamil	const int exitval2 = 15;
57731.1Skamil	const int sigval = SIGSTOP;
57741.1Skamil	const int sigmasked = SIGTRAP;
57751.1Skamil	pid_t child, child2, wpid;
57761.1Skamil#if defined(TWAIT_HAVE_STATUS)
57771.1Skamil	int status;
57781.1Skamil#endif
57791.1Skamil	sigset_t intmask;
57801.1Skamil	ptrace_state_t state;
57811.1Skamil	const int slen = sizeof(state);
57821.1Skamil	ptrace_event_t event;
57831.1Skamil	const int elen = sizeof(event);
57841.1Skamil
57851.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
57861.14Schristos
57871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57891.1Skamil	if (child == 0) {
57901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57921.1Skamil
57931.1Skamil		sigemptyset(&intmask);
57941.1Skamil		sigaddset(&intmask, sigmasked);
57951.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57961.1Skamil
57971.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57981.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57991.1Skamil
58001.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
58011.1Skamil
58021.1Skamil		if (child2 == 0)
58031.1Skamil			_exit(exitval2);
58041.1Skamil
58051.1Skamil		FORKEE_REQUIRE_SUCCESS
58061.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
58071.1Skamil
58081.1Skamil		forkee_status_exited(status, exitval2);
58091.1Skamil
58101.13Schristos		DPRINTF("Before exiting of the child process\n");
58111.1Skamil		_exit(exitval);
58121.1Skamil	}
58131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58141.1Skamil
58151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58171.1Skamil
58181.1Skamil	validate_status_stopped(status, sigval);
58191.1Skamil
58201.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
58211.1Skamil	event.pe_set_event = PTRACE_VFORK;
58221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
58231.1Skamil
58241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58251.1Skamil	    "without signal to be sent\n");
58261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58271.1Skamil
58281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58301.1Skamil
58311.1Skamil	validate_status_stopped(status, sigmasked);
58321.1Skamil
58331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
58341.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
58351.1Skamil
58361.1Skamil	child2 = state.pe_other_pid;
58371.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
58381.1Skamil
58391.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
58401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58411.1Skamil	    child2);
58421.1Skamil
58431.1Skamil	validate_status_stopped(status, SIGTRAP);
58441.1Skamil
58451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
58461.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
58471.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
58481.1Skamil
58491.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
58501.1Skamil	    "without signal to be sent\n");
58511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
58521.1Skamil
58531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58541.1Skamil	    "without signal to be sent\n");
58551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58561.1Skamil
58571.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
58581.1Skamil	    TWAIT_FNAME);
58591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58601.1Skamil	    child2);
58611.1Skamil
58621.1Skamil	validate_status_exited(status, exitval2);
58631.1Skamil
58641.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
58651.1Skamil	    TWAIT_FNAME);
58661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
58671.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
58681.1Skamil
58691.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
58701.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
58711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58721.1Skamil
58731.1Skamil	validate_status_stopped(status, SIGCHLD);
58741.1Skamil
58751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58761.1Skamil	    "without signal to be sent\n");
58771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58781.1Skamil
58791.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
58801.1Skamil	    TWAIT_FNAME);
58811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58821.1Skamil
58831.1Skamil	validate_status_exited(status, exitval);
58841.1Skamil
58851.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
58861.1Skamil	    TWAIT_FNAME);
58871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58881.1Skamil}
58891.1Skamil#endif
58901.1Skamil
58911.1SkamilATF_TC(signal8);
58921.1SkamilATF_TC_HEAD(signal8, tc)
58931.1Skamil{
58941.1Skamil	atf_tc_set_md_var(tc, "descr",
58951.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58961.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
58971.1Skamil}
58981.1Skamil
58991.1SkamilATF_TC_BODY(signal8, tc)
59001.1Skamil{
59011.1Skamil	const int exitval = 5;
59021.1Skamil	const int exitval2 = 15;
59031.1Skamil	const int sigval = SIGSTOP;
59041.1Skamil	const int sigmasked = SIGTRAP;
59051.1Skamil	pid_t child, child2, wpid;
59061.1Skamil#if defined(TWAIT_HAVE_STATUS)
59071.1Skamil	int status;
59081.1Skamil#endif
59091.1Skamil	sigset_t intmask;
59101.1Skamil	ptrace_state_t state;
59111.1Skamil	const int slen = sizeof(state);
59121.1Skamil	ptrace_event_t event;
59131.1Skamil	const int elen = sizeof(event);
59141.1Skamil
59151.14Schristos	atf_tc_expect_fail("PR kern/51918");
59161.14Schristos
59171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59191.1Skamil	if (child == 0) {
59201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59221.1Skamil
59231.1Skamil		sigemptyset(&intmask);
59241.1Skamil		sigaddset(&intmask, sigmasked);
59251.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59261.1Skamil
59271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59291.1Skamil
59301.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
59311.1Skamil
59321.1Skamil		if (child2 == 0)
59331.1Skamil			_exit(exitval2);
59341.1Skamil
59351.1Skamil		FORKEE_REQUIRE_SUCCESS
59361.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
59371.1Skamil
59381.1Skamil		forkee_status_exited(status, exitval2);
59391.1Skamil
59401.13Schristos		DPRINTF("Before exiting of the child process\n");
59411.1Skamil		_exit(exitval);
59421.1Skamil	}
59431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59441.1Skamil
59451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59471.1Skamil
59481.1Skamil	validate_status_stopped(status, sigval);
59491.1Skamil
59501.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
59511.1Skamil	    child);
59521.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
59531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
59541.1Skamil
59551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59561.1Skamil	    "without signal to be sent\n");
59571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59581.1Skamil
59591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59611.1Skamil
59621.1Skamil	validate_status_stopped(status, sigmasked);
59631.1Skamil
59641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
59651.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
59661.1Skamil
59671.1Skamil	child2 = state.pe_other_pid;
59681.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
59691.1Skamil
59701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59711.1Skamil	    "without signal to be sent\n");
59721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59731.1Skamil
59741.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
59751.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
59761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59771.1Skamil
59781.1Skamil	validate_status_stopped(status, SIGCHLD);
59791.1Skamil
59801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59811.1Skamil	    "without signal to be sent\n");
59821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59831.1Skamil
59841.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
59851.1Skamil	    TWAIT_FNAME);
59861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59871.1Skamil
59881.1Skamil	validate_status_exited(status, exitval);
59891.1Skamil
59901.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
59911.1Skamil	    TWAIT_FNAME);
59921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59931.1Skamil}
59941.1Skamil
59951.1SkamilATF_TC(signal9);
59961.1SkamilATF_TC_HEAD(signal9, tc)
59971.1Skamil{
59981.1Skamil	atf_tc_set_md_var(tc, "descr",
59991.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
60001.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
60011.1Skamil}
60021.1Skamil
60031.1SkamilATF_TC_BODY(signal9, tc)
60041.1Skamil{
60051.1Skamil	const int exitval = 5;
60061.1Skamil	const int sigval = SIGSTOP;
60071.1Skamil	const int sigmasked = SIGTRAP;
60081.1Skamil	pid_t child, wpid;
60091.1Skamil#if defined(TWAIT_HAVE_STATUS)
60101.1Skamil	int status;
60111.1Skamil#endif
60121.1Skamil	sigset_t intmask;
60131.1Skamil	ptrace_state_t state;
60141.1Skamil	const int slen = sizeof(state);
60151.1Skamil	ptrace_event_t event;
60161.1Skamil	const int elen = sizeof(event);
60171.1Skamil	ucontext_t uc;
60181.1Skamil	lwpid_t lid;
60191.1Skamil	static const size_t ssize = 16*1024;
60201.1Skamil	void *stack;
60211.1Skamil
60221.14Schristos	atf_tc_expect_fail("PR kern/51918");
60231.14Schristos
60241.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60251.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60261.1Skamil	if (child == 0) {
60271.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60281.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60291.1Skamil
60301.1Skamil		sigemptyset(&intmask);
60311.1Skamil		sigaddset(&intmask, sigmasked);
60321.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60331.1Skamil
60341.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60351.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60361.1Skamil
60371.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
60381.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
60391.1Skamil
60401.13Schristos		DPRINTF("Before making context for new lwp in child\n");
60411.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
60421.1Skamil
60431.13Schristos		DPRINTF("Before creating new in child\n");
60441.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
60451.1Skamil
60461.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
60471.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
60481.1Skamil
60491.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
60501.1Skamil		    "are the same\n", lid, the_lwp_id);
60511.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
60521.1Skamil
60531.13Schristos		DPRINTF("Before exiting of the child process\n");
60541.1Skamil		_exit(exitval);
60551.1Skamil	}
60561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60571.1Skamil
60581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60601.1Skamil
60611.1Skamil	validate_status_stopped(status, sigval);
60621.1Skamil
60631.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
60641.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
60651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60661.1Skamil
60671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60681.1Skamil	    "without signal to be sent\n");
60691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60701.1Skamil
60711.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60721.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
60731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60741.1Skamil
60751.1Skamil	validate_status_stopped(status, sigmasked);
60761.1Skamil
60771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60781.1Skamil
60791.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
60801.1Skamil
60811.1Skamil	lid = state.pe_lwp;
60821.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
60831.1Skamil
60841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60851.1Skamil	    "without signal to be sent\n");
60861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60871.1Skamil
60881.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60891.1Skamil	    TWAIT_FNAME);
60901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60911.1Skamil
60921.1Skamil	validate_status_exited(status, exitval);
60931.1Skamil
60941.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60951.1Skamil	    TWAIT_FNAME);
60961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60971.1Skamil}
60981.1Skamil
60991.1SkamilATF_TC(signal10);
61001.1SkamilATF_TC_HEAD(signal10, tc)
61011.1Skamil{
61021.1Skamil	atf_tc_set_md_var(tc, "descr",
61031.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61041.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
61051.1Skamil}
61061.1Skamil
61071.1SkamilATF_TC_BODY(signal10, tc)
61081.1Skamil{
61091.1Skamil	const int exitval = 5;
61101.1Skamil	const int sigval = SIGSTOP;
61111.1Skamil	const int sigmasked = SIGTRAP;
61121.1Skamil	pid_t child, wpid;
61131.1Skamil#if defined(TWAIT_HAVE_STATUS)
61141.1Skamil	int status;
61151.1Skamil#endif
61161.1Skamil	sigset_t intmask;
61171.1Skamil	ptrace_state_t state;
61181.1Skamil	const int slen = sizeof(state);
61191.1Skamil	ptrace_event_t event;
61201.1Skamil	const int elen = sizeof(event);
61211.1Skamil	ucontext_t uc;
61221.1Skamil	lwpid_t lid;
61231.1Skamil	static const size_t ssize = 16*1024;
61241.1Skamil	void *stack;
61251.1Skamil
61261.14Schristos	atf_tc_expect_fail("PR kern/51918");
61271.14Schristos
61281.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61291.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61301.1Skamil	if (child == 0) {
61311.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61321.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61331.1Skamil
61341.1Skamil		sigemptyset(&intmask);
61351.1Skamil		sigaddset(&intmask, sigmasked);
61361.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61371.1Skamil
61381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61401.1Skamil
61411.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
61421.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
61431.1Skamil
61441.13Schristos		DPRINTF("Before making context for new lwp in child\n");
61451.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
61461.1Skamil
61471.13Schristos		DPRINTF("Before creating new in child\n");
61481.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
61491.1Skamil
61501.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
61511.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
61521.1Skamil
61531.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
61541.1Skamil		    "are the same\n", lid, the_lwp_id);
61551.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
61561.1Skamil
61571.13Schristos		DPRINTF("Before exiting of the child process\n");
61581.1Skamil		_exit(exitval);
61591.1Skamil	}
61601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61611.1Skamil
61621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61641.1Skamil
61651.1Skamil	validate_status_stopped(status, sigval);
61661.1Skamil
61671.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
61681.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
61691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
61701.1Skamil
61711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61721.1Skamil	    "without signal to be sent\n");
61731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61741.1Skamil
61751.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61761.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
61771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61781.1Skamil
61791.1Skamil	validate_status_stopped(status, sigmasked);
61801.1Skamil
61811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61821.1Skamil
61831.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
61841.1Skamil
61851.1Skamil	lid = state.pe_lwp;
61861.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
61871.1Skamil
61881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61891.1Skamil	    "without signal to be sent\n");
61901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61911.1Skamil
61921.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61931.1Skamil	    TWAIT_FNAME);
61941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61951.1Skamil
61961.1Skamil	validate_status_exited(status, exitval);
61971.1Skamil
61981.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61991.1Skamil	    TWAIT_FNAME);
62001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62011.1Skamil}
62021.1Skamil
62031.1Skamilstatic void
62041.1Skamillwp_main_stop(void *arg)
62051.1Skamil{
62061.1Skamil	the_lwp_id = _lwp_self();
62071.1Skamil
62081.1Skamil	raise(SIGTRAP);
62091.1Skamil
62101.1Skamil	_lwp_exit();
62111.1Skamil}
62121.1Skamil
62131.1SkamilATF_TC(suspend1);
62141.1SkamilATF_TC_HEAD(suspend1, tc)
62151.1Skamil{
62161.1Skamil	atf_tc_set_md_var(tc, "descr",
62171.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
62181.1Skamil	    "resumed by a tracee");
62191.1Skamil}
62201.1Skamil
62211.1SkamilATF_TC_BODY(suspend1, tc)
62221.1Skamil{
62231.1Skamil	const int exitval = 5;
62241.1Skamil	const int sigval = SIGSTOP;
62251.1Skamil	pid_t child, wpid;
62261.1Skamil#if defined(TWAIT_HAVE_STATUS)
62271.1Skamil	int status;
62281.1Skamil#endif
62291.1Skamil	ucontext_t uc;
62301.1Skamil	lwpid_t lid;
62311.1Skamil	static const size_t ssize = 16*1024;
62321.1Skamil	void *stack;
62331.1Skamil	struct ptrace_lwpinfo pl;
62341.1Skamil	struct ptrace_siginfo psi;
62351.1Skamil	volatile int go = 0;
62361.1Skamil
62371.17Skamil	// Feature pending for refactoring
62381.17Skamil	atf_tc_expect_fail("PR kern/51995");
62391.17Skamil
62401.16Skamil	// Hangs with qemu
62411.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
62421.16Skamil
62431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62451.1Skamil	if (child == 0) {
62461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62481.1Skamil
62491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62511.1Skamil
62521.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
62531.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
62541.1Skamil
62551.13Schristos		DPRINTF("Before making context for new lwp in child\n");
62561.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
62571.1Skamil
62581.13Schristos		DPRINTF("Before creating new in child\n");
62591.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
62601.1Skamil
62611.1Skamil		while (go == 0)
62621.1Skamil			continue;
62631.1Skamil
62641.1Skamil		raise(SIGINT);
62651.1Skamil
62661.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
62671.1Skamil
62681.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
62691.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
62701.1Skamil
62711.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
62721.1Skamil		    "are the same\n", lid, the_lwp_id);
62731.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
62741.1Skamil
62751.13Schristos		DPRINTF("Before exiting of the child process\n");
62761.1Skamil		_exit(exitval);
62771.1Skamil	}
62781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62791.1Skamil
62801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62821.1Skamil
62831.1Skamil	validate_status_stopped(status, sigval);
62841.1Skamil
62851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62861.1Skamil	    "without signal to be sent\n");
62871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62881.1Skamil
62891.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62901.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
62911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62921.1Skamil
62931.1Skamil	validate_status_stopped(status, SIGTRAP);
62941.1Skamil
62951.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
62961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
62971.1Skamil
62981.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
62991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
63001.1Skamil
63011.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
63021.1Skamil	    child, getpid());
63031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
63041.1Skamil
63051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63061.1Skamil	    "without signal to be sent\n");
63071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63081.1Skamil
63091.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63101.1Skamil	    "SIGINT\n", TWAIT_FNAME);
63111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63121.1Skamil
63131.1Skamil	validate_status_stopped(status, SIGINT);
63141.1Skamil
63151.1Skamil	pl.pl_lwpid = 0;
63161.1Skamil
63171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
63181.1Skamil	while (pl.pl_lwpid != 0) {
63191.1Skamil
63201.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
63211.1Skamil		switch (pl.pl_lwpid) {
63221.1Skamil		case 1:
63231.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
63241.1Skamil			break;
63251.1Skamil		case 2:
63261.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
63271.1Skamil			break;
63281.1Skamil		}
63291.1Skamil	}
63301.1Skamil
63311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63321.1Skamil	    "without signal to be sent\n");
63331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63341.1Skamil
63351.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63361.1Skamil	    TWAIT_FNAME);
63371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63381.1Skamil
63391.1Skamil	validate_status_exited(status, exitval);
63401.1Skamil
63411.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63421.1Skamil	    TWAIT_FNAME);
63431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63441.1Skamil}
63451.1Skamil
63461.1SkamilATF_TC(suspend2);
63471.1SkamilATF_TC_HEAD(suspend2, tc)
63481.1Skamil{
63491.1Skamil	atf_tc_set_md_var(tc, "descr",
63501.1Skamil	    "Verify that the while the only thread within a process is "
63511.1Skamil	    "suspended, the whole process cannot be unstopped");
63521.1Skamil}
63531.1Skamil
63541.1SkamilATF_TC_BODY(suspend2, tc)
63551.1Skamil{
63561.1Skamil	const int exitval = 5;
63571.1Skamil	const int sigval = SIGSTOP;
63581.1Skamil	pid_t child, wpid;
63591.1Skamil#if defined(TWAIT_HAVE_STATUS)
63601.1Skamil	int status;
63611.1Skamil#endif
63621.1Skamil	struct ptrace_siginfo psi;
63631.1Skamil
63641.17Skamil	// Feature pending for refactoring
63651.17Skamil	atf_tc_expect_fail("PR kern/51995");
63661.17Skamil
63671.16Skamil	// Hangs with qemu
63681.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
63691.16Skamil
63701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63721.1Skamil	if (child == 0) {
63731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63751.1Skamil
63761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63781.1Skamil
63791.13Schristos		DPRINTF("Before exiting of the child process\n");
63801.1Skamil		_exit(exitval);
63811.1Skamil	}
63821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63831.1Skamil
63841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63861.1Skamil
63871.1Skamil	validate_status_stopped(status, sigval);
63881.1Skamil
63891.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
63901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
63911.1Skamil
63921.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
63931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
63941.1Skamil
63951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63961.1Skamil	    "without signal to be sent\n");
63971.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
63981.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
63991.1Skamil
64001.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
64011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
64021.1Skamil
64031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64041.1Skamil	    "without signal to be sent\n");
64051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64061.1Skamil
64071.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64081.1Skamil	    TWAIT_FNAME);
64091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64101.1Skamil
64111.1Skamil	validate_status_exited(status, exitval);
64121.1Skamil
64131.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64141.1Skamil	    TWAIT_FNAME);
64151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64161.1Skamil}
64171.1Skamil
64181.1SkamilATF_TC(resume1);
64191.1SkamilATF_TC_HEAD(resume1, tc)
64201.1Skamil{
64211.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
64221.1Skamil	atf_tc_set_md_var(tc, "descr",
64231.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
64241.1Skamil	    "resumed by the debugger");
64251.1Skamil}
64261.1Skamil
64271.1SkamilATF_TC_BODY(resume1, tc)
64281.1Skamil{
64291.1Skamil	struct msg_fds fds;
64301.1Skamil	const int exitval = 5;
64311.1Skamil	const int sigval = SIGSTOP;
64321.1Skamil	pid_t child, wpid;
64331.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
64341.1Skamil#if defined(TWAIT_HAVE_STATUS)
64351.1Skamil	int status;
64361.1Skamil#endif
64371.1Skamil	ucontext_t uc;
64381.1Skamil	lwpid_t lid;
64391.1Skamil	static const size_t ssize = 16*1024;
64401.1Skamil	void *stack;
64411.1Skamil	struct ptrace_lwpinfo pl;
64421.1Skamil	struct ptrace_siginfo psi;
64431.1Skamil
64441.17Skamil	// Feature pending for refactoring
64451.17Skamil	atf_tc_expect_fail("PR kern/51995");
64461.17Skamil
64471.15Schristos	// Hangs with qemu
64481.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
64491.1Skamil
64501.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
64511.1Skamil
64521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64541.1Skamil	if (child == 0) {
64551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64571.1Skamil
64581.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64591.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64601.1Skamil
64611.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64621.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64631.1Skamil
64641.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64651.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
64661.1Skamil
64671.13Schristos		DPRINTF("Before creating new in child\n");
64681.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64691.1Skamil
64701.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
64711.1Skamil
64721.1Skamil		raise(SIGINT);
64731.1Skamil
64741.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64751.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64761.1Skamil
64771.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64781.1Skamil		    "are the same\n", lid, the_lwp_id);
64791.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64801.1Skamil
64811.13Schristos		DPRINTF("Before exiting of the child process\n");
64821.1Skamil		_exit(exitval);
64831.1Skamil	}
64841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64851.1Skamil
64861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64881.1Skamil
64891.1Skamil	validate_status_stopped(status, sigval);
64901.1Skamil
64911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64921.1Skamil	    "without signal to be sent\n");
64931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64941.1Skamil
64951.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64961.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64981.1Skamil
64991.1Skamil	validate_status_stopped(status, SIGTRAP);
65001.1Skamil
65011.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
65021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
65031.1Skamil
65041.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
65051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
65061.1Skamil
65071.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
65081.1Skamil
65091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65101.1Skamil	    "without signal to be sent\n");
65111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65121.1Skamil
65131.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65141.1Skamil	    "SIGINT\n", TWAIT_FNAME);
65151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65161.1Skamil
65171.1Skamil	validate_status_stopped(status, SIGINT);
65181.1Skamil
65191.1Skamil	pl.pl_lwpid = 0;
65201.1Skamil
65211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
65221.1Skamil	while (pl.pl_lwpid != 0) {
65231.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
65241.1Skamil		switch (pl.pl_lwpid) {
65251.1Skamil		case 1:
65261.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
65271.1Skamil			break;
65281.1Skamil		case 2:
65291.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
65301.1Skamil			break;
65311.1Skamil		}
65321.1Skamil	}
65331.1Skamil
65341.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
65351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
65361.1Skamil
65371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65381.1Skamil	    "without signal to be sent\n");
65391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65401.1Skamil
65411.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65421.1Skamil	    TWAIT_FNAME);
65431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65441.1Skamil
65451.1Skamil	validate_status_exited(status, exitval);
65461.1Skamil
65471.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65481.1Skamil	    TWAIT_FNAME);
65491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65501.1Skamil
65511.1Skamil	msg_close(&fds);
65521.1Skamil
65531.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
65541.1Skamil	sleep(10);
65551.1Skamil}
65561.1Skamil
65571.1SkamilATF_TC(syscall1);
65581.1SkamilATF_TC_HEAD(syscall1, tc)
65591.1Skamil{
65601.1Skamil	atf_tc_set_md_var(tc, "descr",
65611.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
65621.1Skamil}
65631.1Skamil
65641.1SkamilATF_TC_BODY(syscall1, tc)
65651.1Skamil{
65661.1Skamil	const int exitval = 5;
65671.1Skamil	const int sigval = SIGSTOP;
65681.1Skamil	pid_t child, wpid;
65691.1Skamil#if defined(TWAIT_HAVE_STATUS)
65701.1Skamil	int status;
65711.1Skamil#endif
65721.1Skamil	struct ptrace_siginfo info;
65731.1Skamil	memset(&info, 0, sizeof(info));
65741.1Skamil
65751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65771.1Skamil	if (child == 0) {
65781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65801.1Skamil
65811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65831.1Skamil
65841.1Skamil		syscall(SYS_getpid);
65851.1Skamil
65861.13Schristos		DPRINTF("Before exiting of the child process\n");
65871.1Skamil		_exit(exitval);
65881.1Skamil	}
65891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65901.1Skamil
65911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65931.1Skamil
65941.1Skamil	validate_status_stopped(status, sigval);
65951.1Skamil
65961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65971.1Skamil	    "without signal to be sent\n");
65981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
65991.1Skamil
66001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66021.1Skamil
66031.1Skamil	validate_status_stopped(status, SIGTRAP);
66041.1Skamil
66051.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
66061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
66071.1Skamil
66081.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
66091.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
66101.1Skamil
66111.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66121.1Skamil	    "without signal to be sent\n");
66131.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66141.1Skamil
66151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66171.1Skamil
66181.1Skamil	validate_status_stopped(status, SIGTRAP);
66191.1Skamil
66201.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
66211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
66221.1Skamil
66231.13Schristos	DPRINTF("Before checking siginfo_t\n");
66241.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
66251.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
66261.1Skamil
66271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66281.1Skamil	    "without signal to be sent\n");
66291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66301.1Skamil
66311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66331.1Skamil
66341.1Skamil	validate_status_exited(status, exitval);
66351.1Skamil
66361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66381.1Skamil}
66391.1Skamil
66401.1SkamilATF_TC(syscallemu1);
66411.1SkamilATF_TC_HEAD(syscallemu1, tc)
66421.1Skamil{
66431.1Skamil	atf_tc_set_md_var(tc, "descr",
66441.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
66451.1Skamil}
66461.1Skamil
66471.1SkamilATF_TC_BODY(syscallemu1, tc)
66481.1Skamil{
66491.1Skamil	const int exitval = 5;
66501.1Skamil	const int sigval = SIGSTOP;
66511.1Skamil	pid_t child, wpid;
66521.1Skamil#if defined(TWAIT_HAVE_STATUS)
66531.1Skamil	int status;
66541.1Skamil#endif
66551.1Skamil
66561.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
66571.6Skamil	/* syscallemu does not work on sparc (32-bit) */
66581.6Skamil	atf_tc_expect_fail("PR kern/52166");
66591.6Skamil#endif
66601.6Skamil
66611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66631.1Skamil	if (child == 0) {
66641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66661.1Skamil
66671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66691.1Skamil
66701.1Skamil		syscall(SYS_exit, 100);
66711.1Skamil
66721.13Schristos		DPRINTF("Before exiting of the child process\n");
66731.1Skamil		_exit(exitval);
66741.1Skamil	}
66751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66761.1Skamil
66771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66791.1Skamil
66801.1Skamil	validate_status_stopped(status, sigval);
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("Set SYSCALLEMU for intercepted syscall\n");
66921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
66931.1Skamil
66941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66951.1Skamil	    "without signal to be sent\n");
66961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66971.1Skamil
66981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67001.1Skamil
67011.1Skamil	validate_status_stopped(status, SIGTRAP);
67021.1Skamil
67031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67041.1Skamil	    "without signal to be sent\n");
67051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67061.1Skamil
67071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67091.1Skamil
67101.1Skamil	validate_status_exited(status, exitval);
67111.1Skamil
67121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67141.1Skamil}
67151.1Skamil
67161.26Skamil#if defined(TWAIT_HAVE_PID)
67171.26SkamilATF_TC(race1);
67181.26SkamilATF_TC_HEAD(race1, tc)
67191.26Skamil{
67201.26Skamil	atf_tc_set_md_var(tc, "descr",
67211.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
67221.26Skamil	    "process and no other error is reported");
67231.26Skamil}
67241.26Skamil
67251.26SkamilATF_TC_BODY(race1, tc)
67261.26Skamil{
67271.26Skamil	time_t start, end;
67281.26Skamil	double diff;
67291.26Skamil	unsigned long N = 0;
67301.26Skamil
67311.26Skamil	/* Reuse this test with attach1 */
67321.26Skamil
67331.26Skamil	start = time(NULL);
67341.26Skamil	while (true) {
67351.26Skamil		DPRINTF("Step: %lu\n", N);
67361.26Skamil		attach1_raw(true);
67371.26Skamil		end = time(NULL);
67381.26Skamil		diff = difftime(end, start);
67391.26Skamil		if (diff >= 5.0)
67401.26Skamil			break;
67411.26Skamil		++N;
67421.26Skamil	}
67431.26Skamil	DPRINTF("Iterations: %lu\n", N);
67441.26Skamil}
67451.26Skamil#endif
67461.26Skamil
67471.1Skamil#include "t_ptrace_amd64_wait.h"
67481.1Skamil#include "t_ptrace_i386_wait.h"
67491.1Skamil#include "t_ptrace_x86_wait.h"
67501.1Skamil
67511.1SkamilATF_TP_ADD_TCS(tp)
67521.1Skamil{
67531.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
67541.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
67551.33Skamil
67561.33Skamil//	ATF_TP_ADD_TC(tp, traceme_raise1); // not yet
67571.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
67581.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
67591.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
67601.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
67611.33Skamil
67621.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
67631.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
67641.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
67651.34Skamil
67661.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler1);
67671.35Skamil//	ATF_TP_ADD_TC(tp, traceme_signal_nohandler2); // not yet
67681.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler3);
67691.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler4);
67701.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);
67711.1Skamil
67721.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
67731.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
67741.1Skamil	ATF_TP_ADD_TC(tp, attach3);
67751.1Skamil	ATF_TP_ADD_TC(tp, attach4);
67761.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
67771.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
67781.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
67791.1Skamil
67801.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
67811.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
67821.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
67831.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
67841.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
67851.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
67861.1Skamil
67871.31Skamil	ATF_TP_ADD_TC(tp, fork1);
67881.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
67891.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
67901.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
67911.31Skamil	ATF_TP_ADD_TC(tp, fork5);
67921.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
67931.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
67941.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
67951.31Skamil
67961.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
67971.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
67981.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
67991.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
68001.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
68011.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
68021.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
68031.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
68041.1Skamil
68051.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
68061.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
68071.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
68081.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
68091.1Skamil
68101.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
68111.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
68121.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
68131.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
68141.1Skamil
68151.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
68161.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
68171.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
68181.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
68191.1Skamil
68201.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
68211.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
68221.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
68231.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
68241.1Skamil
68251.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
68261.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
68271.1Skamil
68281.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
68291.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
68301.1Skamil
68311.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
68321.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
68331.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
68341.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
68351.1Skamil
68361.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
68371.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
68381.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
68391.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
68401.1Skamil
68411.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
68421.1Skamil
68431.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
68441.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
68451.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
68461.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
68471.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
68481.1Skamil
68491.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
68501.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
68511.1Skamil
68521.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
68531.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
68541.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
68551.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
68561.1Skamil
68571.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
68581.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
68591.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
68601.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
68611.2Skamil
68621.1Skamil	ATF_TP_ADD_TC(tp, kill1);
68631.1Skamil	ATF_TP_ADD_TC(tp, kill2);
68641.1Skamil
68651.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
68661.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
68671.1Skamil
68681.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
68691.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
68701.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
68711.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
68721.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
68731.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
68741.1Skamil
68751.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
68761.1Skamil
68771.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
68781.1Skamil
68791.1Skamil	ATF_TP_ADD_TC(tp, signal1);
68801.1Skamil	ATF_TP_ADD_TC(tp, signal2);
68811.1Skamil	ATF_TP_ADD_TC(tp, signal3);
68821.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
68831.1Skamil	ATF_TP_ADD_TC(tp, signal5);
68841.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
68851.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
68861.1Skamil	ATF_TP_ADD_TC(tp, signal8);
68871.1Skamil	ATF_TP_ADD_TC(tp, signal9);
68881.1Skamil	ATF_TP_ADD_TC(tp, signal10);
68891.1Skamil
68901.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
68911.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
68921.1Skamil
68931.1Skamil	ATF_TP_ADD_TC(tp, resume1);
68941.1Skamil
68951.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
68961.1Skamil
68971.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
68981.1Skamil
68991.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
69001.26Skamil
69011.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
69021.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
69031.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
69041.1Skamil
69051.1Skamil	return atf_no_error();
69061.1Skamil}
6907