t_ptrace_wait.c revision 1.36
11.36Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.36 2018/04/28 19:00:25 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.36Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.36 2018/04/28 19:00:25 kamil Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/types.h>
341.1Skamil#include <sys/ptrace.h>
351.1Skamil#include <sys/resource.h>
361.1Skamil#include <sys/stat.h>
371.1Skamil#include <sys/syscall.h>
381.1Skamil#include <sys/sysctl.h>
391.1Skamil#include <sys/wait.h>
401.1Skamil#include <machine/reg.h>
411.1Skamil#include <elf.h>
421.1Skamil#include <err.h>
431.1Skamil#include <errno.h>
441.1Skamil#include <lwp.h>
451.1Skamil#include <sched.h>
461.1Skamil#include <signal.h>
471.1Skamil#include <stdint.h>
481.1Skamil#include <stdio.h>
491.1Skamil#include <stdlib.h>
501.1Skamil#include <strings.h>
511.26Skamil#include <time.h>
521.1Skamil#include <unistd.h>
531.1Skamil
541.1Skamil#include <atf-c.h>
551.1Skamil
561.1Skamil#include "h_macros.h"
571.1Skamil
581.1Skamil#include "t_ptrace_wait.h"
591.1Skamil#include "msg.h"
601.1Skamil
611.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
621.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
631.1Skamil
641.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
651.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
661.1Skamil
671.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
681.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
691.1Skamil
701.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
711.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
721.13Schristos
731.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
741.13Schristos    strerror(errno))
751.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
761.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
771.13Schristos
781.13Schristosstatic int debug = 0;
791.13Schristos
801.13Schristos#define DPRINTF(a, ...)	do  \
811.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
821.13Schristos    while (/*CONSTCOND*/0)
831.1Skamil
841.34Skamil/// ----------------------------------------------------------------------------
851.34Skamil
861.33Skamilstatic void
871.33Skamiltraceme_raise(int sigval)
881.1Skamil{
891.1Skamil	const int exitval = 5;
901.1Skamil	pid_t child, wpid;
911.1Skamil#if defined(TWAIT_HAVE_STATUS)
921.1Skamil	int status;
931.1Skamil#endif
941.1Skamil
951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
971.1Skamil	if (child == 0) {
981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1001.1Skamil
1011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1031.1Skamil
1041.36Skamil		switch (sigval) {
1051.36Skamil		case SIGKILL:
1061.36Skamil			/* NOTREACHED */
1071.36Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
1081.36Skamil		default:
1091.36Skamil			DPRINTF("Before exiting of the child process\n");
1101.36Skamil			_exit(exitval);
1111.36Skamil		}
1121.1Skamil	}
1131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1141.1Skamil
1151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1171.1Skamil
1181.36Skamil	switch (sigval) {
1191.36Skamil	case SIGKILL:
1201.36Skamil		validate_status_signaled(status, sigval, 0);
1211.36Skamil		break;
1221.36Skamil	default:
1231.36Skamil		validate_status_stopped(status, sigval);
1241.1Skamil
1251.36Skamil		DPRINTF("Before resuming the child process where it left off "
1261.36Skamil		    "and without signal to be sent\n");
1271.36Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1281.1Skamil
1291.36Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1301.36Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1311.36Skamil		                      child);
1321.36Skamil		break;
1331.36Skamil	}
1341.1Skamil
1351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1371.1Skamil}
1381.1Skamil
1391.33Skamil#define TRACEME_RAISE(test, sig)						\
1401.33SkamilATF_TC(test);									\
1411.33SkamilATF_TC_HEAD(test, tc)								\
1421.33Skamil{										\
1431.33Skamil	atf_tc_set_md_var(tc, "descr",						\
1441.33Skamil	    "Verify " #sig " followed by _exit(2) in a child");			\
1451.33Skamil}										\
1461.33Skamil										\
1471.33SkamilATF_TC_BODY(test, tc)								\
1481.33Skamil{										\
1491.33Skamil										\
1501.33Skamil	traceme_raise(sig);							\
1511.33Skamil}
1521.33Skamil
1531.36SkamilTRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
1541.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
1551.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
1561.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
1571.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
1581.33Skamil
1591.34Skamil/// ----------------------------------------------------------------------------
1601.1Skamil
1611.1Skamilstatic void
1621.34Skamiltraceme_sighandler_catch(int sigsent, void (*sah)(int arg), int *traceme_caught)
1631.1Skamil{
1641.1Skamil	const int exitval = 5;
1651.34Skamil	const int sigval = SIGSTOP;
1661.1Skamil	pid_t child, wpid;
1671.1Skamil	struct sigaction sa;
1681.1Skamil#if defined(TWAIT_HAVE_STATUS)
1691.1Skamil	int status;
1701.1Skamil#endif
1711.1Skamil
1721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1741.1Skamil	if (child == 0) {
1751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1771.1Skamil
1781.34Skamil		sa.sa_handler = sah;
1791.1Skamil		sa.sa_flags = SA_SIGINFO;
1801.1Skamil		sigemptyset(&sa.sa_mask);
1811.1Skamil
1821.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1831.1Skamil
1841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1861.1Skamil
1871.34Skamil		FORKEE_ASSERT_EQ(*traceme_caught, 1);
1881.1Skamil
1891.13Schristos		DPRINTF("Before exiting of the child process\n");
1901.1Skamil		_exit(exitval);
1911.1Skamil	}
1921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1931.1Skamil
1941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1961.1Skamil
1971.1Skamil	validate_status_stopped(status, sigval);
1981.1Skamil
1991.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2001.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2021.1Skamil
2031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2051.1Skamil
2061.1Skamil	validate_status_exited(status, exitval);
2071.1Skamil
2081.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2101.1Skamil}
2111.1Skamil
2121.34Skamil#define TRACEME_SIGHANDLER_CATCH(test, sig)					\
2131.34SkamilATF_TC(test);									\
2141.34SkamilATF_TC_HEAD(test, tc)								\
2151.34Skamil{										\
2161.34Skamil	atf_tc_set_md_var(tc, "descr",						\
2171.34Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
2181.34Skamil	    "handled correctly and caught by a signal handler");		\
2191.34Skamil}										\
2201.34Skamil										\
2211.34Skamilstatic int test##_caught = 0;							\
2221.34Skamil										\
2231.34Skamilstatic void									\
2241.34Skamiltest##_sighandler(int arg)							\
2251.34Skamil{										\
2261.34Skamil	FORKEE_ASSERT_EQ(arg, sig);						\
2271.34Skamil										\
2281.34Skamil	++ test##_caught;							\
2291.34Skamil}										\
2301.34Skamil										\
2311.34SkamilATF_TC_BODY(test, tc)								\
2321.34Skamil{										\
2331.34Skamil										\
2341.34Skamil	traceme_sighandler_catch(sig, test##_sighandler, & test##_caught);	\
2351.34Skamil}
2361.34Skamil
2371.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered.
2381.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch1, SIGABRT) /* abort trap */
2391.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch2, SIGHUP)  /* hangup */
2401.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch3, SIGCONT) /* continued? */
2411.34Skamil
2421.34Skamil/// ----------------------------------------------------------------------------
2431.34Skamil
2441.35Skamilstatic void
2451.35Skamiltraceme_signal_nohandler(int sigsent)
2461.1Skamil{
2471.35Skamil	const int sigval = SIGSTOP;
2481.35Skamil	int exitval = 0;
2491.1Skamil	pid_t child, wpid;
2501.1Skamil#if defined(TWAIT_HAVE_STATUS)
2511.1Skamil	int status;
2521.35Skamil	int expect_core = (sigsent == SIGABRT) ? 1 : 0;
2531.1Skamil#endif
2541.1Skamil
2551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2571.1Skamil	if (child == 0) {
2581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2601.1Skamil
2611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2631.1Skamil
2641.35Skamil		switch (sigsent) {
2651.35Skamil		case SIGCONT:
2661.35Skamil			_exit(exitval);
2671.35Skamil		default:
2681.35Skamil			/* NOTREACHED */
2691.35Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
2701.35Skamil		}
2711.1Skamil	}
2721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2731.1Skamil
2741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2761.1Skamil
2771.1Skamil	validate_status_stopped(status, sigval);
2781.1Skamil
2791.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2801.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2821.1Skamil
2831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2851.1Skamil
2861.35Skamil	switch (sigsent) {
2871.35Skamil	case SIGCONT:
2881.35Skamil		validate_status_exited(status, exitval);
2891.35Skamil		break;
2901.35Skamil	default:
2911.35Skamil		validate_status_signaled(status, sigsent, expect_core);
2921.35Skamil		break;
2931.35Skamil	}
2941.1Skamil
2951.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2971.1Skamil}
2981.1Skamil
2991.35Skamil#define TRACEME_SIGNAL_NOHANDLER(test, sig)					\
3001.35SkamilATF_TC(test);									\
3011.35SkamilATF_TC_HEAD(test, tc)								\
3021.35Skamil{										\
3031.35Skamil	atf_tc_set_md_var(tc, "descr",						\
3041.35Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
3051.35Skamil	    "handled correctly in a child without a signal handler");		\
3061.35Skamil}										\
3071.35Skamil										\
3081.35SkamilATF_TC_BODY(test, tc)								\
3091.35Skamil{										\
3101.35Skamil										\
3111.35Skamil	traceme_signal_nohandler(sig);						\
3121.35Skamil}
3131.35Skamil
3141.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */
3151.35Skamil//TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */
3161.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */
3171.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP)  /* hangup */
3181.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */
3191.35Skamil
3201.35Skamil/// ----------------------------------------------------------------------------
3211.35Skamil
3221.1Skamil#if defined(TWAIT_HAVE_PID)
3231.1SkamilATF_TC(attach1);
3241.1SkamilATF_TC_HEAD(attach1, tc)
3251.1Skamil{
3261.1Skamil	atf_tc_set_md_var(tc, "descr",
3271.1Skamil	    "Assert that tracer sees process termination before the parent");
3281.1Skamil}
3291.1Skamil
3301.26Skamilstatic void
3311.26Skamilattach1_raw(bool raw)
3321.1Skamil{
3331.1Skamil	struct msg_fds parent_tracee, parent_tracer;
3341.1Skamil	const int exitval_tracee = 5;
3351.1Skamil	const int exitval_tracer = 10;
3361.1Skamil	pid_t tracee, tracer, wpid;
3371.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3381.1Skamil#if defined(TWAIT_HAVE_STATUS)
3391.1Skamil	int status;
3401.1Skamil#endif
3411.1Skamil
3421.13Schristos	DPRINTF("Spawn tracee\n");
3431.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3441.1Skamil	tracee = atf_utils_fork();
3451.1Skamil	if (tracee == 0) {
3461.1Skamil		// Wait for parent to let us exit
3471.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3481.1Skamil		_exit(exitval_tracee);
3491.1Skamil	}
3501.1Skamil
3511.13Schristos	DPRINTF("Spawn debugger\n");
3521.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3531.1Skamil	tracer = atf_utils_fork();
3541.1Skamil	if (tracer == 0) {
3551.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3561.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3571.1Skamil
3581.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3591.1Skamil		FORKEE_REQUIRE_SUCCESS(
3601.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3611.1Skamil
3621.1Skamil		forkee_status_stopped(status, SIGSTOP);
3631.1Skamil
3641.1Skamil		/* Resume tracee with PT_CONTINUE */
3651.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3661.1Skamil
3671.1Skamil		/* Inform parent that tracer has attached to tracee */
3681.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3691.1Skamil
3701.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3711.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3721.1Skamil
3731.1Skamil		/* Wait for tracee and assert that it exited */
3741.1Skamil		FORKEE_REQUIRE_SUCCESS(
3751.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3761.1Skamil
3771.1Skamil		forkee_status_exited(status, exitval_tracee);
3781.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3791.1Skamil
3801.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3811.1Skamil		_exit(exitval_tracer);
3821.1Skamil	}
3831.1Skamil
3841.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3851.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3861.1Skamil
3871.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3881.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3891.1Skamil
3901.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3911.26Skamil	if (raw)
3921.26Skamil		await_zombie_raw(tracee, 0);
3931.26Skamil	else
3941.26Skamil		await_zombie(tracee);
3951.1Skamil
3961.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3971.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3981.1Skamil	    TWAIT_FNAME);
3991.1Skamil	TWAIT_REQUIRE_SUCCESS(
4001.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4011.1Skamil
4021.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
4031.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
4041.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
4051.1Skamil	    TWAIT_FNAME);
4061.1Skamil
4071.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
4081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
4091.1Skamil	    tracer);
4101.1Skamil
4111.1Skamil	validate_status_exited(status, exitval_tracer);
4121.1Skamil
4131.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4141.1Skamil	    TWAIT_FNAME);
4151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4161.1Skamil	    tracee);
4171.1Skamil
4181.1Skamil	validate_status_exited(status, exitval_tracee);
4191.1Skamil
4201.1Skamil	msg_close(&parent_tracer);
4211.1Skamil	msg_close(&parent_tracee);
4221.1Skamil}
4231.26Skamil
4241.26SkamilATF_TC_BODY(attach1, tc)
4251.26Skamil{
4261.26Skamil
4271.26Skamil	/* Reuse this test with race1 */
4281.26Skamil	attach1_raw(false);
4291.26Skamil}
4301.26Skamil
4311.1Skamil#endif
4321.1Skamil
4331.1Skamil#if defined(TWAIT_HAVE_PID)
4341.1SkamilATF_TC(attach2);
4351.1SkamilATF_TC_HEAD(attach2, tc)
4361.1Skamil{
4371.1Skamil	atf_tc_set_md_var(tc, "descr",
4381.1Skamil	    "Assert that any tracer sees process termination before its "
4391.1Skamil	    "parent");
4401.1Skamil}
4411.1Skamil
4421.1SkamilATF_TC_BODY(attach2, tc)
4431.1Skamil{
4441.1Skamil	struct msg_fds parent_tracer, parent_tracee;
4451.1Skamil	const int exitval_tracee = 5;
4461.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
4471.1Skamil	pid_t tracee, tracer, wpid;
4481.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4491.1Skamil#if defined(TWAIT_HAVE_STATUS)
4501.1Skamil	int status;
4511.1Skamil#endif
4521.1Skamil
4531.13Schristos	DPRINTF("Spawn tracee\n");
4541.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4551.1Skamil	tracee = atf_utils_fork();
4561.1Skamil	if (tracee == 0) {
4571.1Skamil		/* Wait for message from the parent */
4581.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4591.1Skamil		_exit(exitval_tracee);
4601.1Skamil	}
4611.1Skamil
4621.13Schristos	DPRINTF("Spawn debugger\n");
4631.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4641.1Skamil	tracer = atf_utils_fork();
4651.1Skamil	if (tracer == 0) {
4661.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4671.1Skamil		tracer = atf_utils_fork();
4681.1Skamil		if (tracer != 0)
4691.1Skamil			_exit(exitval_tracer1);
4701.1Skamil
4711.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4721.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4731.1Skamil
4741.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4751.1Skamil		FORKEE_REQUIRE_SUCCESS(
4761.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4771.1Skamil
4781.1Skamil		forkee_status_stopped(status, SIGSTOP);
4791.1Skamil
4801.1Skamil		/* Resume tracee with PT_CONTINUE */
4811.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4821.1Skamil
4831.1Skamil		/* Inform parent that tracer has attached to tracee */
4841.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4851.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4861.1Skamil
4871.1Skamil		/* Wait for tracee and assert that it exited */
4881.1Skamil		FORKEE_REQUIRE_SUCCESS(
4891.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4901.1Skamil
4911.1Skamil		forkee_status_exited(status, exitval_tracee);
4921.1Skamil
4931.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4941.1Skamil		_exit(exitval_tracer2);
4951.1Skamil	}
4961.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4971.1Skamil	    "%s()\n", TWAIT_FNAME);
4981.1Skamil	TWAIT_REQUIRE_SUCCESS(
4991.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
5001.1Skamil
5011.1Skamil	validate_status_exited(status, exitval_tracer1);
5021.1Skamil
5031.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
5041.1Skamil	    TWAIT_FNAME);
5051.1Skamil	TWAIT_REQUIRE_SUCCESS(
5061.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
5071.1Skamil
5081.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
5091.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
5101.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
5111.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5121.1Skamil
5131.13Schristos	DPRINTF("Detect that tracee is zombie\n");
5141.1Skamil	await_zombie(tracee);
5151.1Skamil
5161.13Schristos	DPRINTF("Assert that there is no status about tracee - "
5171.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
5181.1Skamil	TWAIT_REQUIRE_SUCCESS(
5191.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
5201.1Skamil
5211.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
5221.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
5231.1Skamil
5241.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5251.1Skamil	    TWAIT_FNAME);
5261.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
5271.1Skamil	    tracee);
5281.1Skamil
5291.1Skamil	validate_status_exited(status, exitval_tracee);
5301.1Skamil
5311.1Skamil	msg_close(&parent_tracer);
5321.1Skamil	msg_close(&parent_tracee);
5331.1Skamil}
5341.1Skamil#endif
5351.1Skamil
5361.1SkamilATF_TC(attach3);
5371.1SkamilATF_TC_HEAD(attach3, tc)
5381.1Skamil{
5391.1Skamil	atf_tc_set_md_var(tc, "descr",
5401.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
5411.1Skamil}
5421.1Skamil
5431.1SkamilATF_TC_BODY(attach3, tc)
5441.1Skamil{
5451.1Skamil	struct msg_fds parent_tracee;
5461.1Skamil	const int exitval_tracee = 5;
5471.1Skamil	pid_t tracee, wpid;
5481.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5491.1Skamil#if defined(TWAIT_HAVE_STATUS)
5501.1Skamil	int status;
5511.1Skamil#endif
5521.1Skamil
5531.13Schristos	DPRINTF("Spawn tracee\n");
5541.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5551.1Skamil	tracee = atf_utils_fork();
5561.1Skamil	if (tracee == 0) {
5571.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5581.13Schristos		DPRINTF("Parent should now attach to tracee\n");
5591.1Skamil
5601.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5611.1Skamil		/* Wait for message from the parent */
5621.1Skamil		_exit(exitval_tracee);
5631.1Skamil	}
5641.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5651.1Skamil
5661.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5681.1Skamil
5691.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5701.1Skamil	    TWAIT_FNAME);
5711.1Skamil	TWAIT_REQUIRE_SUCCESS(
5721.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5731.1Skamil
5741.1Skamil	validate_status_stopped(status, SIGSTOP);
5751.1Skamil
5761.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5781.1Skamil
5791.13Schristos	DPRINTF("Let the tracee exit now\n");
5801.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5811.1Skamil
5821.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5831.1Skamil	TWAIT_REQUIRE_SUCCESS(
5841.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5851.1Skamil
5861.1Skamil	validate_status_exited(status, exitval_tracee);
5871.1Skamil
5881.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5891.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5901.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5911.1Skamil
5921.1Skamil	msg_close(&parent_tracee);
5931.1Skamil}
5941.1Skamil
5951.1SkamilATF_TC(attach4);
5961.1SkamilATF_TC_HEAD(attach4, tc)
5971.1Skamil{
5981.1Skamil	atf_tc_set_md_var(tc, "descr",
5991.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
6001.1Skamil}
6011.1Skamil
6021.1SkamilATF_TC_BODY(attach4, tc)
6031.1Skamil{
6041.1Skamil	struct msg_fds parent_tracee;
6051.1Skamil	const int exitval_tracer = 5;
6061.1Skamil	pid_t tracer, wpid;
6071.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6081.1Skamil#if defined(TWAIT_HAVE_STATUS)
6091.1Skamil	int status;
6101.1Skamil#endif
6111.1Skamil
6121.13Schristos	DPRINTF("Spawn tracer\n");
6131.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6141.1Skamil	tracer = atf_utils_fork();
6151.1Skamil	if (tracer == 0) {
6161.1Skamil
6171.1Skamil		/* Wait for message from the parent */
6181.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
6191.1Skamil
6201.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
6211.1Skamil		    getppid());
6221.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
6231.1Skamil
6241.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
6251.1Skamil		    TWAIT_FNAME);
6261.1Skamil		FORKEE_REQUIRE_SUCCESS(
6271.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
6281.1Skamil
6291.1Skamil		forkee_status_stopped(status, SIGSTOP);
6301.1Skamil
6311.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
6321.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
6331.1Skamil		    != -1);
6341.1Skamil
6351.1Skamil		/* Tell parent we are ready */
6361.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
6371.1Skamil
6381.1Skamil		_exit(exitval_tracer);
6391.1Skamil	}
6401.1Skamil
6411.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
6421.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6431.13Schristos	DPRINTF("Allow the tracer to exit now\n");
6441.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
6451.1Skamil
6461.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
6471.1Skamil	TWAIT_REQUIRE_SUCCESS(
6481.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6491.1Skamil
6501.1Skamil	validate_status_exited(status, exitval_tracer);
6511.1Skamil
6521.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
6531.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6541.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
6551.1Skamil
6561.1Skamil	msg_close(&parent_tracee);
6571.1Skamil}
6581.1Skamil
6591.1Skamil#if defined(TWAIT_HAVE_PID)
6601.1SkamilATF_TC(attach5);
6611.1SkamilATF_TC_HEAD(attach5, tc)
6621.1Skamil{
6631.1Skamil	atf_tc_set_md_var(tc, "descr",
6641.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6651.1Skamil	    "(check getppid(2))");
6661.1Skamil}
6671.1Skamil
6681.1SkamilATF_TC_BODY(attach5, tc)
6691.1Skamil{
6701.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6711.1Skamil	const int exitval_tracee = 5;
6721.1Skamil	const int exitval_tracer = 10;
6731.1Skamil	pid_t parent, tracee, tracer, wpid;
6741.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6751.1Skamil#if defined(TWAIT_HAVE_STATUS)
6761.1Skamil	int status;
6771.1Skamil#endif
6781.1Skamil
6791.13Schristos	DPRINTF("Spawn tracee\n");
6801.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6811.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6821.1Skamil	tracee = atf_utils_fork();
6831.1Skamil	if (tracee == 0) {
6841.1Skamil		parent = getppid();
6851.1Skamil
6861.1Skamil		/* Emit message to the parent */
6871.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6881.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6891.1Skamil
6901.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6911.1Skamil
6921.1Skamil		_exit(exitval_tracee);
6931.1Skamil	}
6941.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6951.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6961.1Skamil
6971.13Schristos	DPRINTF("Spawn debugger\n");
6981.1Skamil	tracer = atf_utils_fork();
6991.1Skamil	if (tracer == 0) {
7001.1Skamil		/* No IPC to communicate with the child */
7011.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
7021.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7031.1Skamil
7041.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
7051.1Skamil		FORKEE_REQUIRE_SUCCESS(
7061.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7071.1Skamil
7081.1Skamil		forkee_status_stopped(status, SIGSTOP);
7091.1Skamil
7101.1Skamil		/* Resume tracee with PT_CONTINUE */
7111.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7121.1Skamil
7131.1Skamil		/* Inform parent that tracer has attached to tracee */
7141.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
7151.1Skamil
7161.1Skamil		/* Wait for parent to tell use that tracee should have exited */
7171.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
7181.1Skamil
7191.1Skamil		/* Wait for tracee and assert that it exited */
7201.1Skamil		FORKEE_REQUIRE_SUCCESS(
7211.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7221.1Skamil
7231.1Skamil		forkee_status_exited(status, exitval_tracee);
7241.1Skamil
7251.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7261.1Skamil		_exit(exitval_tracer);
7271.1Skamil	}
7281.1Skamil
7291.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7301.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
7311.1Skamil
7321.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7331.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
7341.1Skamil
7351.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7361.1Skamil	await_zombie(tracee);
7371.1Skamil
7381.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7391.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7401.1Skamil	TWAIT_REQUIRE_SUCCESS(
7411.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7421.1Skamil
7431.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7441.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
7451.1Skamil
7461.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7481.1Skamil	    tracer);
7491.1Skamil
7501.1Skamil	validate_status_exited(status, exitval_tracer);
7511.1Skamil
7521.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7531.1Skamil	    TWAIT_FNAME);
7541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7551.1Skamil	    tracee);
7561.1Skamil
7571.1Skamil	validate_status_exited(status, exitval_tracee);
7581.1Skamil
7591.1Skamil	msg_close(&parent_tracer);
7601.1Skamil	msg_close(&parent_tracee);
7611.1Skamil}
7621.1Skamil#endif
7631.1Skamil
7641.1Skamil#if defined(TWAIT_HAVE_PID)
7651.1SkamilATF_TC(attach6);
7661.1SkamilATF_TC_HEAD(attach6, tc)
7671.1Skamil{
7681.1Skamil	atf_tc_set_md_var(tc, "descr",
7691.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7701.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7711.1Skamil}
7721.1Skamil
7731.1SkamilATF_TC_BODY(attach6, tc)
7741.1Skamil{
7751.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7761.1Skamil	const int exitval_tracee = 5;
7771.1Skamil	const int exitval_tracer = 10;
7781.1Skamil	pid_t parent, tracee, tracer, wpid;
7791.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7801.1Skamil#if defined(TWAIT_HAVE_STATUS)
7811.1Skamil	int status;
7821.1Skamil#endif
7831.1Skamil	int name[CTL_MAXNAME];
7841.1Skamil	struct kinfo_proc2 kp;
7851.1Skamil	size_t len = sizeof(kp);
7861.1Skamil	unsigned int namelen;
7871.1Skamil
7881.13Schristos	DPRINTF("Spawn tracee\n");
7891.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7901.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7911.1Skamil	tracee = atf_utils_fork();
7921.1Skamil	if (tracee == 0) {
7931.1Skamil		parent = getppid();
7941.1Skamil
7951.1Skamil		/* Emit message to the parent */
7961.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7971.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7981.1Skamil
7991.1Skamil		namelen = 0;
8001.1Skamil		name[namelen++] = CTL_KERN;
8011.1Skamil		name[namelen++] = KERN_PROC2;
8021.1Skamil		name[namelen++] = KERN_PROC_PID;
8031.1Skamil		name[namelen++] = getpid();
8041.1Skamil		name[namelen++] = len;
8051.1Skamil		name[namelen++] = 1;
8061.1Skamil
8071.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
8081.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
8091.1Skamil
8101.1Skamil		_exit(exitval_tracee);
8111.1Skamil	}
8121.1Skamil
8131.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
8141.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
8151.1Skamil
8161.13Schristos	DPRINTF("Spawn debugger\n");
8171.1Skamil	tracer = atf_utils_fork();
8181.1Skamil	if (tracer == 0) {
8191.1Skamil		/* No IPC to communicate with the child */
8201.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8211.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8221.1Skamil
8231.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8241.1Skamil		FORKEE_REQUIRE_SUCCESS(
8251.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8261.1Skamil
8271.1Skamil		forkee_status_stopped(status, SIGSTOP);
8281.1Skamil
8291.1Skamil		/* Resume tracee with PT_CONTINUE */
8301.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8311.1Skamil
8321.1Skamil		/* Inform parent that tracer has attached to tracee */
8331.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8341.1Skamil
8351.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8361.1Skamil
8371.1Skamil		/* Wait for tracee and assert that it exited */
8381.1Skamil		FORKEE_REQUIRE_SUCCESS(
8391.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8401.1Skamil
8411.1Skamil		forkee_status_exited(status, exitval_tracee);
8421.1Skamil
8431.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8441.1Skamil		_exit(exitval_tracer);
8451.1Skamil	}
8461.1Skamil
8471.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8481.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8491.1Skamil
8501.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8511.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8521.1Skamil
8531.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8541.1Skamil	await_zombie(tracee);
8551.1Skamil
8561.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8571.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8581.1Skamil	TWAIT_REQUIRE_SUCCESS(
8591.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8601.1Skamil
8611.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8621.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8631.1Skamil
8641.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8651.1Skamil	    TWAIT_FNAME);
8661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8671.1Skamil	    tracer);
8681.1Skamil
8691.1Skamil	validate_status_exited(status, exitval_tracer);
8701.1Skamil
8711.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8721.1Skamil	    TWAIT_FNAME);
8731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8741.1Skamil	    tracee);
8751.1Skamil
8761.1Skamil	validate_status_exited(status, exitval_tracee);
8771.1Skamil
8781.1Skamil	msg_close(&parent_tracee);
8791.1Skamil	msg_close(&parent_tracer);
8801.1Skamil}
8811.1Skamil#endif
8821.1Skamil
8831.1Skamil#if defined(TWAIT_HAVE_PID)
8841.1SkamilATF_TC(attach7);
8851.1SkamilATF_TC_HEAD(attach7, tc)
8861.1Skamil{
8871.1Skamil	atf_tc_set_md_var(tc, "descr",
8881.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8891.1Skamil	    "(check /proc/curproc/status 3rd column)");
8901.1Skamil}
8911.1Skamil
8921.1SkamilATF_TC_BODY(attach7, tc)
8931.1Skamil{
8941.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8951.1Skamil	int rv;
8961.1Skamil	const int exitval_tracee = 5;
8971.1Skamil	const int exitval_tracer = 10;
8981.1Skamil	pid_t parent, tracee, tracer, wpid;
8991.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
9001.1Skamil#if defined(TWAIT_HAVE_STATUS)
9011.1Skamil	int status;
9021.1Skamil#endif
9031.1Skamil	FILE *fp;
9041.1Skamil	struct stat st;
9051.1Skamil	const char *fname = "/proc/curproc/status";
9061.1Skamil	char s_executable[MAXPATHLEN];
9071.1Skamil	int s_pid, s_ppid;
9081.1Skamil	/*
9091.1Skamil	 * Format:
9101.1Skamil	 *  EXECUTABLE PID PPID ...
9111.1Skamil	 */
9121.1Skamil
9131.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
9141.1Skamil	if (rv != 0) {
9151.1Skamil		atf_tc_skip("/proc/curproc/status not found");
9161.1Skamil	}
9171.1Skamil
9181.13Schristos	DPRINTF("Spawn tracee\n");
9191.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9201.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
9211.1Skamil	tracee = atf_utils_fork();
9221.1Skamil	if (tracee == 0) {
9231.1Skamil		parent = getppid();
9241.1Skamil
9251.1Skamil		// Wait for parent to let us exit
9261.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
9271.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
9281.1Skamil
9291.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
9301.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
9311.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
9321.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
9331.1Skamil
9341.1Skamil		_exit(exitval_tracee);
9351.1Skamil	}
9361.1Skamil
9371.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9381.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
9391.1Skamil
9401.13Schristos	DPRINTF("Spawn debugger\n");
9411.1Skamil	tracer = atf_utils_fork();
9421.1Skamil	if (tracer == 0) {
9431.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9441.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9451.1Skamil
9461.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9471.1Skamil		FORKEE_REQUIRE_SUCCESS(
9481.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9491.1Skamil
9501.1Skamil		forkee_status_stopped(status, SIGSTOP);
9511.1Skamil
9521.1Skamil		/* Resume tracee with PT_CONTINUE */
9531.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9541.1Skamil
9551.1Skamil		/* Inform parent that tracer has attached to tracee */
9561.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9571.1Skamil
9581.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9591.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9601.1Skamil
9611.1Skamil		/* Wait for tracee and assert that it exited */
9621.1Skamil		FORKEE_REQUIRE_SUCCESS(
9631.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9641.1Skamil
9651.1Skamil		forkee_status_exited(status, exitval_tracee);
9661.1Skamil
9671.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9681.1Skamil		_exit(exitval_tracer);
9691.1Skamil	}
9701.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9711.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9721.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9731.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9741.1Skamil
9751.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9761.1Skamil	await_zombie(tracee);
9771.1Skamil
9781.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9791.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9801.1Skamil	TWAIT_REQUIRE_SUCCESS(
9811.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9821.1Skamil
9831.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9841.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9851.1Skamil
9861.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9871.1Skamil	    TWAIT_FNAME);
9881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9891.1Skamil	    tracer);
9901.1Skamil
9911.1Skamil	validate_status_exited(status, exitval_tracer);
9921.1Skamil
9931.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9941.1Skamil	    TWAIT_FNAME);
9951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9961.1Skamil	    tracee);
9971.1Skamil
9981.1Skamil	validate_status_exited(status, exitval_tracee);
9991.1Skamil
10001.1Skamil	msg_close(&parent_tracee);
10011.1Skamil	msg_close(&parent_tracer);
10021.1Skamil}
10031.1Skamil#endif
10041.1Skamil
10051.1SkamilATF_TC(eventmask1);
10061.1SkamilATF_TC_HEAD(eventmask1, tc)
10071.1Skamil{
10081.1Skamil	atf_tc_set_md_var(tc, "descr",
10091.1Skamil	    "Verify that empty EVENT_MASK is preserved");
10101.1Skamil}
10111.1Skamil
10121.1SkamilATF_TC_BODY(eventmask1, tc)
10131.1Skamil{
10141.1Skamil	const int exitval = 5;
10151.1Skamil	const int sigval = SIGSTOP;
10161.1Skamil	pid_t child, wpid;
10171.1Skamil#if defined(TWAIT_HAVE_STATUS)
10181.1Skamil	int status;
10191.1Skamil#endif
10201.1Skamil	ptrace_event_t set_event, get_event;
10211.1Skamil	const int len = sizeof(ptrace_event_t);
10221.1Skamil
10231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10251.1Skamil	if (child == 0) {
10261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10281.1Skamil
10291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10311.1Skamil
10321.13Schristos		DPRINTF("Before exiting of the child process\n");
10331.1Skamil		_exit(exitval);
10341.1Skamil	}
10351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10361.1Skamil
10371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10391.1Skamil
10401.1Skamil	validate_status_stopped(status, sigval);
10411.1Skamil
10421.1Skamil	set_event.pe_set_event = 0;
10431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10451.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10461.1Skamil
10471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10481.1Skamil	    "without signal to be sent\n");
10491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10501.1Skamil
10511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10531.1Skamil
10541.1Skamil	validate_status_exited(status, exitval);
10551.1Skamil
10561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10581.1Skamil}
10591.1Skamil
10601.1SkamilATF_TC(eventmask2);
10611.1SkamilATF_TC_HEAD(eventmask2, tc)
10621.1Skamil{
10631.1Skamil	atf_tc_set_md_var(tc, "descr",
10641.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10651.1Skamil}
10661.1Skamil
10671.1SkamilATF_TC_BODY(eventmask2, tc)
10681.1Skamil{
10691.1Skamil	const int exitval = 5;
10701.1Skamil	const int sigval = SIGSTOP;
10711.1Skamil	pid_t child, wpid;
10721.1Skamil#if defined(TWAIT_HAVE_STATUS)
10731.1Skamil	int status;
10741.1Skamil#endif
10751.1Skamil	ptrace_event_t set_event, get_event;
10761.1Skamil	const int len = sizeof(ptrace_event_t);
10771.1Skamil
10781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10801.1Skamil	if (child == 0) {
10811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10831.1Skamil
10841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10861.1Skamil
10871.13Schristos		DPRINTF("Before exiting of the child process\n");
10881.1Skamil		_exit(exitval);
10891.1Skamil	}
10901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10911.1Skamil
10921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10941.1Skamil
10951.1Skamil	validate_status_stopped(status, sigval);
10961.1Skamil
10971.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11001.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11011.1Skamil
11021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11031.1Skamil	    "without signal to be sent\n");
11041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11051.1Skamil
11061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11081.1Skamil
11091.1Skamil	validate_status_exited(status, exitval);
11101.1Skamil
11111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11131.1Skamil}
11141.1Skamil
11151.1SkamilATF_TC(eventmask3);
11161.1SkamilATF_TC_HEAD(eventmask3, tc)
11171.1Skamil{
11181.1Skamil	atf_tc_set_md_var(tc, "descr",
11191.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
11201.1Skamil}
11211.1Skamil
11221.1SkamilATF_TC_BODY(eventmask3, tc)
11231.1Skamil{
11241.1Skamil	const int exitval = 5;
11251.1Skamil	const int sigval = SIGSTOP;
11261.1Skamil	pid_t child, wpid;
11271.1Skamil#if defined(TWAIT_HAVE_STATUS)
11281.1Skamil	int status;
11291.1Skamil#endif
11301.1Skamil	ptrace_event_t set_event, get_event;
11311.1Skamil	const int len = sizeof(ptrace_event_t);
11321.1Skamil
11331.14Schristos	atf_tc_expect_fail("PR kern/51630");
11341.14Schristos
11351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11371.1Skamil	if (child == 0) {
11381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11401.1Skamil
11411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11431.1Skamil
11441.13Schristos		DPRINTF("Before exiting of the child process\n");
11451.1Skamil		_exit(exitval);
11461.1Skamil	}
11471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11481.1Skamil
11491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11511.1Skamil
11521.1Skamil	validate_status_stopped(status, sigval);
11531.1Skamil
11541.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
11551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
11561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11571.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11581.1Skamil
11591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11601.1Skamil	    "without signal to be sent\n");
11611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11621.1Skamil
11631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11651.1Skamil
11661.1Skamil	validate_status_exited(status, exitval);
11671.1Skamil
11681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11701.1Skamil}
11711.1Skamil
11721.1SkamilATF_TC(eventmask4);
11731.1SkamilATF_TC_HEAD(eventmask4, tc)
11741.1Skamil{
11751.1Skamil	atf_tc_set_md_var(tc, "descr",
11761.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11771.1Skamil}
11781.1Skamil
11791.1SkamilATF_TC_BODY(eventmask4, tc)
11801.1Skamil{
11811.1Skamil	const int exitval = 5;
11821.1Skamil	const int sigval = SIGSTOP;
11831.1Skamil	pid_t child, wpid;
11841.1Skamil#if defined(TWAIT_HAVE_STATUS)
11851.1Skamil	int status;
11861.1Skamil#endif
11871.1Skamil	ptrace_event_t set_event, get_event;
11881.1Skamil	const int len = sizeof(ptrace_event_t);
11891.1Skamil
11901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11921.1Skamil	if (child == 0) {
11931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11951.1Skamil
11961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11981.1Skamil
11991.13Schristos		DPRINTF("Before exiting of the child process\n");
12001.1Skamil		_exit(exitval);
12011.1Skamil	}
12021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12031.1Skamil
12041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12061.1Skamil
12071.1Skamil	validate_status_stopped(status, sigval);
12081.1Skamil
12091.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
12101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12121.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12131.1Skamil
12141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12151.1Skamil	    "without signal to be sent\n");
12161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12171.1Skamil
12181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12201.1Skamil
12211.1Skamil	validate_status_exited(status, exitval);
12221.1Skamil
12231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12251.1Skamil}
12261.1Skamil
12271.1SkamilATF_TC(eventmask5);
12281.1SkamilATF_TC_HEAD(eventmask5, tc)
12291.1Skamil{
12301.1Skamil	atf_tc_set_md_var(tc, "descr",
12311.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
12321.1Skamil}
12331.1Skamil
12341.1SkamilATF_TC_BODY(eventmask5, tc)
12351.1Skamil{
12361.1Skamil	const int exitval = 5;
12371.1Skamil	const int sigval = SIGSTOP;
12381.1Skamil	pid_t child, wpid;
12391.1Skamil#if defined(TWAIT_HAVE_STATUS)
12401.1Skamil	int status;
12411.1Skamil#endif
12421.1Skamil	ptrace_event_t set_event, get_event;
12431.1Skamil	const int len = sizeof(ptrace_event_t);
12441.1Skamil
12451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12471.1Skamil	if (child == 0) {
12481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12501.1Skamil
12511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12531.1Skamil
12541.13Schristos		DPRINTF("Before exiting of the child process\n");
12551.1Skamil		_exit(exitval);
12561.1Skamil	}
12571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12581.1Skamil
12591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12611.1Skamil
12621.1Skamil	validate_status_stopped(status, sigval);
12631.1Skamil
12641.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12671.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12681.1Skamil
12691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12701.1Skamil	    "without signal to be sent\n");
12711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12721.1Skamil
12731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12751.1Skamil
12761.1Skamil	validate_status_exited(status, exitval);
12771.1Skamil
12781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12801.1Skamil}
12811.1Skamil
12821.1SkamilATF_TC(eventmask6);
12831.1SkamilATF_TC_HEAD(eventmask6, tc)
12841.1Skamil{
12851.1Skamil	atf_tc_set_md_var(tc, "descr",
12861.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12871.1Skamil}
12881.1Skamil
12891.1SkamilATF_TC_BODY(eventmask6, tc)
12901.1Skamil{
12911.1Skamil	const int exitval = 5;
12921.1Skamil	const int sigval = SIGSTOP;
12931.1Skamil	pid_t child, wpid;
12941.1Skamil#if defined(TWAIT_HAVE_STATUS)
12951.1Skamil	int status;
12961.1Skamil#endif
12971.1Skamil	ptrace_event_t set_event, get_event;
12981.1Skamil	const int len = sizeof(ptrace_event_t);
12991.1Skamil
13001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13021.1Skamil	if (child == 0) {
13031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13051.1Skamil
13061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13081.1Skamil
13091.13Schristos		DPRINTF("Before exiting of the child process\n");
13101.1Skamil		_exit(exitval);
13111.1Skamil	}
13121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13131.1Skamil
13141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13161.1Skamil
13171.1Skamil	validate_status_stopped(status, sigval);
13181.1Skamil
13191.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
13201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13221.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13231.1Skamil
13241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13251.1Skamil	    "without signal to be sent\n");
13261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13271.1Skamil
13281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13301.1Skamil
13311.1Skamil	validate_status_exited(status, exitval);
13321.1Skamil
13331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13351.1Skamil}
13361.1Skamil
13371.28Skamilstatic void
13381.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
13391.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
13401.1Skamil{
13411.1Skamil	const int exitval = 5;
13421.1Skamil	const int exitval2 = 15;
13431.1Skamil	const int sigval = SIGSTOP;
13441.31Skamil	pid_t child, child2 = 0, wpid;
13451.1Skamil#if defined(TWAIT_HAVE_STATUS)
13461.1Skamil	int status;
13471.1Skamil#endif
13481.1Skamil	ptrace_state_t state;
13491.1Skamil	const int slen = sizeof(state);
13501.1Skamil	ptrace_event_t event;
13511.1Skamil	const int elen = sizeof(event);
13521.1Skamil
13531.30Skamil	if (trackvfork) {
13541.28Skamil		atf_tc_expect_fail("PR kern/51630");
13551.28Skamil	}
13561.28Skamil
13571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13591.1Skamil	if (child == 0) {
13601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13621.1Skamil
13631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13651.1Skamil
13661.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
13671.1Skamil
13681.1Skamil		if (child2 == 0)
13691.1Skamil			_exit(exitval2);
13701.1Skamil
13711.1Skamil		FORKEE_REQUIRE_SUCCESS
13721.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13731.1Skamil
13741.1Skamil		forkee_status_exited(status, exitval2);
13751.1Skamil
13761.13Schristos		DPRINTF("Before exiting of the child process\n");
13771.1Skamil		_exit(exitval);
13781.1Skamil	}
13791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13801.1Skamil
13811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13831.1Skamil
13841.1Skamil	validate_status_stopped(status, sigval);
13851.1Skamil
13861.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
13871.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
13881.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
13891.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
13901.30Skamil	event.pe_set_event = 0;
13911.30Skamil	if (trackfork)
13921.30Skamil		event.pe_set_event |= PTRACE_FORK;
13931.30Skamil	if (trackvfork)
13941.30Skamil		event.pe_set_event |= PTRACE_VFORK;
13951.30Skamil	if (trackvforkdone)
13961.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
13971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13981.1Skamil
13991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14001.1Skamil	    "without signal to be sent\n");
14011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14021.1Skamil
14031.29Skamil#if defined(TWAIT_HAVE_PID)
14041.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
14051.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
14061.29Skamil		        child);
14071.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
14081.29Skamil		                      child);
14091.1Skamil
14101.29Skamil		validate_status_stopped(status, SIGTRAP);
14111.1Skamil
14121.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
14131.29Skamil		                       slen) != -1);
14141.31Skamil		if (trackfork && fn == fork) {
14151.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
14161.30Skamil			       PTRACE_FORK);
14171.30Skamil		}
14181.31Skamil		if (trackvfork && fn == vfork) {
14191.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
14201.30Skamil			       PTRACE_VFORK);
14211.30Skamil		}
14221.29Skamil
14231.29Skamil		child2 = state.pe_other_pid;
14241.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
14251.29Skamil
14261.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
14271.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
14281.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14291.29Skamil		    child2);
14301.1Skamil
14311.29Skamil		validate_status_stopped(status, SIGTRAP);
14321.1Skamil
14331.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
14341.29Skamil		                       slen) != -1);
14351.31Skamil		if (trackfork && fn == fork) {
14361.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
14371.30Skamil			       PTRACE_FORK);
14381.30Skamil		}
14391.31Skamil		if (trackvfork && fn == vfork) {
14401.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
14411.30Skamil			       PTRACE_VFORK);
14421.30Skamil		}
14431.30Skamil
14441.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
14451.29Skamil
14461.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
14471.29Skamil		    "and without signal to be sent\n");
14481.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
14491.29Skamil		                != -1);
14501.29Skamil
14511.29Skamil		DPRINTF("Before resuming the child process where it left off "
14521.29Skamil		        "and without signal to be sent\n");
14531.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14541.30Skamil	}
14551.30Skamil#endif
14561.30Skamil
14571.31Skamil	if (trackvforkdone && fn == vfork) {
14581.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
14591.30Skamil		        child);
14601.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
14611.30Skamil		                      child);
14621.30Skamil
14631.30Skamil		validate_status_stopped(status, SIGTRAP);
14641.30Skamil
14651.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
14661.30Skamil		                       slen) != -1);
14671.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
14681.30Skamil
14691.30Skamil		child2 = state.pe_other_pid;
14701.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
14711.30Skamil		        child2);
14721.30Skamil
14731.30Skamil		DPRINTF("Before resuming the child process where it left off "
14741.30Skamil		        "and without signal to be sent\n");
14751.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14761.30Skamil	}
14771.29Skamil
14781.30Skamil#if defined(TWAIT_HAVE_PID)
14791.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
14801.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
14811.29Skamil		        "\n", TWAIT_FNAME);
14821.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14831.29Skamil		    child2);
14841.29Skamil
14851.29Skamil		validate_status_exited(status, exitval2);
14861.29Skamil
14871.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
14881.29Skamil		        "process\n", TWAIT_FNAME);
14891.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
14901.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
14911.29Skamil	}
14921.29Skamil#endif
14931.1Skamil
14941.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14951.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14971.1Skamil
14981.1Skamil	validate_status_stopped(status, SIGCHLD);
14991.1Skamil
15001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15011.1Skamil	    "without signal to be sent\n");
15021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15031.1Skamil
15041.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
15051.1Skamil	    TWAIT_FNAME);
15061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15071.1Skamil
15081.1Skamil	validate_status_exited(status, exitval);
15091.1Skamil
15101.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
15111.1Skamil	    TWAIT_FNAME);
15121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15131.1Skamil}
15141.28Skamil
15151.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
15161.32SkamilATF_TC(name);									\
15171.32SkamilATF_TC_HEAD(name, tc)								\
15181.32Skamil{										\
15191.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
15201.32Skamil}										\
15211.32Skamil										\
15221.32SkamilATF_TC_BODY(name, tc)								\
15231.32Skamil{										\
15241.32Skamil										\
15251.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
15261.32Skamil}
15271.32Skamil
15281.32Skamil#define F false
15291.32Skamil#define T true
15301.32Skamil
15311.32Skamil#define F_IF__0(x)
15321.32Skamil#define F_IF__1(x) x
15331.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
15341.32Skamil#define F_IF_(x,y) F_IF__(x,y)
15351.32Skamil#define F_IF(x,y) F_IF_(x,y)
15361.32Skamil
15371.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
15381.32Skamil        "Verify " #function "(2) called with 0"					\
15391.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
15401.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
15411.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
15421.32Skamil        " in EVENT_MASK."							\
15431.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
15441.32Skamil        F_IF(dparentbit," Detach parent in this test.")
15451.1Skamil
15461.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
15471.31Skamil#if defined(TWAIT_HAVE_PID)
15481.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
15491.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
15501.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
15511.31Skamil#endif
15521.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
15531.31Skamil#if defined(TWAIT_HAVE_PID)
15541.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
15551.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
15561.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
15571.31Skamil#endif
15581.1Skamil
15591.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
15601.31Skamil#if defined(TWAIT_HAVE_PID)
15611.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
15621.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
15631.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
15641.31Skamil#endif
15651.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
15661.31Skamil#if defined(TWAIT_HAVE_PID)
15671.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
15681.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
15691.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
15701.31Skamil#endif
15711.31Skamil
15721.31Skamil
15731.31Skamil
15741.1Skamil
15751.1SkamilATF_TC(io_read_d1);
15761.1SkamilATF_TC_HEAD(io_read_d1, tc)
15771.1Skamil{
15781.1Skamil	atf_tc_set_md_var(tc, "descr",
15791.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
15801.1Skamil}
15811.1Skamil
15821.1SkamilATF_TC_BODY(io_read_d1, tc)
15831.1Skamil{
15841.1Skamil	const int exitval = 5;
15851.1Skamil	const int sigval = SIGSTOP;
15861.1Skamil	pid_t child, wpid;
15871.1Skamil	uint8_t lookup_me = 0;
15881.1Skamil	const uint8_t magic = 0xab;
15891.1Skamil	struct ptrace_io_desc io = {
15901.1Skamil		.piod_op = PIOD_READ_D,
15911.1Skamil		.piod_offs = &lookup_me,
15921.1Skamil		.piod_addr = &lookup_me,
15931.1Skamil		.piod_len = sizeof(lookup_me)
15941.1Skamil	};
15951.1Skamil#if defined(TWAIT_HAVE_STATUS)
15961.1Skamil	int status;
15971.1Skamil#endif
15981.1Skamil
15991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16011.1Skamil	if (child == 0) {
16021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16041.1Skamil
16051.1Skamil		lookup_me = magic;
16061.1Skamil
16071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16091.1Skamil
16101.13Schristos		DPRINTF("Before exiting of the child process\n");
16111.1Skamil		_exit(exitval);
16121.1Skamil	}
16131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16141.1Skamil
16151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16171.1Skamil
16181.1Skamil	validate_status_stopped(status, sigval);
16191.1Skamil
16201.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16211.1Skamil	    child, getpid());
16221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16231.1Skamil
16241.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16251.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
16261.1Skamil
16271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16281.1Skamil	    "without signal to be sent\n");
16291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16301.1Skamil
16311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16331.1Skamil
16341.1Skamil	validate_status_exited(status, exitval);
16351.1Skamil
16361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16381.1Skamil}
16391.1Skamil
16401.1SkamilATF_TC(io_read_d2);
16411.1SkamilATF_TC_HEAD(io_read_d2, tc)
16421.1Skamil{
16431.1Skamil	atf_tc_set_md_var(tc, "descr",
16441.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
16451.1Skamil}
16461.1Skamil
16471.1SkamilATF_TC_BODY(io_read_d2, tc)
16481.1Skamil{
16491.1Skamil	const int exitval = 5;
16501.1Skamil	const int sigval = SIGSTOP;
16511.1Skamil	pid_t child, wpid;
16521.1Skamil	uint16_t lookup_me = 0;
16531.1Skamil	const uint16_t magic = 0x1234;
16541.1Skamil	struct ptrace_io_desc io = {
16551.1Skamil		.piod_op = PIOD_READ_D,
16561.1Skamil		.piod_offs = &lookup_me,
16571.1Skamil		.piod_addr = &lookup_me,
16581.1Skamil		.piod_len = sizeof(lookup_me)
16591.1Skamil	};
16601.1Skamil#if defined(TWAIT_HAVE_STATUS)
16611.1Skamil	int status;
16621.1Skamil#endif
16631.1Skamil
16641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16661.1Skamil	if (child == 0) {
16671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16691.1Skamil
16701.1Skamil		lookup_me = magic;
16711.1Skamil
16721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16741.1Skamil
16751.13Schristos		DPRINTF("Before exiting of the child process\n");
16761.1Skamil		_exit(exitval);
16771.1Skamil	}
16781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16791.1Skamil
16801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16821.1Skamil
16831.1Skamil	validate_status_stopped(status, sigval);
16841.1Skamil
16851.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16861.1Skamil	    child, getpid());
16871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16881.1Skamil
16891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16901.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
16911.1Skamil
16921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16931.1Skamil	    "without signal to be sent\n");
16941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16951.1Skamil
16961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16981.1Skamil
16991.1Skamil	validate_status_exited(status, exitval);
17001.1Skamil
17011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17021.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17031.1Skamil}
17041.1Skamil
17051.1SkamilATF_TC(io_read_d3);
17061.1SkamilATF_TC_HEAD(io_read_d3, tc)
17071.1Skamil{
17081.1Skamil	atf_tc_set_md_var(tc, "descr",
17091.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
17101.1Skamil}
17111.1Skamil
17121.1SkamilATF_TC_BODY(io_read_d3, tc)
17131.1Skamil{
17141.1Skamil	const int exitval = 5;
17151.1Skamil	const int sigval = SIGSTOP;
17161.1Skamil	pid_t child, wpid;
17171.1Skamil	uint32_t lookup_me = 0;
17181.1Skamil	const uint32_t magic = 0x1234abcd;
17191.1Skamil	struct ptrace_io_desc io = {
17201.1Skamil		.piod_op = PIOD_READ_D,
17211.1Skamil		.piod_offs = &lookup_me,
17221.1Skamil		.piod_addr = &lookup_me,
17231.1Skamil		.piod_len = sizeof(lookup_me)
17241.1Skamil	};
17251.1Skamil#if defined(TWAIT_HAVE_STATUS)
17261.1Skamil	int status;
17271.1Skamil#endif
17281.1Skamil
17291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17311.1Skamil	if (child == 0) {
17321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17341.1Skamil
17351.1Skamil		lookup_me = magic;
17361.1Skamil
17371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17391.1Skamil
17401.13Schristos		DPRINTF("Before exiting of the child process\n");
17411.1Skamil		_exit(exitval);
17421.1Skamil	}
17431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17441.1Skamil
17451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17471.1Skamil
17481.1Skamil	validate_status_stopped(status, sigval);
17491.1Skamil
17501.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
17511.1Skamil	    child, getpid());
17521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
17531.1Skamil
17541.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
17551.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
17561.1Skamil
17571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17581.1Skamil	    "without signal to be sent\n");
17591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17601.1Skamil
17611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17631.1Skamil
17641.1Skamil	validate_status_exited(status, exitval);
17651.1Skamil
17661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17681.1Skamil}
17691.1Skamil
17701.1SkamilATF_TC(io_read_d4);
17711.1SkamilATF_TC_HEAD(io_read_d4, tc)
17721.1Skamil{
17731.1Skamil	atf_tc_set_md_var(tc, "descr",
17741.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
17751.1Skamil}
17761.1Skamil
17771.1SkamilATF_TC_BODY(io_read_d4, tc)
17781.1Skamil{
17791.1Skamil	const int exitval = 5;
17801.1Skamil	const int sigval = SIGSTOP;
17811.1Skamil	pid_t child, wpid;
17821.1Skamil	uint64_t lookup_me = 0;
17831.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
17841.1Skamil	struct ptrace_io_desc io = {
17851.1Skamil		.piod_op = PIOD_READ_D,
17861.1Skamil		.piod_offs = &lookup_me,
17871.1Skamil		.piod_addr = &lookup_me,
17881.1Skamil		.piod_len = sizeof(lookup_me)
17891.1Skamil	};
17901.1Skamil#if defined(TWAIT_HAVE_STATUS)
17911.1Skamil	int status;
17921.1Skamil#endif
17931.1Skamil
17941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17961.1Skamil	if (child == 0) {
17971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17991.1Skamil
18001.1Skamil		lookup_me = magic;
18011.1Skamil
18021.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18031.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18041.1Skamil
18051.13Schristos		DPRINTF("Before exiting of the child process\n");
18061.1Skamil		_exit(exitval);
18071.1Skamil	}
18081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18091.1Skamil
18101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18121.1Skamil
18131.1Skamil	validate_status_stopped(status, sigval);
18141.1Skamil
18151.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
18161.1Skamil	    child, getpid());
18171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18181.1Skamil
18191.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
18201.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
18211.1Skamil
18221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18231.1Skamil	    "without signal to be sent\n");
18241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18251.1Skamil
18261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18281.1Skamil
18291.1Skamil	validate_status_exited(status, exitval);
18301.1Skamil
18311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18331.1Skamil}
18341.1Skamil
18351.1SkamilATF_TC(io_write_d1);
18361.1SkamilATF_TC_HEAD(io_write_d1, tc)
18371.1Skamil{
18381.1Skamil	atf_tc_set_md_var(tc, "descr",
18391.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
18401.1Skamil}
18411.1Skamil
18421.1SkamilATF_TC_BODY(io_write_d1, tc)
18431.1Skamil{
18441.1Skamil	const int exitval = 5;
18451.1Skamil	const int sigval = SIGSTOP;
18461.1Skamil	pid_t child, wpid;
18471.1Skamil	uint8_t lookup_me = 0;
18481.1Skamil	const uint8_t magic = 0xab;
18491.1Skamil	struct ptrace_io_desc io = {
18501.1Skamil		.piod_op = PIOD_WRITE_D,
18511.1Skamil		.piod_offs = &lookup_me,
18521.1Skamil		.piod_addr = &lookup_me,
18531.1Skamil		.piod_len = sizeof(lookup_me)
18541.1Skamil	};
18551.1Skamil#if defined(TWAIT_HAVE_STATUS)
18561.1Skamil	int status;
18571.1Skamil#endif
18581.1Skamil
18591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18611.1Skamil	if (child == 0) {
18621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18641.1Skamil
18651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18671.1Skamil
18681.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
18691.1Skamil
18701.13Schristos		DPRINTF("Before exiting of the child process\n");
18711.1Skamil		_exit(exitval);
18721.1Skamil	}
18731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18741.1Skamil
18751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18771.1Skamil
18781.1Skamil	validate_status_stopped(status, sigval);
18791.1Skamil
18801.1Skamil	lookup_me = magic;
18811.1Skamil
18821.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
18831.1Skamil	    child, getpid());
18841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18851.1Skamil
18861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18871.1Skamil	    "without signal to be sent\n");
18881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18891.1Skamil
18901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18921.1Skamil
18931.1Skamil	validate_status_exited(status, exitval);
18941.1Skamil
18951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18971.1Skamil}
18981.1Skamil
18991.1SkamilATF_TC(io_write_d2);
19001.1SkamilATF_TC_HEAD(io_write_d2, tc)
19011.1Skamil{
19021.1Skamil	atf_tc_set_md_var(tc, "descr",
19031.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
19041.1Skamil}
19051.1Skamil
19061.1SkamilATF_TC_BODY(io_write_d2, tc)
19071.1Skamil{
19081.1Skamil	const int exitval = 5;
19091.1Skamil	const int sigval = SIGSTOP;
19101.1Skamil	pid_t child, wpid;
19111.1Skamil	uint16_t lookup_me = 0;
19121.1Skamil	const uint16_t magic = 0xab12;
19131.1Skamil	struct ptrace_io_desc io = {
19141.1Skamil		.piod_op = PIOD_WRITE_D,
19151.1Skamil		.piod_offs = &lookup_me,
19161.1Skamil		.piod_addr = &lookup_me,
19171.1Skamil		.piod_len = sizeof(lookup_me)
19181.1Skamil	};
19191.1Skamil#if defined(TWAIT_HAVE_STATUS)
19201.1Skamil	int status;
19211.1Skamil#endif
19221.1Skamil
19231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19251.1Skamil	if (child == 0) {
19261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19281.1Skamil
19291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19311.1Skamil
19321.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19331.1Skamil
19341.13Schristos		DPRINTF("Before exiting of the child process\n");
19351.1Skamil		_exit(exitval);
19361.1Skamil	}
19371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19381.1Skamil
19391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19411.1Skamil
19421.1Skamil	validate_status_stopped(status, sigval);
19431.1Skamil
19441.1Skamil	lookup_me = magic;
19451.1Skamil
19461.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
19471.1Skamil	    child, getpid());
19481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19491.1Skamil
19501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19511.1Skamil	    "without signal to be sent\n");
19521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19531.1Skamil
19541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19561.1Skamil
19571.1Skamil	validate_status_exited(status, exitval);
19581.1Skamil
19591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19611.1Skamil}
19621.1Skamil
19631.1SkamilATF_TC(io_write_d3);
19641.1SkamilATF_TC_HEAD(io_write_d3, tc)
19651.1Skamil{
19661.1Skamil	atf_tc_set_md_var(tc, "descr",
19671.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
19681.1Skamil}
19691.1Skamil
19701.1SkamilATF_TC_BODY(io_write_d3, tc)
19711.1Skamil{
19721.1Skamil	const int exitval = 5;
19731.1Skamil	const int sigval = SIGSTOP;
19741.1Skamil	pid_t child, wpid;
19751.1Skamil	uint32_t lookup_me = 0;
19761.1Skamil	const uint32_t magic = 0xab127643;
19771.1Skamil	struct ptrace_io_desc io = {
19781.1Skamil		.piod_op = PIOD_WRITE_D,
19791.1Skamil		.piod_offs = &lookup_me,
19801.1Skamil		.piod_addr = &lookup_me,
19811.1Skamil		.piod_len = sizeof(lookup_me)
19821.1Skamil	};
19831.1Skamil#if defined(TWAIT_HAVE_STATUS)
19841.1Skamil	int status;
19851.1Skamil#endif
19861.1Skamil
19871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19891.1Skamil	if (child == 0) {
19901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19921.1Skamil
19931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19951.1Skamil
19961.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19971.1Skamil
19981.13Schristos		DPRINTF("Before exiting of the child process\n");
19991.1Skamil		_exit(exitval);
20001.1Skamil	}
20011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20021.1Skamil
20031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20051.1Skamil
20061.1Skamil	validate_status_stopped(status, sigval);
20071.1Skamil
20081.1Skamil	lookup_me = magic;
20091.1Skamil
20101.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20111.1Skamil	    child, getpid());
20121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20131.1Skamil
20141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20151.1Skamil	    "without signal to be sent\n");
20161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20171.1Skamil
20181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20201.1Skamil
20211.1Skamil	validate_status_exited(status, exitval);
20221.1Skamil
20231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20251.1Skamil}
20261.1Skamil
20271.1SkamilATF_TC(io_write_d4);
20281.1SkamilATF_TC_HEAD(io_write_d4, tc)
20291.1Skamil{
20301.1Skamil	atf_tc_set_md_var(tc, "descr",
20311.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
20321.1Skamil}
20331.1Skamil
20341.1SkamilATF_TC_BODY(io_write_d4, tc)
20351.1Skamil{
20361.1Skamil	const int exitval = 5;
20371.1Skamil	const int sigval = SIGSTOP;
20381.1Skamil	pid_t child, wpid;
20391.1Skamil	uint64_t lookup_me = 0;
20401.1Skamil	const uint64_t magic = 0xab12764376490123;
20411.1Skamil	struct ptrace_io_desc io = {
20421.1Skamil		.piod_op = PIOD_WRITE_D,
20431.1Skamil		.piod_offs = &lookup_me,
20441.1Skamil		.piod_addr = &lookup_me,
20451.1Skamil		.piod_len = sizeof(lookup_me)
20461.1Skamil	};
20471.1Skamil#if defined(TWAIT_HAVE_STATUS)
20481.1Skamil	int status;
20491.1Skamil#endif
20501.1Skamil
20511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20531.1Skamil	if (child == 0) {
20541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20561.1Skamil
20571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20591.1Skamil
20601.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
20611.1Skamil
20621.13Schristos		DPRINTF("Before exiting of the child process\n");
20631.1Skamil		_exit(exitval);
20641.1Skamil	}
20651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20661.1Skamil
20671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20691.1Skamil
20701.1Skamil	validate_status_stopped(status, sigval);
20711.1Skamil
20721.1Skamil	lookup_me = magic;
20731.1Skamil
20741.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20751.1Skamil	    child, getpid());
20761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20771.1Skamil
20781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20791.1Skamil	    "without signal to be sent\n");
20801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20811.1Skamil
20821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20841.1Skamil
20851.1Skamil	validate_status_exited(status, exitval);
20861.1Skamil
20871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20881.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20891.1Skamil}
20901.1Skamil
20911.1SkamilATF_TC(io_read_auxv1);
20921.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
20931.1Skamil{
20941.1Skamil	atf_tc_set_md_var(tc, "descr",
20951.1Skamil	    "Verify PT_READ_AUXV called for tracee");
20961.1Skamil}
20971.1Skamil
20981.1SkamilATF_TC_BODY(io_read_auxv1, tc)
20991.1Skamil{
21001.1Skamil	const int exitval = 5;
21011.1Skamil	const int sigval = SIGSTOP;
21021.1Skamil	pid_t child, wpid;
21031.1Skamil#if defined(TWAIT_HAVE_STATUS)
21041.1Skamil	int status;
21051.1Skamil#endif
21061.1Skamil	AuxInfo ai[100], *aip;
21071.1Skamil	struct ptrace_io_desc io = {
21081.1Skamil		.piod_op = PIOD_READ_AUXV,
21091.1Skamil		.piod_offs = 0,
21101.1Skamil		.piod_addr = ai,
21111.1Skamil		.piod_len = sizeof(ai)
21121.1Skamil	};
21131.1Skamil
21141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21161.1Skamil	if (child == 0) {
21171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21191.1Skamil
21201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21221.1Skamil
21231.13Schristos		DPRINTF("Before exiting of the child process\n");
21241.1Skamil		_exit(exitval);
21251.1Skamil	}
21261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21271.1Skamil
21281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21301.1Skamil
21311.1Skamil	validate_status_stopped(status, sigval);
21321.1Skamil
21331.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
21341.1Skamil	    child, getpid());
21351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21361.1Skamil
21371.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
21381.1Skamil	ATF_REQUIRE(io.piod_len > 0);
21391.1Skamil
21401.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
21411.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
21421.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
21431.1Skamil
21441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21451.1Skamil	    "without signal to be sent\n");
21461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21471.1Skamil
21481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21501.1Skamil
21511.1Skamil	validate_status_exited(status, exitval);
21521.1Skamil
21531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21551.1Skamil}
21561.1Skamil
21571.1SkamilATF_TC(read_d1);
21581.1SkamilATF_TC_HEAD(read_d1, tc)
21591.1Skamil{
21601.1Skamil	atf_tc_set_md_var(tc, "descr",
21611.1Skamil	    "Verify PT_READ_D called once");
21621.1Skamil}
21631.1Skamil
21641.1SkamilATF_TC_BODY(read_d1, tc)
21651.1Skamil{
21661.1Skamil	const int exitval = 5;
21671.1Skamil	const int sigval = SIGSTOP;
21681.1Skamil	pid_t child, wpid;
21691.1Skamil	int lookup_me = 0;
21701.1Skamil	const int magic = (int)random();
21711.1Skamil#if defined(TWAIT_HAVE_STATUS)
21721.1Skamil	int status;
21731.1Skamil#endif
21741.1Skamil
21751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21771.1Skamil	if (child == 0) {
21781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21801.1Skamil
21811.1Skamil		lookup_me = magic;
21821.1Skamil
21831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21851.1Skamil
21861.13Schristos		DPRINTF("Before exiting of the child process\n");
21871.1Skamil		_exit(exitval);
21881.1Skamil	}
21891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21901.1Skamil
21911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21931.1Skamil
21941.1Skamil	validate_status_stopped(status, sigval);
21951.1Skamil
21961.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21971.1Skamil	    child, getpid());
21981.1Skamil	errno = 0;
21991.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
22001.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22011.1Skamil
22021.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
22031.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
22041.1Skamil
22051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22061.1Skamil	    "without signal to be sent\n");
22071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22081.1Skamil
22091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22111.1Skamil
22121.1Skamil	validate_status_exited(status, exitval);
22131.1Skamil
22141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22161.1Skamil}
22171.1Skamil
22181.1SkamilATF_TC(read_d2);
22191.1SkamilATF_TC_HEAD(read_d2, tc)
22201.1Skamil{
22211.1Skamil	atf_tc_set_md_var(tc, "descr",
22221.1Skamil	    "Verify PT_READ_D called twice");
22231.1Skamil}
22241.1Skamil
22251.1SkamilATF_TC_BODY(read_d2, tc)
22261.1Skamil{
22271.1Skamil	const int exitval = 5;
22281.1Skamil	const int sigval = SIGSTOP;
22291.1Skamil	pid_t child, wpid;
22301.1Skamil	int lookup_me1 = 0;
22311.1Skamil	int lookup_me2 = 0;
22321.1Skamil	const int magic1 = (int)random();
22331.1Skamil	const int magic2 = (int)random();
22341.1Skamil#if defined(TWAIT_HAVE_STATUS)
22351.1Skamil	int status;
22361.1Skamil#endif
22371.1Skamil
22381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22401.1Skamil	if (child == 0) {
22411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22431.1Skamil
22441.1Skamil		lookup_me1 = magic1;
22451.1Skamil		lookup_me2 = magic2;
22461.1Skamil
22471.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22481.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22491.1Skamil
22501.13Schristos		DPRINTF("Before exiting of the child process\n");
22511.1Skamil		_exit(exitval);
22521.1Skamil	}
22531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22541.1Skamil
22551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22571.1Skamil
22581.1Skamil	validate_status_stopped(status, sigval);
22591.1Skamil
22601.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
22611.1Skamil	    child, getpid());
22621.1Skamil	errno = 0;
22631.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
22641.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22651.1Skamil
22661.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
22671.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
22681.1Skamil
22691.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
22701.1Skamil	    child, getpid());
22711.1Skamil	errno = 0;
22721.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
22731.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22741.1Skamil
22751.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
22761.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
22771.1Skamil
22781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22791.1Skamil	    "without signal to be sent\n");
22801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22811.1Skamil
22821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22841.1Skamil
22851.1Skamil	validate_status_exited(status, exitval);
22861.1Skamil
22871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22881.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22891.1Skamil}
22901.1Skamil
22911.1SkamilATF_TC(read_d3);
22921.1SkamilATF_TC_HEAD(read_d3, tc)
22931.1Skamil{
22941.1Skamil	atf_tc_set_md_var(tc, "descr",
22951.1Skamil	    "Verify PT_READ_D called three times");
22961.1Skamil}
22971.1Skamil
22981.1SkamilATF_TC_BODY(read_d3, tc)
22991.1Skamil{
23001.1Skamil	const int exitval = 5;
23011.1Skamil	const int sigval = SIGSTOP;
23021.1Skamil	pid_t child, wpid;
23031.1Skamil	int lookup_me1 = 0;
23041.1Skamil	int lookup_me2 = 0;
23051.1Skamil	int lookup_me3 = 0;
23061.1Skamil	const int magic1 = (int)random();
23071.1Skamil	const int magic2 = (int)random();
23081.1Skamil	const int magic3 = (int)random();
23091.1Skamil#if defined(TWAIT_HAVE_STATUS)
23101.1Skamil	int status;
23111.1Skamil#endif
23121.1Skamil
23131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23151.1Skamil	if (child == 0) {
23161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23181.1Skamil
23191.1Skamil		lookup_me1 = magic1;
23201.1Skamil		lookup_me2 = magic2;
23211.1Skamil		lookup_me3 = magic3;
23221.1Skamil
23231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23251.1Skamil
23261.13Schristos		DPRINTF("Before exiting of the child process\n");
23271.1Skamil		_exit(exitval);
23281.1Skamil	}
23291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23301.1Skamil
23311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23331.1Skamil
23341.1Skamil	validate_status_stopped(status, sigval);
23351.1Skamil
23361.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
23371.1Skamil	    child, getpid());
23381.1Skamil	errno = 0;
23391.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
23401.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23411.1Skamil
23421.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
23431.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
23441.1Skamil
23451.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
23461.1Skamil	    child, getpid());
23471.1Skamil	errno = 0;
23481.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
23491.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23501.1Skamil
23511.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
23521.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
23531.1Skamil
23541.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
23551.1Skamil	    child, getpid());
23561.1Skamil	errno = 0;
23571.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
23581.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23591.1Skamil
23601.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
23611.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
23621.1Skamil
23631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23641.1Skamil	    "without signal to be sent\n");
23651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23661.1Skamil
23671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23691.1Skamil
23701.1Skamil	validate_status_exited(status, exitval);
23711.1Skamil
23721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23741.1Skamil}
23751.1Skamil
23761.1SkamilATF_TC(read_d4);
23771.1SkamilATF_TC_HEAD(read_d4, tc)
23781.1Skamil{
23791.1Skamil	atf_tc_set_md_var(tc, "descr",
23801.1Skamil	    "Verify PT_READ_D called four times");
23811.1Skamil}
23821.1Skamil
23831.1SkamilATF_TC_BODY(read_d4, tc)
23841.1Skamil{
23851.1Skamil	const int exitval = 5;
23861.1Skamil	const int sigval = SIGSTOP;
23871.1Skamil	pid_t child, wpid;
23881.1Skamil	int lookup_me1 = 0;
23891.1Skamil	int lookup_me2 = 0;
23901.1Skamil	int lookup_me3 = 0;
23911.1Skamil	int lookup_me4 = 0;
23921.1Skamil	const int magic1 = (int)random();
23931.1Skamil	const int magic2 = (int)random();
23941.1Skamil	const int magic3 = (int)random();
23951.1Skamil	const int magic4 = (int)random();
23961.1Skamil#if defined(TWAIT_HAVE_STATUS)
23971.1Skamil	int status;
23981.1Skamil#endif
23991.1Skamil
24001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24021.1Skamil	if (child == 0) {
24031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24051.1Skamil
24061.1Skamil		lookup_me1 = magic1;
24071.1Skamil		lookup_me2 = magic2;
24081.1Skamil		lookup_me3 = magic3;
24091.1Skamil		lookup_me4 = magic4;
24101.1Skamil
24111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24131.1Skamil
24141.13Schristos		DPRINTF("Before exiting of the child process\n");
24151.1Skamil		_exit(exitval);
24161.1Skamil	}
24171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24181.1Skamil
24191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24211.1Skamil
24221.1Skamil	validate_status_stopped(status, sigval);
24231.1Skamil
24241.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
24251.1Skamil	    child, getpid());
24261.1Skamil	errno = 0;
24271.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
24281.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24291.1Skamil
24301.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
24311.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
24321.1Skamil
24331.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
24341.1Skamil	    child, getpid());
24351.1Skamil	errno = 0;
24361.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
24371.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24381.1Skamil
24391.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
24401.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
24411.1Skamil
24421.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
24431.1Skamil	    child, getpid());
24441.1Skamil	errno = 0;
24451.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
24461.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24471.1Skamil
24481.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
24491.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
24501.1Skamil
24511.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
24521.1Skamil	    child, getpid());
24531.1Skamil	errno = 0;
24541.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
24551.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24561.1Skamil
24571.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
24581.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
24591.1Skamil
24601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24611.1Skamil	    "without signal to be sent\n");
24621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24631.1Skamil
24641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24661.1Skamil
24671.1Skamil	validate_status_exited(status, exitval);
24681.1Skamil
24691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24711.1Skamil}
24721.1Skamil
24731.1SkamilATF_TC(write_d1);
24741.1SkamilATF_TC_HEAD(write_d1, tc)
24751.1Skamil{
24761.1Skamil	atf_tc_set_md_var(tc, "descr",
24771.1Skamil	    "Verify PT_WRITE_D called once");
24781.1Skamil}
24791.1Skamil
24801.1SkamilATF_TC_BODY(write_d1, tc)
24811.1Skamil{
24821.1Skamil	const int exitval = 5;
24831.1Skamil	const int sigval = SIGSTOP;
24841.1Skamil	pid_t child, wpid;
24851.1Skamil	int lookup_me = 0;
24861.1Skamil	const int magic = (int)random();
24871.1Skamil#if defined(TWAIT_HAVE_STATUS)
24881.1Skamil	int status;
24891.1Skamil#endif
24901.1Skamil
24911.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24921.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24931.1Skamil	if (child == 0) {
24941.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24951.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24961.1Skamil
24971.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24981.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24991.1Skamil
25001.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
25011.1Skamil
25021.13Schristos		DPRINTF("Before exiting of the child process\n");
25031.1Skamil		_exit(exitval);
25041.1Skamil	}
25051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25061.1Skamil
25071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25091.1Skamil
25101.1Skamil	validate_status_stopped(status, sigval);
25111.1Skamil
25121.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
25131.1Skamil	    child, getpid());
25141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
25151.1Skamil
25161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25171.1Skamil	    "without signal to be sent\n");
25181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25191.1Skamil
25201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25221.1Skamil
25231.1Skamil	validate_status_exited(status, exitval);
25241.1Skamil
25251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25271.1Skamil}
25281.1Skamil
25291.1SkamilATF_TC(write_d2);
25301.1SkamilATF_TC_HEAD(write_d2, tc)
25311.1Skamil{
25321.1Skamil	atf_tc_set_md_var(tc, "descr",
25331.1Skamil	    "Verify PT_WRITE_D called twice");
25341.1Skamil}
25351.1Skamil
25361.1SkamilATF_TC_BODY(write_d2, tc)
25371.1Skamil{
25381.1Skamil	const int exitval = 5;
25391.1Skamil	const int sigval = SIGSTOP;
25401.1Skamil	pid_t child, wpid;
25411.1Skamil	int lookup_me1 = 0;
25421.1Skamil	int lookup_me2 = 0;
25431.1Skamil	const int magic1 = (int)random();
25441.1Skamil	const int magic2 = (int)random();
25451.1Skamil#if defined(TWAIT_HAVE_STATUS)
25461.1Skamil	int status;
25471.1Skamil#endif
25481.1Skamil
25491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25511.1Skamil	if (child == 0) {
25521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25541.1Skamil
25551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25571.1Skamil
25581.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
25591.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
25601.1Skamil
25611.13Schristos		DPRINTF("Before exiting of the child process\n");
25621.1Skamil		_exit(exitval);
25631.1Skamil	}
25641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25651.1Skamil
25661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25681.1Skamil
25691.1Skamil	validate_status_stopped(status, sigval);
25701.1Skamil
25711.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
25721.1Skamil	    child, getpid());
25731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
25741.1Skamil
25751.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
25761.1Skamil	    child, getpid());
25771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
25781.1Skamil
25791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25801.1Skamil	    "without signal to be sent\n");
25811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25821.1Skamil
25831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25851.1Skamil
25861.1Skamil	validate_status_exited(status, exitval);
25871.1Skamil
25881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25891.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25901.1Skamil}
25911.1Skamil
25921.1SkamilATF_TC(write_d3);
25931.1SkamilATF_TC_HEAD(write_d3, tc)
25941.1Skamil{
25951.1Skamil	atf_tc_set_md_var(tc, "descr",
25961.1Skamil	    "Verify PT_WRITE_D called three times");
25971.1Skamil}
25981.1Skamil
25991.1SkamilATF_TC_BODY(write_d3, tc)
26001.1Skamil{
26011.1Skamil	const int exitval = 5;
26021.1Skamil	const int sigval = SIGSTOP;
26031.1Skamil	pid_t child, wpid;
26041.1Skamil	int lookup_me1 = 0;
26051.1Skamil	int lookup_me2 = 0;
26061.1Skamil	int lookup_me3 = 0;
26071.1Skamil	const int magic1 = (int)random();
26081.1Skamil	const int magic2 = (int)random();
26091.1Skamil	const int magic3 = (int)random();
26101.1Skamil#if defined(TWAIT_HAVE_STATUS)
26111.1Skamil	int status;
26121.1Skamil#endif
26131.1Skamil
26141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26161.1Skamil	if (child == 0) {
26171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26191.1Skamil
26201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26221.1Skamil
26231.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26241.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26251.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
26261.1Skamil
26271.13Schristos		DPRINTF("Before exiting of the child process\n");
26281.1Skamil		_exit(exitval);
26291.1Skamil	}
26301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26311.1Skamil
26321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26341.1Skamil
26351.1Skamil	validate_status_stopped(status, sigval);
26361.1Skamil
26371.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
26381.1Skamil	    child, getpid());
26391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
26401.1Skamil
26411.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
26421.1Skamil	    child, getpid());
26431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
26441.1Skamil
26451.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
26461.1Skamil	    child, getpid());
26471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
26481.1Skamil
26491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26501.1Skamil	    "without signal to be sent\n");
26511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26521.1Skamil
26531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26551.1Skamil
26561.1Skamil	validate_status_exited(status, exitval);
26571.1Skamil
26581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26601.1Skamil}
26611.1Skamil
26621.1SkamilATF_TC(write_d4);
26631.1SkamilATF_TC_HEAD(write_d4, tc)
26641.1Skamil{
26651.1Skamil	atf_tc_set_md_var(tc, "descr",
26661.1Skamil	    "Verify PT_WRITE_D called four times");
26671.1Skamil}
26681.1Skamil
26691.1SkamilATF_TC_BODY(write_d4, tc)
26701.1Skamil{
26711.1Skamil	const int exitval = 5;
26721.1Skamil	const int sigval = SIGSTOP;
26731.1Skamil	pid_t child, wpid;
26741.1Skamil	int lookup_me1 = 0;
26751.1Skamil	int lookup_me2 = 0;
26761.1Skamil	int lookup_me3 = 0;
26771.1Skamil	int lookup_me4 = 0;
26781.1Skamil	const int magic1 = (int)random();
26791.1Skamil	const int magic2 = (int)random();
26801.1Skamil	const int magic3 = (int)random();
26811.1Skamil	const int magic4 = (int)random();
26821.1Skamil#if defined(TWAIT_HAVE_STATUS)
26831.1Skamil	int status;
26841.1Skamil#endif
26851.1Skamil
26861.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26871.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26881.1Skamil	if (child == 0) {
26891.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26901.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26911.1Skamil
26921.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26931.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26941.1Skamil
26951.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26961.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26971.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
26981.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
26991.1Skamil
27001.13Schristos		DPRINTF("Before exiting of the child process\n");
27011.1Skamil		_exit(exitval);
27021.1Skamil	}
27031.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27041.1Skamil
27051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27071.1Skamil
27081.1Skamil	validate_status_stopped(status, sigval);
27091.1Skamil
27101.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
27111.1Skamil	    child, getpid());
27121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
27131.1Skamil
27141.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
27151.1Skamil	    child, getpid());
27161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
27171.1Skamil
27181.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
27191.1Skamil	    child, getpid());
27201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
27211.1Skamil
27221.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
27231.1Skamil	    child, getpid());
27241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
27251.1Skamil
27261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27271.1Skamil	    "without signal to be sent\n");
27281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27291.1Skamil
27301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27321.1Skamil
27331.1Skamil	validate_status_exited(status, exitval);
27341.1Skamil
27351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27371.1Skamil}
27381.1Skamil
27391.1SkamilATF_TC(io_read_d_write_d_handshake1);
27401.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
27411.1Skamil{
27421.1Skamil	atf_tc_set_md_var(tc, "descr",
27431.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
27441.1Skamil}
27451.1Skamil
27461.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
27471.1Skamil{
27481.1Skamil	const int exitval = 5;
27491.1Skamil	const int sigval = SIGSTOP;
27501.1Skamil	pid_t child, wpid;
27511.1Skamil	uint8_t lookup_me_fromtracee = 0;
27521.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
27531.1Skamil	uint8_t lookup_me_totracee = 0;
27541.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
27551.1Skamil	struct ptrace_io_desc io_fromtracee = {
27561.1Skamil		.piod_op = PIOD_READ_D,
27571.1Skamil		.piod_offs = &lookup_me_fromtracee,
27581.1Skamil		.piod_addr = &lookup_me_fromtracee,
27591.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
27601.1Skamil	};
27611.1Skamil	struct ptrace_io_desc io_totracee = {
27621.1Skamil		.piod_op = PIOD_WRITE_D,
27631.1Skamil		.piod_offs = &lookup_me_totracee,
27641.1Skamil		.piod_addr = &lookup_me_totracee,
27651.1Skamil		.piod_len = sizeof(lookup_me_totracee)
27661.1Skamil	};
27671.1Skamil#if defined(TWAIT_HAVE_STATUS)
27681.1Skamil	int status;
27691.1Skamil#endif
27701.1Skamil
27711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27731.1Skamil	if (child == 0) {
27741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27761.1Skamil
27771.1Skamil		lookup_me_fromtracee = magic_fromtracee;
27781.1Skamil
27791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27811.1Skamil
27821.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
27831.1Skamil
27841.13Schristos		DPRINTF("Before exiting of the child process\n");
27851.1Skamil		_exit(exitval);
27861.1Skamil	}
27871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27881.1Skamil
27891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27911.1Skamil
27921.1Skamil	validate_status_stopped(status, sigval);
27931.1Skamil
27941.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
27951.1Skamil	    child, getpid());
27961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
27971.1Skamil
27981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
27991.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
28001.1Skamil	    magic_fromtracee);
28011.1Skamil
28021.1Skamil	lookup_me_totracee = magic_totracee;
28031.1Skamil
28041.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
28051.1Skamil	    child, getpid());
28061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
28071.1Skamil
28081.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
28091.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
28101.1Skamil	    magic_totracee);
28111.1Skamil
28121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28131.1Skamil	    "without signal to be sent\n");
28141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28151.1Skamil
28161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28181.1Skamil
28191.1Skamil	validate_status_exited(status, exitval);
28201.1Skamil
28211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28231.1Skamil}
28241.1Skamil
28251.1SkamilATF_TC(io_read_d_write_d_handshake2);
28261.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
28271.1Skamil{
28281.1Skamil	atf_tc_set_md_var(tc, "descr",
28291.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
28301.1Skamil}
28311.1Skamil
28321.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
28331.1Skamil{
28341.1Skamil	const int exitval = 5;
28351.1Skamil	const int sigval = SIGSTOP;
28361.1Skamil	pid_t child, wpid;
28371.1Skamil	uint8_t lookup_me_fromtracee = 0;
28381.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
28391.1Skamil	uint8_t lookup_me_totracee = 0;
28401.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
28411.1Skamil	struct ptrace_io_desc io_fromtracee = {
28421.1Skamil		.piod_op = PIOD_READ_D,
28431.1Skamil		.piod_offs = &lookup_me_fromtracee,
28441.1Skamil		.piod_addr = &lookup_me_fromtracee,
28451.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
28461.1Skamil	};
28471.1Skamil	struct ptrace_io_desc io_totracee = {
28481.1Skamil		.piod_op = PIOD_WRITE_D,
28491.1Skamil		.piod_offs = &lookup_me_totracee,
28501.1Skamil		.piod_addr = &lookup_me_totracee,
28511.1Skamil		.piod_len = sizeof(lookup_me_totracee)
28521.1Skamil	};
28531.1Skamil#if defined(TWAIT_HAVE_STATUS)
28541.1Skamil	int status;
28551.1Skamil#endif
28561.1Skamil
28571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28591.1Skamil	if (child == 0) {
28601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28621.1Skamil
28631.1Skamil		lookup_me_fromtracee = magic_fromtracee;
28641.1Skamil
28651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28671.1Skamil
28681.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
28691.1Skamil
28701.13Schristos		DPRINTF("Before exiting of the child process\n");
28711.1Skamil		_exit(exitval);
28721.1Skamil	}
28731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28741.1Skamil
28751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28771.1Skamil
28781.1Skamil	validate_status_stopped(status, sigval);
28791.1Skamil
28801.1Skamil	lookup_me_totracee = magic_totracee;
28811.1Skamil
28821.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
28831.1Skamil	    child, getpid());
28841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
28851.1Skamil
28861.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
28871.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
28881.1Skamil	    magic_totracee);
28891.1Skamil
28901.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
28911.1Skamil	    child, getpid());
28921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
28931.1Skamil
28941.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
28951.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
28961.1Skamil	    magic_fromtracee);
28971.1Skamil
28981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28991.1Skamil	    "without signal to be sent\n");
29001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29011.1Skamil
29021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29041.1Skamil
29051.1Skamil	validate_status_exited(status, exitval);
29061.1Skamil
29071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29091.1Skamil}
29101.1Skamil
29111.1SkamilATF_TC(read_d_write_d_handshake1);
29121.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
29131.1Skamil{
29141.1Skamil	atf_tc_set_md_var(tc, "descr",
29151.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
29161.1Skamil}
29171.1Skamil
29181.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
29191.1Skamil{
29201.1Skamil	const int exitval = 5;
29211.1Skamil	const int sigval = SIGSTOP;
29221.1Skamil	pid_t child, wpid;
29231.1Skamil	int lookup_me_fromtracee = 0;
29241.1Skamil	const int magic_fromtracee = (int)random();
29251.1Skamil	int lookup_me_totracee = 0;
29261.1Skamil	const int magic_totracee = (int)random();
29271.1Skamil#if defined(TWAIT_HAVE_STATUS)
29281.1Skamil	int status;
29291.1Skamil#endif
29301.1Skamil
29311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29331.1Skamil	if (child == 0) {
29341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29361.1Skamil
29371.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29381.1Skamil
29391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29411.1Skamil
29421.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
29431.1Skamil
29441.13Schristos		DPRINTF("Before exiting of the child process\n");
29451.1Skamil		_exit(exitval);
29461.1Skamil	}
29471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29481.1Skamil
29491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29511.1Skamil
29521.1Skamil	validate_status_stopped(status, sigval);
29531.1Skamil
29541.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
29551.1Skamil	    child, getpid());
29561.1Skamil	errno = 0;
29571.1Skamil	lookup_me_fromtracee =
29581.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
29591.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
29601.1Skamil
29611.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29621.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
29631.1Skamil	    magic_fromtracee);
29641.1Skamil
29651.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
29661.1Skamil	    child, getpid());
29671.1Skamil	ATF_REQUIRE
29681.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
29691.1Skamil	    != -1);
29701.1Skamil
29711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29721.1Skamil	    "without signal to be sent\n");
29731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29741.1Skamil
29751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29771.1Skamil
29781.1Skamil	validate_status_exited(status, exitval);
29791.1Skamil
29801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29811.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29821.1Skamil}
29831.1Skamil
29841.1SkamilATF_TC(read_d_write_d_handshake2);
29851.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
29861.1Skamil{
29871.1Skamil	atf_tc_set_md_var(tc, "descr",
29881.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
29891.1Skamil}
29901.1Skamil
29911.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
29921.1Skamil{
29931.1Skamil	const int exitval = 5;
29941.1Skamil	const int sigval = SIGSTOP;
29951.1Skamil	pid_t child, wpid;
29961.1Skamil	int lookup_me_fromtracee = 0;
29971.1Skamil	const int magic_fromtracee = (int)random();
29981.1Skamil	int lookup_me_totracee = 0;
29991.1Skamil	const int magic_totracee = (int)random();
30001.1Skamil#if defined(TWAIT_HAVE_STATUS)
30011.1Skamil	int status;
30021.1Skamil#endif
30031.1Skamil
30041.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30051.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30061.1Skamil	if (child == 0) {
30071.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30081.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30091.1Skamil
30101.1Skamil		lookup_me_fromtracee = magic_fromtracee;
30111.1Skamil
30121.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30131.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30141.1Skamil
30151.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
30161.1Skamil
30171.13Schristos		DPRINTF("Before exiting of the child process\n");
30181.1Skamil		_exit(exitval);
30191.1Skamil	}
30201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30211.1Skamil
30221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30241.1Skamil
30251.1Skamil	validate_status_stopped(status, sigval);
30261.1Skamil
30271.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
30281.1Skamil	    child, getpid());
30291.1Skamil	ATF_REQUIRE
30301.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
30311.1Skamil	    != -1);
30321.1Skamil
30331.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
30341.1Skamil	    child, getpid());
30351.1Skamil	errno = 0;
30361.1Skamil	lookup_me_fromtracee =
30371.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
30381.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
30391.1Skamil
30401.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
30411.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
30421.1Skamil	    magic_fromtracee);
30431.1Skamil
30441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30451.1Skamil	    "without signal to be sent\n");
30461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30471.1Skamil
30481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30501.1Skamil
30511.1Skamil	validate_status_exited(status, exitval);
30521.1Skamil
30531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30551.1Skamil}
30561.1Skamil
30571.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
30581.1Skamilstatic int __used
30591.1Skamildummy_fn1(int a, int b, int c, int d)
30601.1Skamil{
30611.1Skamil
30621.1Skamil	a *= 1;
30631.1Skamil	b += 2;
30641.1Skamil	c -= 3;
30651.1Skamil	d /= 4;
30661.1Skamil
30671.1Skamil	return a + b * c - d;
30681.1Skamil}
30691.1Skamil
30701.1Skamilstatic int __used
30711.1Skamildummy_fn2(int a, int b, int c, int d)
30721.1Skamil{
30731.1Skamil
30741.1Skamil	a *= 4;
30751.1Skamil	b += 3;
30761.1Skamil	c -= 2;
30771.1Skamil	d /= 1;
30781.1Skamil
30791.1Skamil	return a + b * c - d;
30801.1Skamil}
30811.1Skamil
30821.1Skamilstatic int __used
30831.1Skamildummy_fn3(int a, int b, int c, int d)
30841.1Skamil{
30851.1Skamil
30861.1Skamil	a *= 10;
30871.1Skamil	b += 20;
30881.1Skamil	c -= 30;
30891.1Skamil	d /= 40;
30901.1Skamil
30911.1Skamil	return a + b * c - d;
30921.1Skamil}
30931.1Skamil
30941.1Skamilstatic int __used
30951.1Skamildummy_fn4(int a, int b, int c, int d)
30961.1Skamil{
30971.1Skamil
30981.1Skamil	a *= 40;
30991.1Skamil	b += 30;
31001.1Skamil	c -= 20;
31011.1Skamil	d /= 10;
31021.1Skamil
31031.1Skamil	return a + b * c - d;
31041.1Skamil}
31051.1Skamil
31061.1SkamilATF_TC(io_read_i1);
31071.1SkamilATF_TC_HEAD(io_read_i1, tc)
31081.1Skamil{
31091.1Skamil	atf_tc_set_md_var(tc, "descr",
31101.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
31111.1Skamil}
31121.1Skamil
31131.1SkamilATF_TC_BODY(io_read_i1, tc)
31141.1Skamil{
31151.1Skamil	const int exitval = 5;
31161.1Skamil	const int sigval = SIGSTOP;
31171.1Skamil	pid_t child, wpid;
31181.1Skamil	uint8_t lookup_me = 0;
31191.1Skamil	uint8_t magic;
31201.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31211.1Skamil	struct ptrace_io_desc io = {
31221.1Skamil		.piod_op = PIOD_READ_I,
31231.1Skamil		.piod_offs = dummy_fn1,
31241.1Skamil		.piod_addr = &lookup_me,
31251.1Skamil		.piod_len = sizeof(lookup_me)
31261.1Skamil	};
31271.1Skamil#if defined(TWAIT_HAVE_STATUS)
31281.1Skamil	int status;
31291.1Skamil#endif
31301.1Skamil
31311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31331.1Skamil	if (child == 0) {
31341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31361.1Skamil
31371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31391.1Skamil
31401.13Schristos		DPRINTF("Before exiting of the child process\n");
31411.1Skamil		_exit(exitval);
31421.1Skamil	}
31431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31441.1Skamil
31451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31471.1Skamil
31481.1Skamil	validate_status_stopped(status, sigval);
31491.1Skamil
31501.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
31511.1Skamil	    child, getpid());
31521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
31531.1Skamil
31541.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
31551.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
31561.1Skamil
31571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31581.1Skamil	    "without signal to be sent\n");
31591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31601.1Skamil
31611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31631.1Skamil
31641.1Skamil	validate_status_exited(status, exitval);
31651.1Skamil
31661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31681.1Skamil}
31691.1Skamil
31701.1SkamilATF_TC(io_read_i2);
31711.1SkamilATF_TC_HEAD(io_read_i2, tc)
31721.1Skamil{
31731.1Skamil	atf_tc_set_md_var(tc, "descr",
31741.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
31751.1Skamil}
31761.1Skamil
31771.1SkamilATF_TC_BODY(io_read_i2, tc)
31781.1Skamil{
31791.1Skamil	const int exitval = 5;
31801.1Skamil	const int sigval = SIGSTOP;
31811.1Skamil	pid_t child, wpid;
31821.1Skamil	uint16_t lookup_me = 0;
31831.1Skamil	uint16_t magic;
31841.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31851.1Skamil	struct ptrace_io_desc io = {
31861.1Skamil		.piod_op = PIOD_READ_I,
31871.1Skamil		.piod_offs = dummy_fn1,
31881.1Skamil		.piod_addr = &lookup_me,
31891.1Skamil		.piod_len = sizeof(lookup_me)
31901.1Skamil	};
31911.1Skamil#if defined(TWAIT_HAVE_STATUS)
31921.1Skamil	int status;
31931.1Skamil#endif
31941.1Skamil
31951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31971.1Skamil	if (child == 0) {
31981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32001.1Skamil
32011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32031.1Skamil
32041.13Schristos		DPRINTF("Before exiting of the child process\n");
32051.1Skamil		_exit(exitval);
32061.1Skamil	}
32071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32081.1Skamil
32091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32111.1Skamil
32121.1Skamil	validate_status_stopped(status, sigval);
32131.1Skamil
32141.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32151.1Skamil	    child, getpid());
32161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32171.1Skamil
32181.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32191.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
32201.1Skamil
32211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32221.1Skamil	    "without signal to be sent\n");
32231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32241.1Skamil
32251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32271.1Skamil
32281.1Skamil	validate_status_exited(status, exitval);
32291.1Skamil
32301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32321.1Skamil}
32331.1Skamil
32341.1SkamilATF_TC(io_read_i3);
32351.1SkamilATF_TC_HEAD(io_read_i3, tc)
32361.1Skamil{
32371.1Skamil	atf_tc_set_md_var(tc, "descr",
32381.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
32391.1Skamil}
32401.1Skamil
32411.1SkamilATF_TC_BODY(io_read_i3, tc)
32421.1Skamil{
32431.1Skamil	const int exitval = 5;
32441.1Skamil	const int sigval = SIGSTOP;
32451.1Skamil	pid_t child, wpid;
32461.1Skamil	uint32_t lookup_me = 0;
32471.1Skamil	uint32_t magic;
32481.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
32491.1Skamil	struct ptrace_io_desc io = {
32501.1Skamil		.piod_op = PIOD_READ_I,
32511.1Skamil		.piod_offs = dummy_fn1,
32521.1Skamil		.piod_addr = &lookup_me,
32531.1Skamil		.piod_len = sizeof(lookup_me)
32541.1Skamil	};
32551.1Skamil#if defined(TWAIT_HAVE_STATUS)
32561.1Skamil	int status;
32571.1Skamil#endif
32581.1Skamil
32591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32611.1Skamil	if (child == 0) {
32621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32641.1Skamil
32651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32671.1Skamil
32681.13Schristos		DPRINTF("Before exiting of the child process\n");
32691.1Skamil		_exit(exitval);
32701.1Skamil	}
32711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32721.1Skamil
32731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32751.1Skamil
32761.1Skamil	validate_status_stopped(status, sigval);
32771.1Skamil
32781.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32791.1Skamil	    child, getpid());
32801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32811.1Skamil
32821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32831.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
32841.1Skamil
32851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32861.1Skamil	    "without signal to be sent\n");
32871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32881.1Skamil
32891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32911.1Skamil
32921.1Skamil	validate_status_exited(status, exitval);
32931.1Skamil
32941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32961.1Skamil}
32971.1Skamil
32981.1SkamilATF_TC(io_read_i4);
32991.1SkamilATF_TC_HEAD(io_read_i4, tc)
33001.1Skamil{
33011.1Skamil	atf_tc_set_md_var(tc, "descr",
33021.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
33031.1Skamil}
33041.1Skamil
33051.1SkamilATF_TC_BODY(io_read_i4, tc)
33061.1Skamil{
33071.1Skamil	const int exitval = 5;
33081.1Skamil	const int sigval = SIGSTOP;
33091.1Skamil	pid_t child, wpid;
33101.1Skamil	uint64_t lookup_me = 0;
33111.1Skamil	uint64_t magic;
33121.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33131.1Skamil	struct ptrace_io_desc io = {
33141.1Skamil		.piod_op = PIOD_READ_I,
33151.1Skamil		.piod_offs = dummy_fn1,
33161.1Skamil		.piod_addr = &lookup_me,
33171.1Skamil		.piod_len = sizeof(lookup_me)
33181.1Skamil	};
33191.1Skamil#if defined(TWAIT_HAVE_STATUS)
33201.1Skamil	int status;
33211.1Skamil#endif
33221.1Skamil
33231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33251.1Skamil	if (child == 0) {
33261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33281.1Skamil
33291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33311.1Skamil
33321.13Schristos		DPRINTF("Before exiting of the child process\n");
33331.1Skamil		_exit(exitval);
33341.1Skamil	}
33351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33361.1Skamil
33371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33391.1Skamil
33401.1Skamil	validate_status_stopped(status, sigval);
33411.1Skamil
33421.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33431.1Skamil	    child, getpid());
33441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
33451.1Skamil
33461.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33471.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
33481.1Skamil
33491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33501.1Skamil	    "without signal to be sent\n");
33511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33521.1Skamil
33531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33551.1Skamil
33561.1Skamil	validate_status_exited(status, exitval);
33571.1Skamil
33581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33601.1Skamil}
33611.1Skamil
33621.1SkamilATF_TC(read_i1);
33631.1SkamilATF_TC_HEAD(read_i1, tc)
33641.1Skamil{
33651.1Skamil	atf_tc_set_md_var(tc, "descr",
33661.1Skamil	    "Verify PT_READ_I called once");
33671.1Skamil}
33681.1Skamil
33691.1SkamilATF_TC_BODY(read_i1, tc)
33701.1Skamil{
33711.1Skamil	const int exitval = 5;
33721.1Skamil	const int sigval = SIGSTOP;
33731.1Skamil	pid_t child, wpid;
33741.1Skamil	int lookup_me = 0;
33751.1Skamil	int magic;
33761.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33771.1Skamil#if defined(TWAIT_HAVE_STATUS)
33781.1Skamil	int status;
33791.1Skamil#endif
33801.1Skamil
33811.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33821.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33831.1Skamil	if (child == 0) {
33841.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33851.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33861.1Skamil
33871.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33881.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33891.1Skamil
33901.13Schristos		DPRINTF("Before exiting of the child process\n");
33911.1Skamil		_exit(exitval);
33921.1Skamil	}
33931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33941.1Skamil
33951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33971.1Skamil
33981.1Skamil	validate_status_stopped(status, sigval);
33991.1Skamil
34001.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34011.1Skamil	    child, getpid());
34021.1Skamil	errno = 0;
34031.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
34041.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34051.1Skamil
34061.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34071.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
34081.1Skamil
34091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34101.1Skamil	    "without signal to be sent\n");
34111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34121.1Skamil
34131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34151.1Skamil
34161.1Skamil	validate_status_exited(status, exitval);
34171.1Skamil
34181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34201.1Skamil}
34211.1Skamil
34221.1SkamilATF_TC(read_i2);
34231.1SkamilATF_TC_HEAD(read_i2, tc)
34241.1Skamil{
34251.1Skamil	atf_tc_set_md_var(tc, "descr",
34261.1Skamil	    "Verify PT_READ_I called twice");
34271.1Skamil}
34281.1Skamil
34291.1SkamilATF_TC_BODY(read_i2, tc)
34301.1Skamil{
34311.1Skamil	const int exitval = 5;
34321.1Skamil	const int sigval = SIGSTOP;
34331.1Skamil	pid_t child, wpid;
34341.1Skamil	int lookup_me1 = 0;
34351.1Skamil	int lookup_me2 = 0;
34361.1Skamil	int magic1;
34371.1Skamil	int magic2;
34381.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
34391.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
34401.1Skamil#if defined(TWAIT_HAVE_STATUS)
34411.1Skamil	int status;
34421.1Skamil#endif
34431.1Skamil
34441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34461.1Skamil	if (child == 0) {
34471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34491.1Skamil
34501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34521.1Skamil
34531.13Schristos		DPRINTF("Before exiting of the child process\n");
34541.1Skamil		_exit(exitval);
34551.1Skamil	}
34561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34571.1Skamil
34581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34601.1Skamil
34611.1Skamil	validate_status_stopped(status, sigval);
34621.1Skamil
34631.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
34641.1Skamil	    child, getpid());
34651.1Skamil	errno = 0;
34661.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
34671.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34681.1Skamil
34691.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
34701.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
34711.1Skamil
34721.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
34731.1Skamil	    child, getpid());
34741.1Skamil	errno = 0;
34751.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
34761.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34771.1Skamil
34781.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
34791.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
34801.1Skamil
34811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34821.1Skamil	    "without signal to be sent\n");
34831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34841.1Skamil
34851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34871.1Skamil
34881.1Skamil	validate_status_exited(status, exitval);
34891.1Skamil
34901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34921.1Skamil}
34931.1Skamil
34941.1SkamilATF_TC(read_i3);
34951.1SkamilATF_TC_HEAD(read_i3, tc)
34961.1Skamil{
34971.1Skamil	atf_tc_set_md_var(tc, "descr",
34981.1Skamil	    "Verify PT_READ_I called three times");
34991.1Skamil}
35001.1Skamil
35011.1SkamilATF_TC_BODY(read_i3, tc)
35021.1Skamil{
35031.1Skamil	const int exitval = 5;
35041.1Skamil	const int sigval = SIGSTOP;
35051.1Skamil	pid_t child, wpid;
35061.1Skamil	int lookup_me1 = 0;
35071.1Skamil	int lookup_me2 = 0;
35081.1Skamil	int lookup_me3 = 0;
35091.1Skamil	int magic1;
35101.1Skamil	int magic2;
35111.1Skamil	int magic3;
35121.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35131.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
35141.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
35151.1Skamil#if defined(TWAIT_HAVE_STATUS)
35161.1Skamil	int status;
35171.1Skamil#endif
35181.1Skamil
35191.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35201.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35211.1Skamil	if (child == 0) {
35221.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35231.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35241.1Skamil
35251.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35261.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35271.1Skamil
35281.13Schristos		DPRINTF("Before exiting of the child process\n");
35291.1Skamil		_exit(exitval);
35301.1Skamil	}
35311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35321.1Skamil
35331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35351.1Skamil
35361.1Skamil	validate_status_stopped(status, sigval);
35371.1Skamil
35381.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
35391.1Skamil	    child, getpid());
35401.1Skamil	errno = 0;
35411.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
35421.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35431.1Skamil
35441.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
35451.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
35461.1Skamil
35471.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
35481.1Skamil	    child, getpid());
35491.1Skamil	errno = 0;
35501.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
35511.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35521.1Skamil
35531.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
35541.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
35551.1Skamil
35561.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
35571.1Skamil	    child, getpid());
35581.1Skamil	errno = 0;
35591.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
35601.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35611.1Skamil
35621.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
35631.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
35641.1Skamil
35651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35661.1Skamil	    "without signal to be sent\n");
35671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35681.1Skamil
35691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35711.1Skamil
35721.1Skamil	validate_status_exited(status, exitval);
35731.1Skamil
35741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35761.1Skamil}
35771.1Skamil
35781.1SkamilATF_TC(read_i4);
35791.1SkamilATF_TC_HEAD(read_i4, tc)
35801.1Skamil{
35811.1Skamil	atf_tc_set_md_var(tc, "descr",
35821.1Skamil	    "Verify PT_READ_I called four times");
35831.1Skamil}
35841.1Skamil
35851.1SkamilATF_TC_BODY(read_i4, tc)
35861.1Skamil{
35871.1Skamil	const int exitval = 5;
35881.1Skamil	const int sigval = SIGSTOP;
35891.1Skamil	pid_t child, wpid;
35901.1Skamil	int lookup_me1 = 0;
35911.1Skamil	int lookup_me2 = 0;
35921.1Skamil	int lookup_me3 = 0;
35931.1Skamil	int lookup_me4 = 0;
35941.1Skamil	int magic1;
35951.1Skamil	int magic2;
35961.1Skamil	int magic3;
35971.1Skamil	int magic4;
35981.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35991.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
36001.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
36011.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
36021.1Skamil#if defined(TWAIT_HAVE_STATUS)
36031.1Skamil	int status;
36041.1Skamil#endif
36051.1Skamil
36061.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36071.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36081.1Skamil	if (child == 0) {
36091.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36101.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36111.1Skamil
36121.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36131.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36141.1Skamil
36151.13Schristos		DPRINTF("Before exiting of the child process\n");
36161.1Skamil		_exit(exitval);
36171.1Skamil	}
36181.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36191.1Skamil
36201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36221.1Skamil
36231.1Skamil	validate_status_stopped(status, sigval);
36241.1Skamil
36251.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
36261.1Skamil	    child, getpid());
36271.1Skamil	errno = 0;
36281.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
36291.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36301.1Skamil
36311.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
36321.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
36331.1Skamil
36341.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
36351.1Skamil	    child, getpid());
36361.1Skamil	errno = 0;
36371.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
36381.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36391.1Skamil
36401.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
36411.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
36421.1Skamil
36431.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
36441.1Skamil	    child, getpid());
36451.1Skamil	errno = 0;
36461.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
36471.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36481.1Skamil
36491.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
36501.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
36511.1Skamil
36521.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
36531.1Skamil	    child, getpid());
36541.1Skamil	errno = 0;
36551.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
36561.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36571.1Skamil
36581.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
36591.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
36601.1Skamil
36611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36621.1Skamil	    "without signal to be sent\n");
36631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36641.1Skamil
36651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36671.1Skamil
36681.1Skamil	validate_status_exited(status, exitval);
36691.1Skamil
36701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36721.1Skamil}
36731.1Skamil
36741.1Skamil#if defined(HAVE_GPREGS)
36751.1SkamilATF_TC(regs1);
36761.1SkamilATF_TC_HEAD(regs1, tc)
36771.1Skamil{
36781.1Skamil	atf_tc_set_md_var(tc, "descr",
36791.1Skamil	    "Verify plain PT_GETREGS call without further steps");
36801.1Skamil}
36811.1Skamil
36821.1SkamilATF_TC_BODY(regs1, tc)
36831.1Skamil{
36841.1Skamil	const int exitval = 5;
36851.1Skamil	const int sigval = SIGSTOP;
36861.1Skamil	pid_t child, wpid;
36871.1Skamil#if defined(TWAIT_HAVE_STATUS)
36881.1Skamil	int status;
36891.1Skamil#endif
36901.1Skamil	struct reg r;
36911.1Skamil
36921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36941.1Skamil	if (child == 0) {
36951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36971.1Skamil
36981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37001.1Skamil
37011.13Schristos		DPRINTF("Before exiting of the child process\n");
37021.1Skamil		_exit(exitval);
37031.1Skamil	}
37041.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
37101.1Skamil
37111.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37131.1Skamil
37141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37151.1Skamil	    "without signal to be sent\n");
37161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37171.1Skamil
37181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37201.1Skamil
37211.1Skamil	validate_status_exited(status, exitval);
37221.1Skamil
37231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37251.1Skamil}
37261.1Skamil#endif
37271.1Skamil
37281.1Skamil#if defined(HAVE_GPREGS)
37291.1SkamilATF_TC(regs2);
37301.1SkamilATF_TC_HEAD(regs2, tc)
37311.1Skamil{
37321.1Skamil	atf_tc_set_md_var(tc, "descr",
37331.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
37341.1Skamil}
37351.1Skamil
37361.1SkamilATF_TC_BODY(regs2, tc)
37371.1Skamil{
37381.1Skamil	const int exitval = 5;
37391.1Skamil	const int sigval = SIGSTOP;
37401.1Skamil	pid_t child, wpid;
37411.1Skamil#if defined(TWAIT_HAVE_STATUS)
37421.1Skamil	int status;
37431.1Skamil#endif
37441.1Skamil	struct reg r;
37451.1Skamil
37461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37481.1Skamil	if (child == 0) {
37491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37511.1Skamil
37521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37541.1Skamil
37551.13Schristos		DPRINTF("Before exiting of the child process\n");
37561.1Skamil		_exit(exitval);
37571.1Skamil	}
37581.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37591.1Skamil
37601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37621.1Skamil
37631.1Skamil	validate_status_stopped(status, sigval);
37641.1Skamil
37651.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37671.1Skamil
37681.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
37691.1Skamil
37701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37711.1Skamil	    "without signal to be sent\n");
37721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37731.1Skamil
37741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37761.1Skamil
37771.1Skamil	validate_status_exited(status, exitval);
37781.1Skamil
37791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37811.1Skamil}
37821.1Skamil#endif
37831.1Skamil
37841.1Skamil#if defined(HAVE_GPREGS)
37851.1SkamilATF_TC(regs3);
37861.1SkamilATF_TC_HEAD(regs3, tc)
37871.1Skamil{
37881.1Skamil	atf_tc_set_md_var(tc, "descr",
37891.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
37901.1Skamil}
37911.1Skamil
37921.1SkamilATF_TC_BODY(regs3, tc)
37931.1Skamil{
37941.1Skamil	const int exitval = 5;
37951.1Skamil	const int sigval = SIGSTOP;
37961.1Skamil	pid_t child, wpid;
37971.1Skamil#if defined(TWAIT_HAVE_STATUS)
37981.1Skamil	int status;
37991.1Skamil#endif
38001.1Skamil	struct reg r;
38011.1Skamil
38021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38041.1Skamil	if (child == 0) {
38051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38071.1Skamil
38081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38101.1Skamil
38111.13Schristos		DPRINTF("Before exiting of the child process\n");
38121.1Skamil		_exit(exitval);
38131.1Skamil	}
38141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38151.1Skamil
38161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38181.1Skamil
38191.1Skamil	validate_status_stopped(status, sigval);
38201.1Skamil
38211.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38231.1Skamil
38241.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
38251.1Skamil
38261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38271.1Skamil	    "without signal to be sent\n");
38281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38291.1Skamil
38301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38321.1Skamil
38331.1Skamil	validate_status_exited(status, exitval);
38341.1Skamil
38351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38371.1Skamil}
38381.1Skamil#endif
38391.1Skamil
38401.1Skamil#if defined(HAVE_GPREGS)
38411.1SkamilATF_TC(regs4);
38421.1SkamilATF_TC_HEAD(regs4, tc)
38431.1Skamil{
38441.1Skamil	atf_tc_set_md_var(tc, "descr",
38451.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
38461.1Skamil}
38471.1Skamil
38481.1SkamilATF_TC_BODY(regs4, tc)
38491.1Skamil{
38501.1Skamil	const int exitval = 5;
38511.1Skamil	const int sigval = SIGSTOP;
38521.1Skamil	pid_t child, wpid;
38531.1Skamil#if defined(TWAIT_HAVE_STATUS)
38541.1Skamil	int status;
38551.1Skamil#endif
38561.1Skamil	struct reg r;
38571.1Skamil
38581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38601.1Skamil	if (child == 0) {
38611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38631.1Skamil
38641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38661.1Skamil
38671.13Schristos		DPRINTF("Before exiting of the child process\n");
38681.1Skamil		_exit(exitval);
38691.1Skamil	}
38701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38711.1Skamil
38721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38741.1Skamil
38751.1Skamil	validate_status_stopped(status, sigval);
38761.1Skamil
38771.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38791.1Skamil
38801.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
38811.1Skamil
38821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38831.1Skamil	    "without signal to be sent\n");
38841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38851.1Skamil
38861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38881.1Skamil
38891.1Skamil	validate_status_exited(status, exitval);
38901.1Skamil
38911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38931.1Skamil}
38941.1Skamil#endif
38951.1Skamil
38961.1Skamil#if defined(HAVE_GPREGS)
38971.1SkamilATF_TC(regs5);
38981.1SkamilATF_TC_HEAD(regs5, tc)
38991.1Skamil{
39001.1Skamil	atf_tc_set_md_var(tc, "descr",
39011.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
39021.1Skamil}
39031.1Skamil
39041.1SkamilATF_TC_BODY(regs5, tc)
39051.1Skamil{
39061.1Skamil	const int exitval = 5;
39071.1Skamil	const int sigval = SIGSTOP;
39081.1Skamil	pid_t child, wpid;
39091.1Skamil#if defined(TWAIT_HAVE_STATUS)
39101.1Skamil	int status;
39111.1Skamil#endif
39121.1Skamil	struct reg r;
39131.1Skamil
39141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39161.1Skamil	if (child == 0) {
39171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39191.1Skamil
39201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39221.1Skamil
39231.13Schristos		DPRINTF("Before exiting of the child process\n");
39241.1Skamil		_exit(exitval);
39251.1Skamil	}
39261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39271.1Skamil
39281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39301.1Skamil
39311.1Skamil	validate_status_stopped(status, sigval);
39321.1Skamil
39331.13Schristos	DPRINTF("Call GETREGS for the child process\n");
39341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39351.1Skamil
39361.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
39371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39381.1Skamil
39391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39401.1Skamil	    "without signal to be sent\n");
39411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39421.1Skamil
39431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39451.1Skamil
39461.1Skamil	validate_status_exited(status, exitval);
39471.1Skamil
39481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39501.1Skamil}
39511.1Skamil#endif
39521.1Skamil
39531.1Skamil#if defined(HAVE_FPREGS)
39541.1SkamilATF_TC(fpregs1);
39551.1SkamilATF_TC_HEAD(fpregs1, tc)
39561.1Skamil{
39571.1Skamil	atf_tc_set_md_var(tc, "descr",
39581.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
39591.1Skamil}
39601.1Skamil
39611.1SkamilATF_TC_BODY(fpregs1, tc)
39621.1Skamil{
39631.1Skamil	const int exitval = 5;
39641.1Skamil	const int sigval = SIGSTOP;
39651.1Skamil	pid_t child, wpid;
39661.1Skamil#if defined(TWAIT_HAVE_STATUS)
39671.1Skamil	int status;
39681.1Skamil#endif
39691.1Skamil	struct fpreg r;
39701.1Skamil
39711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39731.1Skamil	if (child == 0) {
39741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39761.1Skamil
39771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39791.1Skamil
39801.13Schristos		DPRINTF("Before exiting of the child process\n");
39811.1Skamil		_exit(exitval);
39821.1Skamil	}
39831.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
39891.1Skamil
39901.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
39911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
39921.1Skamil
39931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39941.1Skamil	    "without signal to be sent\n");
39951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39961.1Skamil
39971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39991.1Skamil
40001.1Skamil	validate_status_exited(status, exitval);
40011.1Skamil
40021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40041.1Skamil}
40051.1Skamil#endif
40061.1Skamil
40071.1Skamil#if defined(HAVE_FPREGS)
40081.1SkamilATF_TC(fpregs2);
40091.1SkamilATF_TC_HEAD(fpregs2, tc)
40101.1Skamil{
40111.1Skamil	atf_tc_set_md_var(tc, "descr",
40121.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
40131.1Skamil	    "regs");
40141.1Skamil}
40151.1Skamil
40161.1SkamilATF_TC_BODY(fpregs2, tc)
40171.1Skamil{
40181.1Skamil	const int exitval = 5;
40191.1Skamil	const int sigval = SIGSTOP;
40201.1Skamil	pid_t child, wpid;
40211.1Skamil#if defined(TWAIT_HAVE_STATUS)
40221.1Skamil	int status;
40231.1Skamil#endif
40241.1Skamil	struct fpreg r;
40251.1Skamil
40261.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40271.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40281.1Skamil	if (child == 0) {
40291.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40301.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40311.1Skamil
40321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40341.1Skamil
40351.13Schristos		DPRINTF("Before exiting of the child process\n");
40361.1Skamil		_exit(exitval);
40371.1Skamil	}
40381.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40391.1Skamil
40401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40421.1Skamil
40431.1Skamil	validate_status_stopped(status, sigval);
40441.1Skamil
40451.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
40461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
40471.1Skamil
40481.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
40491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
40501.1Skamil
40511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40521.1Skamil	    "without signal to be sent\n");
40531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40541.1Skamil
40551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40571.1Skamil
40581.1Skamil	validate_status_exited(status, exitval);
40591.1Skamil
40601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40621.1Skamil}
40631.1Skamil#endif
40641.1Skamil
40651.1Skamil#if defined(PT_STEP)
40661.1Skamilstatic void
40671.2Skamilptrace_step(int N, int setstep)
40681.1Skamil{
40691.1Skamil	const int exitval = 5;
40701.1Skamil	const int sigval = SIGSTOP;
40711.1Skamil	pid_t child, wpid;
40721.1Skamil#if defined(TWAIT_HAVE_STATUS)
40731.1Skamil	int status;
40741.1Skamil#endif
40751.1Skamil	int happy;
40761.1Skamil
40771.1Skamil#if defined(__arm__)
40781.1Skamil	/* PT_STEP not supported on arm 32-bit */
40791.1Skamil	atf_tc_expect_fail("PR kern/52119");
40801.1Skamil#endif
40811.1Skamil
40821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40841.1Skamil	if (child == 0) {
40851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40871.1Skamil
40881.1Skamil		happy = check_happy(999);
40891.1Skamil
40901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40921.1Skamil
40931.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
40941.1Skamil
40951.13Schristos		DPRINTF("Before exiting of the child process\n");
40961.1Skamil		_exit(exitval);
40971.1Skamil	}
40981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40991.1Skamil
41001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41021.1Skamil
41031.1Skamil	validate_status_stopped(status, sigval);
41041.1Skamil
41051.1Skamil	while (N --> 0) {
41061.2Skamil		if (setstep) {
41071.13Schristos			DPRINTF("Before resuming the child process where it "
41081.2Skamil			    "left off and without signal to be sent (use "
41091.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
41101.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
41111.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
41121.2Skamil			    != -1);
41131.2Skamil		} else {
41141.13Schristos			DPRINTF("Before resuming the child process where it "
41151.2Skamil			    "left off and without signal to be sent (use "
41161.2Skamil			    "PT_STEP)\n");
41171.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
41181.2Skamil			    != -1);
41191.2Skamil		}
41201.1Skamil
41211.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41221.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
41231.1Skamil		    child);
41241.1Skamil
41251.1Skamil		validate_status_stopped(status, SIGTRAP);
41261.2Skamil
41271.2Skamil		if (setstep) {
41281.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
41291.2Skamil		}
41301.1Skamil	}
41311.1Skamil
41321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41331.1Skamil	    "without signal to be sent\n");
41341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41351.1Skamil
41361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41381.1Skamil
41391.1Skamil	validate_status_exited(status, exitval);
41401.1Skamil
41411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41431.1Skamil}
41441.1Skamil#endif
41451.1Skamil
41461.1Skamil#if defined(PT_STEP)
41471.1SkamilATF_TC(step1);
41481.1SkamilATF_TC_HEAD(step1, tc)
41491.1Skamil{
41501.1Skamil	atf_tc_set_md_var(tc, "descr",
41511.1Skamil	    "Verify single PT_STEP call");
41521.1Skamil}
41531.1Skamil
41541.1SkamilATF_TC_BODY(step1, tc)
41551.1Skamil{
41561.2Skamil	ptrace_step(1, 0);
41571.1Skamil}
41581.1Skamil#endif
41591.1Skamil
41601.1Skamil#if defined(PT_STEP)
41611.1SkamilATF_TC(step2);
41621.1SkamilATF_TC_HEAD(step2, tc)
41631.1Skamil{
41641.1Skamil	atf_tc_set_md_var(tc, "descr",
41651.1Skamil	    "Verify PT_STEP called twice");
41661.1Skamil}
41671.1Skamil
41681.1SkamilATF_TC_BODY(step2, tc)
41691.1Skamil{
41701.2Skamil	ptrace_step(2, 0);
41711.1Skamil}
41721.1Skamil#endif
41731.1Skamil
41741.1Skamil#if defined(PT_STEP)
41751.1SkamilATF_TC(step3);
41761.1SkamilATF_TC_HEAD(step3, tc)
41771.1Skamil{
41781.1Skamil	atf_tc_set_md_var(tc, "descr",
41791.1Skamil	    "Verify PT_STEP called three times");
41801.1Skamil}
41811.1Skamil
41821.1SkamilATF_TC_BODY(step3, tc)
41831.1Skamil{
41841.2Skamil	ptrace_step(3, 0);
41851.1Skamil}
41861.1Skamil#endif
41871.1Skamil
41881.1Skamil#if defined(PT_STEP)
41891.1SkamilATF_TC(step4);
41901.1SkamilATF_TC_HEAD(step4, tc)
41911.1Skamil{
41921.1Skamil	atf_tc_set_md_var(tc, "descr",
41931.1Skamil	    "Verify PT_STEP called four times");
41941.1Skamil}
41951.1Skamil
41961.1SkamilATF_TC_BODY(step4, tc)
41971.1Skamil{
41981.2Skamil	ptrace_step(4, 0);
41991.2Skamil}
42001.2Skamil#endif
42011.2Skamil
42021.2Skamil#if defined(PT_STEP)
42031.2SkamilATF_TC(setstep1);
42041.2SkamilATF_TC_HEAD(setstep1, tc)
42051.2Skamil{
42061.2Skamil	atf_tc_set_md_var(tc, "descr",
42071.2Skamil	    "Verify single PT_SETSTEP call");
42081.2Skamil}
42091.2Skamil
42101.2SkamilATF_TC_BODY(setstep1, tc)
42111.2Skamil{
42121.2Skamil	ptrace_step(1, 1);
42131.2Skamil}
42141.2Skamil#endif
42151.2Skamil
42161.2Skamil#if defined(PT_STEP)
42171.2SkamilATF_TC(setstep2);
42181.2SkamilATF_TC_HEAD(setstep2, tc)
42191.2Skamil{
42201.2Skamil	atf_tc_set_md_var(tc, "descr",
42211.2Skamil	    "Verify PT_SETSTEP called twice");
42221.2Skamil}
42231.2Skamil
42241.2SkamilATF_TC_BODY(setstep2, tc)
42251.2Skamil{
42261.2Skamil	ptrace_step(2, 1);
42271.2Skamil}
42281.2Skamil#endif
42291.2Skamil
42301.2Skamil#if defined(PT_STEP)
42311.2SkamilATF_TC(setstep3);
42321.2SkamilATF_TC_HEAD(setstep3, tc)
42331.2Skamil{
42341.2Skamil	atf_tc_set_md_var(tc, "descr",
42351.2Skamil	    "Verify PT_SETSTEP called three times");
42361.2Skamil}
42371.2Skamil
42381.2SkamilATF_TC_BODY(setstep3, tc)
42391.2Skamil{
42401.2Skamil	ptrace_step(3, 1);
42411.2Skamil}
42421.2Skamil#endif
42431.2Skamil
42441.2Skamil#if defined(PT_STEP)
42451.2SkamilATF_TC(setstep4);
42461.2SkamilATF_TC_HEAD(setstep4, tc)
42471.2Skamil{
42481.2Skamil	atf_tc_set_md_var(tc, "descr",
42491.2Skamil	    "Verify PT_SETSTEP called four times");
42501.2Skamil}
42511.2Skamil
42521.2SkamilATF_TC_BODY(setstep4, tc)
42531.2Skamil{
42541.2Skamil	ptrace_step(4, 1);
42551.1Skamil}
42561.1Skamil#endif
42571.1Skamil
42581.1SkamilATF_TC(kill1);
42591.1SkamilATF_TC_HEAD(kill1, tc)
42601.1Skamil{
42611.1Skamil	atf_tc_set_md_var(tc, "descr",
42621.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
42631.1Skamil}
42641.1Skamil
42651.1SkamilATF_TC_BODY(kill1, tc)
42661.1Skamil{
42671.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
42681.1Skamil	pid_t child, wpid;
42691.1Skamil#if defined(TWAIT_HAVE_STATUS)
42701.1Skamil	int status;
42711.1Skamil#endif
42721.1Skamil
42731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42751.1Skamil	if (child == 0) {
42761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42781.1Skamil
42791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42811.1Skamil
42821.1Skamil		/* NOTREACHED */
42831.1Skamil		FORKEE_ASSERTX(0 &&
42841.1Skamil		    "Child should be terminated by a signal from its parent");
42851.1Skamil	}
42861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42871.1Skamil
42881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42901.1Skamil
42911.1Skamil	validate_status_stopped(status, sigval);
42921.1Skamil
42931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42941.1Skamil	    "without signal to be sent\n");
42951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
42961.1Skamil
42971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42991.1Skamil
43001.1Skamil	validate_status_signaled(status, sigsent, 0);
43011.1Skamil
43021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43041.1Skamil}
43051.1Skamil
43061.1SkamilATF_TC(kill2);
43071.1SkamilATF_TC_HEAD(kill2, tc)
43081.1Skamil{
43091.1Skamil	atf_tc_set_md_var(tc, "descr",
43101.1Skamil	    "Verify that PT_KILL terminates child");
43111.1Skamil}
43121.1Skamil
43131.1SkamilATF_TC_BODY(kill2, tc)
43141.1Skamil{
43151.1Skamil	const int sigval = SIGSTOP;
43161.1Skamil	pid_t child, wpid;
43171.1Skamil#if defined(TWAIT_HAVE_STATUS)
43181.1Skamil	int status;
43191.1Skamil#endif
43201.1Skamil
43211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43231.1Skamil	if (child == 0) {
43241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43261.1Skamil
43271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43291.1Skamil
43301.1Skamil		/* NOTREACHED */
43311.1Skamil		FORKEE_ASSERTX(0 &&
43321.1Skamil		    "Child should be terminated by a signal from its parent");
43331.1Skamil	}
43341.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43351.1Skamil
43361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43381.1Skamil
43391.1Skamil	validate_status_stopped(status, sigval);
43401.1Skamil
43411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43421.1Skamil	    "without signal to be sent\n");
43431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
43441.1Skamil
43451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43471.1Skamil
43481.1Skamil	validate_status_signaled(status, SIGKILL, 0);
43491.1Skamil
43501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43521.1Skamil}
43531.1Skamil
43541.1SkamilATF_TC(lwpinfo1);
43551.1SkamilATF_TC_HEAD(lwpinfo1, tc)
43561.1Skamil{
43571.1Skamil	atf_tc_set_md_var(tc, "descr",
43581.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
43591.1Skamil}
43601.1Skamil
43611.1SkamilATF_TC_BODY(lwpinfo1, tc)
43621.1Skamil{
43631.1Skamil	const int exitval = 5;
43641.1Skamil	const int sigval = SIGSTOP;
43651.1Skamil	pid_t child, wpid;
43661.1Skamil#if defined(TWAIT_HAVE_STATUS)
43671.1Skamil	int status;
43681.1Skamil#endif
43691.1Skamil	struct ptrace_lwpinfo info = {0, 0};
43701.1Skamil
43711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43731.1Skamil	if (child == 0) {
43741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43761.1Skamil
43771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43791.1Skamil
43801.13Schristos		DPRINTF("Before exiting of the child process\n");
43811.1Skamil		_exit(exitval);
43821.1Skamil	}
43831.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43841.1Skamil
43851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43871.1Skamil
43881.1Skamil	validate_status_stopped(status, sigval);
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 exists a thread\n");
43941.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
43951.1Skamil
43961.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
43971.1Skamil	    info.pl_lwpid);
43981.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
43991.1Skamil	    "Received event %d != expected event %d",
44001.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
44011.1Skamil
44021.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
44041.1Skamil
44051.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
44061.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
44071.1Skamil
44081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44091.1Skamil	    "without signal to be sent\n");
44101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44111.1Skamil
44121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44141.1Skamil
44151.1Skamil	validate_status_exited(status, exitval);
44161.1Skamil
44171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44191.1Skamil}
44201.1Skamil
44211.1Skamil#if defined(TWAIT_HAVE_PID)
44221.1SkamilATF_TC(lwpinfo2);
44231.1SkamilATF_TC_HEAD(lwpinfo2, tc)
44241.1Skamil{
44251.1Skamil	atf_tc_set_md_var(tc, "descr",
44261.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
44271.1Skamil	    "tracer)");
44281.1Skamil}
44291.1Skamil
44301.1SkamilATF_TC_BODY(lwpinfo2, tc)
44311.1Skamil{
44321.1Skamil	struct msg_fds parent_tracee, parent_tracer;
44331.1Skamil	const int exitval_tracee = 5;
44341.1Skamil	const int exitval_tracer = 10;
44351.1Skamil	pid_t tracee, tracer, wpid;
44361.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
44371.1Skamil#if defined(TWAIT_HAVE_STATUS)
44381.1Skamil	int status;
44391.1Skamil#endif
44401.1Skamil	struct ptrace_lwpinfo info = {0, 0};
44411.1Skamil
44421.13Schristos	DPRINTF("Spawn tracee\n");
44431.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
44441.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
44451.1Skamil	tracee = atf_utils_fork();
44461.1Skamil	if (tracee == 0) {
44471.1Skamil
44481.1Skamil		/* Wait for message from the parent */
44491.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
44501.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
44511.1Skamil
44521.1Skamil		_exit(exitval_tracee);
44531.1Skamil	}
44541.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
44551.1Skamil
44561.13Schristos	DPRINTF("Spawn debugger\n");
44571.1Skamil	tracer = atf_utils_fork();
44581.1Skamil	if (tracer == 0) {
44591.1Skamil		/* No IPC to communicate with the child */
44601.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
44611.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
44621.1Skamil
44631.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
44641.1Skamil		FORKEE_REQUIRE_SUCCESS(
44651.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44661.1Skamil
44671.1Skamil		forkee_status_stopped(status, SIGSTOP);
44681.1Skamil
44691.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44701.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44711.1Skamil		    != -1);
44721.1Skamil
44731.13Schristos		DPRINTF("Assert that there exists a thread\n");
44741.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
44751.1Skamil
44761.13Schristos		DPRINTF("Assert that lwp thread %d received event "
44771.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
44781.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
44791.1Skamil
44801.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44811.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44821.1Skamil		    != -1);
44831.1Skamil
44841.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
44851.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
44861.1Skamil
44871.1Skamil		/* Resume tracee with PT_CONTINUE */
44881.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
44891.1Skamil
44901.1Skamil		/* Inform parent that tracer has attached to tracee */
44911.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
44921.1Skamil		/* Wait for parent */
44931.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
44941.1Skamil
44951.1Skamil		/* Wait for tracee and assert that it exited */
44961.1Skamil		FORKEE_REQUIRE_SUCCESS(
44971.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44981.1Skamil
44991.1Skamil		forkee_status_exited(status, exitval_tracee);
45001.1Skamil
45011.13Schristos		DPRINTF("Before exiting of the tracer process\n");
45021.1Skamil		_exit(exitval_tracer);
45031.1Skamil	}
45041.1Skamil
45051.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
45061.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
45071.1Skamil
45081.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
45091.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
45101.1Skamil
45111.13Schristos	DPRINTF("Detect that tracee is zombie\n");
45121.1Skamil	await_zombie(tracee);
45131.1Skamil
45141.13Schristos	DPRINTF("Assert that there is no status about tracee - "
45151.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
45161.1Skamil	TWAIT_REQUIRE_SUCCESS(
45171.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
45181.1Skamil
45191.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
45201.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
45211.1Skamil
45221.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
45231.1Skamil	    TWAIT_FNAME);
45241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
45251.1Skamil	    tracer);
45261.1Skamil
45271.1Skamil	validate_status_exited(status, exitval_tracer);
45281.1Skamil
45291.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
45301.1Skamil	    TWAIT_FNAME);
45311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
45321.1Skamil	    tracee);
45331.1Skamil
45341.1Skamil	validate_status_exited(status, exitval_tracee);
45351.1Skamil
45361.1Skamil	msg_close(&parent_tracer);
45371.1Skamil	msg_close(&parent_tracee);
45381.1Skamil}
45391.1Skamil#endif
45401.1Skamil
45411.1SkamilATF_TC(siginfo1);
45421.1SkamilATF_TC_HEAD(siginfo1, tc)
45431.1Skamil{
45441.1Skamil	atf_tc_set_md_var(tc, "descr",
45451.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
45461.1Skamil}
45471.1Skamil
45481.1SkamilATF_TC_BODY(siginfo1, tc)
45491.1Skamil{
45501.1Skamil	const int exitval = 5;
45511.1Skamil	const int sigval = SIGTRAP;
45521.1Skamil	pid_t child, wpid;
45531.1Skamil#if defined(TWAIT_HAVE_STATUS)
45541.1Skamil	int status;
45551.1Skamil#endif
45561.1Skamil	struct ptrace_siginfo info;
45571.1Skamil	memset(&info, 0, sizeof(info));
45581.1Skamil
45591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
45601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
45611.1Skamil	if (child == 0) {
45621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
45631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
45641.1Skamil
45651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
45661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
45671.1Skamil
45681.13Schristos		DPRINTF("Before exiting of the child process\n");
45691.1Skamil		_exit(exitval);
45701.1Skamil	}
45711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
45721.1Skamil
45731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45751.1Skamil
45761.1Skamil	validate_status_stopped(status, sigval);
45771.1Skamil
45781.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
45791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
45801.1Skamil
45811.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
45821.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
45831.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
45841.1Skamil	    info.psi_siginfo.si_errno);
45851.1Skamil
45861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
45871.1Skamil	    "without signal to be sent\n");
45881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
45891.1Skamil
45901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45921.1Skamil
45931.1Skamil	validate_status_exited(status, exitval);
45941.1Skamil
45951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
45971.1Skamil}
45981.1Skamil
45991.1SkamilATF_TC(siginfo2);
46001.1SkamilATF_TC_HEAD(siginfo2, tc)
46011.1Skamil{
46021.1Skamil	atf_tc_set_md_var(tc, "descr",
46031.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
46041.1Skamil	    "modification of SIGINT from tracee");
46051.1Skamil}
46061.1Skamil
46071.1Skamilstatic int siginfo2_caught = 0;
46081.1Skamil
46091.1Skamilstatic void
46101.1Skamilsiginfo2_sighandler(int sig)
46111.1Skamil{
46121.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
46131.1Skamil
46141.1Skamil	++siginfo2_caught;
46151.1Skamil}
46161.1Skamil
46171.1SkamilATF_TC_BODY(siginfo2, tc)
46181.1Skamil{
46191.1Skamil	const int exitval = 5;
46201.1Skamil	const int sigval = SIGINT;
46211.1Skamil	pid_t child, wpid;
46221.1Skamil	struct sigaction sa;
46231.1Skamil#if defined(TWAIT_HAVE_STATUS)
46241.1Skamil	int status;
46251.1Skamil#endif
46261.1Skamil	struct ptrace_siginfo info;
46271.1Skamil	memset(&info, 0, sizeof(info));
46281.1Skamil
46291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46311.1Skamil	if (child == 0) {
46321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46341.1Skamil
46351.1Skamil		sa.sa_handler = siginfo2_sighandler;
46361.1Skamil		sa.sa_flags = SA_SIGINFO;
46371.1Skamil		sigemptyset(&sa.sa_mask);
46381.1Skamil
46391.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
46401.1Skamil
46411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46431.1Skamil
46441.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
46451.1Skamil
46461.13Schristos		DPRINTF("Before exiting of the child process\n");
46471.1Skamil		_exit(exitval);
46481.1Skamil	}
46491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46501.1Skamil
46511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46531.1Skamil
46541.1Skamil	validate_status_stopped(status, sigval);
46551.1Skamil
46561.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
46571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
46581.1Skamil
46591.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
46601.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
46611.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
46621.1Skamil	    info.psi_siginfo.si_errno);
46631.1Skamil
46641.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
46651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
46661.1Skamil
46671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46681.1Skamil	    "without signal to be sent\n");
46691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
46701.1Skamil
46711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46731.1Skamil
46741.1Skamil	validate_status_exited(status, exitval);
46751.1Skamil
46761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46781.1Skamil}
46791.1Skamil
46801.1SkamilATF_TC(siginfo3);
46811.1SkamilATF_TC_HEAD(siginfo3, tc)
46821.1Skamil{
46831.1Skamil	atf_tc_set_md_var(tc, "descr",
46841.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
46851.1Skamil	    "setting signal to new value");
46861.1Skamil}
46871.1Skamil
46881.1Skamilstatic int siginfo3_caught = 0;
46891.1Skamil
46901.1Skamilstatic void
46911.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
46921.1Skamil{
46931.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
46941.1Skamil
46951.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
46961.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
46971.1Skamil
46981.1Skamil	++siginfo3_caught;
46991.1Skamil}
47001.1Skamil
47011.1SkamilATF_TC_BODY(siginfo3, tc)
47021.1Skamil{
47031.1Skamil	const int exitval = 5;
47041.1Skamil	const int sigval = SIGINT;
47051.1Skamil	const int sigfaked = SIGTRAP;
47061.1Skamil	const int sicodefaked = TRAP_BRKPT;
47071.1Skamil	pid_t child, wpid;
47081.1Skamil	struct sigaction sa;
47091.1Skamil#if defined(TWAIT_HAVE_STATUS)
47101.1Skamil	int status;
47111.1Skamil#endif
47121.1Skamil	struct ptrace_siginfo info;
47131.1Skamil	memset(&info, 0, sizeof(info));
47141.1Skamil
47151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47171.1Skamil	if (child == 0) {
47181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47201.1Skamil
47211.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
47221.1Skamil		sa.sa_flags = SA_SIGINFO;
47231.1Skamil		sigemptyset(&sa.sa_mask);
47241.1Skamil
47251.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
47261.1Skamil
47271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47291.1Skamil
47301.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
47311.1Skamil
47321.13Schristos		DPRINTF("Before exiting of the child process\n");
47331.1Skamil		_exit(exitval);
47341.1Skamil	}
47351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47361.1Skamil
47371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47391.1Skamil
47401.1Skamil	validate_status_stopped(status, sigval);
47411.1Skamil
47421.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47441.1Skamil
47451.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47461.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47471.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47481.1Skamil	    info.psi_siginfo.si_errno);
47491.1Skamil
47501.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
47511.1Skamil	    sigfaked, sicodefaked);
47521.1Skamil	info.psi_siginfo.si_signo = sigfaked;
47531.1Skamil	info.psi_siginfo.si_code = sicodefaked;
47541.1Skamil
47551.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
47561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
47571.1Skamil
47581.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47601.1Skamil
47611.13Schristos	DPRINTF("Before checking siginfo_t\n");
47621.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
47631.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
47641.1Skamil
47651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47661.1Skamil	    "without signal to be sent\n");
47671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
47681.1Skamil
47691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47711.1Skamil
47721.1Skamil	validate_status_exited(status, exitval);
47731.1Skamil
47741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47761.1Skamil}
47771.1Skamil
47781.1SkamilATF_TC(siginfo4);
47791.1SkamilATF_TC_HEAD(siginfo4, tc)
47801.1Skamil{
47811.1Skamil	atf_tc_set_md_var(tc, "descr",
47821.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
47831.1Skamil}
47841.1Skamil
47851.1SkamilATF_TC_BODY(siginfo4, tc)
47861.1Skamil{
47871.1Skamil	const int sigval = SIGTRAP;
47881.1Skamil	pid_t child, wpid;
47891.1Skamil#if defined(TWAIT_HAVE_STATUS)
47901.1Skamil	int status;
47911.1Skamil#endif
47921.1Skamil
47931.1Skamil	struct ptrace_siginfo info;
47941.1Skamil	memset(&info, 0, sizeof(info));
47951.1Skamil
47961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47981.1Skamil	if (child == 0) {
47991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48011.1Skamil
48021.13Schristos		DPRINTF("Before calling execve(2) from child\n");
48031.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
48041.1Skamil
48051.1Skamil		FORKEE_ASSERT(0 && "Not reached");
48061.1Skamil	}
48071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
48081.1Skamil
48091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48111.1Skamil
48121.1Skamil	validate_status_stopped(status, sigval);
48131.1Skamil
48141.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48161.1Skamil
48171.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
48181.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
48191.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
48201.1Skamil	    info.psi_siginfo.si_errno);
48211.1Skamil
48221.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
48231.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
48241.1Skamil
48251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48261.1Skamil	    "without signal to be sent\n");
48271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
48281.1Skamil
48291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48311.1Skamil
48321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
48341.1Skamil}
48351.1Skamil
48361.1Skamil#if defined(TWAIT_HAVE_PID)
48371.1SkamilATF_TC(siginfo5);
48381.1SkamilATF_TC_HEAD(siginfo5, tc)
48391.1Skamil{
48401.1Skamil	atf_tc_set_md_var(tc, "descr",
48411.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
48421.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
48431.1Skamil}
48441.1Skamil
48451.1SkamilATF_TC_BODY(siginfo5, tc)
48461.1Skamil{
48471.1Skamil	const int exitval = 5;
48481.1Skamil	const int exitval2 = 15;
48491.1Skamil	const int sigval = SIGSTOP;
48501.1Skamil	pid_t child, child2, wpid;
48511.1Skamil#if defined(TWAIT_HAVE_STATUS)
48521.1Skamil	int status;
48531.1Skamil#endif
48541.1Skamil	ptrace_state_t state;
48551.1Skamil	const int slen = sizeof(state);
48561.1Skamil	ptrace_event_t event;
48571.1Skamil	const int elen = sizeof(event);
48581.1Skamil	struct ptrace_siginfo info;
48591.1Skamil
48601.1Skamil	memset(&info, 0, sizeof(info));
48611.1Skamil
48621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48641.1Skamil	if (child == 0) {
48651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48671.1Skamil
48681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
48691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
48701.1Skamil
48711.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
48721.1Skamil
48731.1Skamil		if (child2 == 0)
48741.1Skamil			_exit(exitval2);
48751.1Skamil
48761.1Skamil		FORKEE_REQUIRE_SUCCESS
48771.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
48781.1Skamil
48791.1Skamil		forkee_status_exited(status, exitval2);
48801.1Skamil
48811.13Schristos		DPRINTF("Before exiting of the child process\n");
48821.1Skamil		_exit(exitval);
48831.1Skamil	}
48841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
48851.1Skamil
48861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48881.1Skamil
48891.1Skamil	validate_status_stopped(status, sigval);
48901.1Skamil
48911.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48931.1Skamil
48941.13Schristos	DPRINTF("Before checking siginfo_t\n");
48951.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
48961.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
48971.1Skamil
48981.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
48991.1Skamil	event.pe_set_event = PTRACE_FORK;
49001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
49011.1Skamil
49021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49031.1Skamil	    "without signal to be sent\n");
49041.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
49051.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
49061.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
49071.1Skamil                "state.pe_other_pid=child)\n", child);
49081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49091.1Skamil
49101.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
49111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49121.1Skamil
49131.1Skamil	validate_status_stopped(status, SIGTRAP);
49141.1Skamil
49151.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49171.1Skamil
49181.13Schristos	DPRINTF("Before checking siginfo_t\n");
49191.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
49201.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
49211.1Skamil
49221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
49231.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
49241.1Skamil
49251.1Skamil	child2 = state.pe_other_pid;
49261.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
49271.1Skamil
49281.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
49291.1Skamil	    TWAIT_FNAME, child2, child);
49301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
49311.1Skamil	    child2);
49321.1Skamil
49331.1Skamil	validate_status_stopped(status, SIGTRAP);
49341.1Skamil
49351.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49371.1Skamil
49381.13Schristos	DPRINTF("Before checking siginfo_t\n");
49391.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
49401.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
49411.1Skamil
49421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
49431.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
49441.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
49451.1Skamil
49461.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
49471.1Skamil	    "without signal to be sent\n");
49481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
49491.1Skamil
49501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49511.1Skamil	    "without signal to be sent\n");
49521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49531.1Skamil
49541.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
49551.1Skamil	    TWAIT_FNAME);
49561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
49571.1Skamil	    child2);
49581.1Skamil
49591.1Skamil	validate_status_exited(status, exitval2);
49601.1Skamil
49611.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
49621.1Skamil	    TWAIT_FNAME);
49631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
49641.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
49651.1Skamil
49661.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
49671.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
49681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49691.1Skamil
49701.1Skamil	validate_status_stopped(status, SIGCHLD);
49711.1Skamil
49721.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49741.1Skamil
49751.13Schristos	DPRINTF("Before checking siginfo_t\n");
49761.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
49771.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
49781.1Skamil
49791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49801.1Skamil	    "without signal to be sent\n");
49811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49821.1Skamil
49831.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
49841.1Skamil	    TWAIT_FNAME);
49851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49861.1Skamil
49871.1Skamil	validate_status_exited(status, exitval);
49881.1Skamil
49891.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
49901.1Skamil	    TWAIT_FNAME);
49911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49921.1Skamil}
49931.1Skamil#endif
49941.1Skamil
49951.1Skamil#if defined(PT_STEP)
49961.1SkamilATF_TC(siginfo6);
49971.1SkamilATF_TC_HEAD(siginfo6, tc)
49981.1Skamil{
49991.1Skamil	atf_tc_set_md_var(tc, "descr",
50001.1Skamil	    "Verify single PT_STEP call with signal information check");
50011.1Skamil}
50021.1Skamil
50031.1SkamilATF_TC_BODY(siginfo6, tc)
50041.1Skamil{
50051.1Skamil	const int exitval = 5;
50061.1Skamil	const int sigval = SIGSTOP;
50071.1Skamil	pid_t child, wpid;
50081.1Skamil#if defined(TWAIT_HAVE_STATUS)
50091.1Skamil	int status;
50101.1Skamil#endif
50111.1Skamil	int happy;
50121.1Skamil	struct ptrace_siginfo info;
50131.1Skamil
50141.1Skamil#if defined(__arm__)
50151.1Skamil	/* PT_STEP not supported on arm 32-bit */
50161.1Skamil	atf_tc_expect_fail("PR kern/52119");
50171.1Skamil#endif
50181.1Skamil
50191.1Skamil	memset(&info, 0, sizeof(info));
50201.1Skamil
50211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50231.1Skamil	if (child == 0) {
50241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50261.1Skamil
50271.1Skamil		happy = check_happy(100);
50281.1Skamil
50291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50311.1Skamil
50321.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
50331.1Skamil
50341.13Schristos		DPRINTF("Before exiting of the child process\n");
50351.1Skamil		_exit(exitval);
50361.1Skamil	}
50371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50381.1Skamil
50391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50411.1Skamil
50421.1Skamil	validate_status_stopped(status, sigval);
50431.1Skamil
50441.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50461.1Skamil
50471.13Schristos	DPRINTF("Before checking siginfo_t\n");
50481.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
50491.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
50501.1Skamil
50511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50521.1Skamil	    "without signal to be sent (use PT_STEP)\n");
50531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
50541.1Skamil
50551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50571.1Skamil
50581.1Skamil	validate_status_stopped(status, SIGTRAP);
50591.1Skamil
50601.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50621.1Skamil
50631.13Schristos	DPRINTF("Before checking siginfo_t\n");
50641.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
50651.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
50661.1Skamil
50671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50681.1Skamil	    "without signal to be sent\n");
50691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50701.1Skamil
50711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50731.1Skamil
50741.1Skamil	validate_status_exited(status, exitval);
50751.1Skamil
50761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50781.1Skamil}
50791.1Skamil#endif
50801.1Skamil
50811.1Skamilvolatile lwpid_t the_lwp_id = 0;
50821.1Skamil
50831.1Skamilstatic void
50841.1Skamillwp_main_func(void *arg)
50851.1Skamil{
50861.1Skamil	the_lwp_id = _lwp_self();
50871.1Skamil	_lwp_exit();
50881.1Skamil}
50891.1Skamil
50901.1SkamilATF_TC(lwp_create1);
50911.1SkamilATF_TC_HEAD(lwp_create1, tc)
50921.1Skamil{
50931.1Skamil	atf_tc_set_md_var(tc, "descr",
50941.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
50951.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
50961.1Skamil}
50971.1Skamil
50981.1SkamilATF_TC_BODY(lwp_create1, tc)
50991.1Skamil{
51001.1Skamil	const int exitval = 5;
51011.1Skamil	const int sigval = SIGSTOP;
51021.1Skamil	pid_t child, wpid;
51031.1Skamil#if defined(TWAIT_HAVE_STATUS)
51041.1Skamil	int status;
51051.1Skamil#endif
51061.1Skamil	ptrace_state_t state;
51071.1Skamil	const int slen = sizeof(state);
51081.1Skamil	ptrace_event_t event;
51091.1Skamil	const int elen = sizeof(event);
51101.1Skamil	ucontext_t uc;
51111.1Skamil	lwpid_t lid;
51121.1Skamil	static const size_t ssize = 16*1024;
51131.1Skamil	void *stack;
51141.1Skamil
51151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51171.1Skamil	if (child == 0) {
51181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51201.1Skamil
51211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
51221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
51231.1Skamil
51241.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
51251.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
51261.1Skamil
51271.13Schristos		DPRINTF("Before making context for new lwp in child\n");
51281.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
51291.1Skamil
51301.13Schristos		DPRINTF("Before creating new in child\n");
51311.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
51321.1Skamil
51331.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
51341.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
51351.1Skamil
51361.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
51371.1Skamil		    "are the same\n", lid, the_lwp_id);
51381.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
51391.1Skamil
51401.13Schristos		DPRINTF("Before exiting of the child process\n");
51411.1Skamil		_exit(exitval);
51421.1Skamil	}
51431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51441.1Skamil
51451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51471.1Skamil
51481.1Skamil	validate_status_stopped(status, sigval);
51491.1Skamil
51501.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
51511.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
51521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
51531.1Skamil
51541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51551.1Skamil	    "without signal to be sent\n");
51561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51571.1Skamil
51581.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
51591.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
51601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51611.1Skamil
51621.1Skamil	validate_status_stopped(status, SIGTRAP);
51631.1Skamil
51641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
51651.1Skamil
51661.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
51671.1Skamil
51681.1Skamil	lid = state.pe_lwp;
51691.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
51701.1Skamil
51711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51721.1Skamil	    "without signal to be sent\n");
51731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51741.1Skamil
51751.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
51761.1Skamil	    TWAIT_FNAME);
51771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51781.1Skamil
51791.1Skamil	validate_status_exited(status, exitval);
51801.1Skamil
51811.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
51821.1Skamil	    TWAIT_FNAME);
51831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51841.1Skamil}
51851.1Skamil
51861.1SkamilATF_TC(lwp_exit1);
51871.1SkamilATF_TC_HEAD(lwp_exit1, tc)
51881.1Skamil{
51891.1Skamil	atf_tc_set_md_var(tc, "descr",
51901.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
51911.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
51921.1Skamil}
51931.1Skamil
51941.1SkamilATF_TC_BODY(lwp_exit1, tc)
51951.1Skamil{
51961.1Skamil	const int exitval = 5;
51971.1Skamil	const int sigval = SIGSTOP;
51981.1Skamil	pid_t child, wpid;
51991.1Skamil#if defined(TWAIT_HAVE_STATUS)
52001.1Skamil	int status;
52011.1Skamil#endif
52021.1Skamil	ptrace_state_t state;
52031.1Skamil	const int slen = sizeof(state);
52041.1Skamil	ptrace_event_t event;
52051.1Skamil	const int elen = sizeof(event);
52061.1Skamil	ucontext_t uc;
52071.1Skamil	lwpid_t lid;
52081.1Skamil	static const size_t ssize = 16*1024;
52091.1Skamil	void *stack;
52101.1Skamil
52111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52131.1Skamil	if (child == 0) {
52141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52161.1Skamil
52171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52191.1Skamil
52201.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
52211.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
52221.1Skamil
52231.13Schristos		DPRINTF("Before making context for new lwp in child\n");
52241.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
52251.1Skamil
52261.13Schristos		DPRINTF("Before creating new in child\n");
52271.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
52281.1Skamil
52291.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
52301.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
52311.1Skamil
52321.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
52331.1Skamil		    "are the same\n", lid, the_lwp_id);
52341.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
52351.1Skamil
52361.13Schristos		DPRINTF("Before exiting of the child process\n");
52371.1Skamil		_exit(exitval);
52381.1Skamil	}
52391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52401.1Skamil
52411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52431.1Skamil
52441.1Skamil	validate_status_stopped(status, sigval);
52451.1Skamil
52461.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
52471.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
52481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52491.1Skamil
52501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52511.1Skamil	    "without signal to be sent\n");
52521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52531.1Skamil
52541.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
52551.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
52561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52571.1Skamil
52581.1Skamil	validate_status_stopped(status, SIGTRAP);
52591.1Skamil
52601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52611.1Skamil
52621.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
52631.1Skamil
52641.1Skamil	lid = state.pe_lwp;
52651.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
52661.1Skamil
52671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52681.1Skamil	    "without signal to be sent\n");
52691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52701.1Skamil
52711.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
52721.1Skamil	    TWAIT_FNAME);
52731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52741.1Skamil
52751.1Skamil	validate_status_exited(status, exitval);
52761.1Skamil
52771.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
52781.1Skamil	    TWAIT_FNAME);
52791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
52801.1Skamil}
52811.1Skamil
52821.1SkamilATF_TC(signal1);
52831.1SkamilATF_TC_HEAD(signal1, tc)
52841.1Skamil{
52851.1Skamil	atf_tc_set_md_var(tc, "descr",
52861.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
52871.1Skamil	    "from catching other signals");
52881.1Skamil}
52891.1Skamil
52901.1SkamilATF_TC_BODY(signal1, tc)
52911.1Skamil{
52921.1Skamil	const int exitval = 5;
52931.1Skamil	const int sigval = SIGSTOP;
52941.1Skamil	const int sigmasked = SIGTRAP;
52951.1Skamil	const int signotmasked = SIGINT;
52961.1Skamil	pid_t child, wpid;
52971.1Skamil#if defined(TWAIT_HAVE_STATUS)
52981.1Skamil	int status;
52991.1Skamil#endif
53001.1Skamil	sigset_t intmask;
53011.1Skamil
53021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53041.1Skamil	if (child == 0) {
53051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53071.1Skamil
53081.1Skamil		sigemptyset(&intmask);
53091.1Skamil		sigaddset(&intmask, sigmasked);
53101.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
53111.1Skamil
53121.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53131.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53141.1Skamil
53151.13Schristos		DPRINTF("Before raising %s from child\n",
53161.1Skamil		    strsignal(signotmasked));
53171.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
53181.1Skamil
53191.13Schristos		DPRINTF("Before exiting of the child process\n");
53201.1Skamil		_exit(exitval);
53211.1Skamil	}
53221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53231.1Skamil
53241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53261.1Skamil
53271.1Skamil	validate_status_stopped(status, sigval);
53281.1Skamil
53291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53301.1Skamil	    "without signal to be sent\n");
53311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53321.1Skamil
53331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53351.1Skamil
53361.1Skamil	validate_status_stopped(status, signotmasked);
53371.1Skamil
53381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53391.1Skamil	    "without signal to be sent\n");
53401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53411.1Skamil
53421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53441.1Skamil
53451.1Skamil	validate_status_exited(status, exitval);
53461.1Skamil
53471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53481.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53491.1Skamil}
53501.1Skamil
53511.1SkamilATF_TC(signal2);
53521.1SkamilATF_TC_HEAD(signal2, tc)
53531.1Skamil{
53541.1Skamil	atf_tc_set_md_var(tc, "descr",
53551.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
53561.1Skamil	    "catching this raised signal");
53571.1Skamil}
53581.1Skamil
53591.1SkamilATF_TC_BODY(signal2, tc)
53601.1Skamil{
53611.1Skamil	const int exitval = 5;
53621.1Skamil	const int sigval = SIGSTOP;
53631.1Skamil	const int sigmasked = SIGTRAP;
53641.1Skamil	pid_t child, wpid;
53651.1Skamil#if defined(TWAIT_HAVE_STATUS)
53661.1Skamil	int status;
53671.1Skamil#endif
53681.1Skamil	sigset_t intmask;
53691.1Skamil
53701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53721.1Skamil	if (child == 0) {
53731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53751.1Skamil
53761.1Skamil		sigemptyset(&intmask);
53771.1Skamil		sigaddset(&intmask, sigmasked);
53781.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
53791.1Skamil
53801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53821.1Skamil
53831.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
53841.1Skamil		    strsignal(sigmasked));
53851.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
53861.1Skamil
53871.13Schristos		DPRINTF("Before exiting of the child process\n");
53881.1Skamil		_exit(exitval);
53891.1Skamil	}
53901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53911.1Skamil
53921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53941.1Skamil
53951.1Skamil	validate_status_stopped(status, sigval);
53961.1Skamil
53971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53981.1Skamil	    "without signal to be sent\n");
53991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54001.1Skamil
54011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54031.1Skamil
54041.1Skamil	validate_status_exited(status, exitval);
54051.1Skamil
54061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54081.1Skamil}
54091.1Skamil
54101.1SkamilATF_TC(signal3);
54111.1SkamilATF_TC_HEAD(signal3, tc)
54121.1Skamil{
54131.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
54141.1Skamil	atf_tc_set_md_var(tc, "descr",
54151.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
54161.1Skamil	    "catching software breakpoints");
54171.1Skamil}
54181.1Skamil
54191.1SkamilATF_TC_BODY(signal3, tc)
54201.1Skamil{
54211.1Skamil	const int exitval = 5;
54221.1Skamil	const int sigval = SIGSTOP;
54231.1Skamil	const int sigmasked = SIGTRAP;
54241.1Skamil	pid_t child, wpid;
54251.1Skamil#if defined(TWAIT_HAVE_STATUS)
54261.1Skamil	int status;
54271.1Skamil#endif
54281.1Skamil	sigset_t intmask;
54291.1Skamil
54301.20Skamil	atf_tc_expect_fail("PR kern/51918");
54311.20Skamil
54321.20Skamil	// This test breaks now on some ports, temporarily disable it
54331.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
54341.20Skamil
54351.10Smartin#if defined(__sparc__)
54361.7Skamil	atf_tc_expect_timeout("PR kern/52167");
54371.7Skamil
54381.7Skamil	// timeout wins, failure still valid
54391.7Skamil	// atf_tc_expect_fail("PR kern/51918");
54401.7Skamil#endif
54411.1Skamil
54421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54441.1Skamil	if (child == 0) {
54451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54471.1Skamil
54481.1Skamil		sigemptyset(&intmask);
54491.1Skamil		sigaddset(&intmask, sigmasked);
54501.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
54511.1Skamil
54521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54541.1Skamil
54551.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
54561.4Skamil
54571.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
54581.4Skamil		PTRACE_BREAKPOINT_ASM;
54591.1Skamil#else
54601.4Skamil		/* port me */
54611.1Skamil#endif
54621.1Skamil
54631.13Schristos		DPRINTF("Before exiting of the child process\n");
54641.1Skamil		_exit(exitval);
54651.1Skamil	}
54661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54671.1Skamil
54681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54701.1Skamil
54711.1Skamil	validate_status_stopped(status, sigval);
54721.1Skamil
54731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54741.1Skamil	    "without signal to be sent\n");
54751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54761.1Skamil
54771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54791.1Skamil
54801.1Skamil	validate_status_stopped(status, sigmasked);
54811.1Skamil
54821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54831.1Skamil	    "without signal to be sent\n");
54841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54851.1Skamil
54861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54881.1Skamil
54891.1Skamil	validate_status_exited(status, exitval);
54901.1Skamil
54911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54931.1Skamil}
54941.1Skamil
54951.1Skamil#if defined(PT_STEP)
54961.1SkamilATF_TC(signal4);
54971.1SkamilATF_TC_HEAD(signal4, tc)
54981.1Skamil{
54991.1Skamil	atf_tc_set_md_var(tc, "descr",
55001.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55011.1Skamil	    "catching single step trap");
55021.1Skamil}
55031.1Skamil
55041.1SkamilATF_TC_BODY(signal4, tc)
55051.1Skamil{
55061.1Skamil	const int exitval = 5;
55071.1Skamil	const int sigval = SIGSTOP;
55081.1Skamil	const int sigmasked = SIGTRAP;
55091.1Skamil	pid_t child, wpid;
55101.1Skamil#if defined(TWAIT_HAVE_STATUS)
55111.1Skamil	int status;
55121.1Skamil#endif
55131.1Skamil	sigset_t intmask;
55141.1Skamil	int happy;
55151.1Skamil
55161.1Skamil#if defined(__arm__)
55171.5Skamil	/* PT_STEP not supported on arm 32-bit */
55181.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
55191.1Skamil#endif
55201.1Skamil
55211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55231.1Skamil	if (child == 0) {
55241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55261.1Skamil
55271.1Skamil		happy = check_happy(100);
55281.1Skamil
55291.1Skamil		sigemptyset(&intmask);
55301.1Skamil		sigaddset(&intmask, sigmasked);
55311.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55321.1Skamil
55331.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55341.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55351.1Skamil
55361.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
55371.1Skamil
55381.13Schristos		DPRINTF("Before exiting of the child process\n");
55391.1Skamil		_exit(exitval);
55401.1Skamil	}
55411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55421.1Skamil
55431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55451.1Skamil
55461.1Skamil	validate_status_stopped(status, sigval);
55471.1Skamil
55481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55491.1Skamil	    "without signal to be sent\n");
55501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
55511.1Skamil
55521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55541.1Skamil
55551.1Skamil	validate_status_stopped(status, sigmasked);
55561.1Skamil
55571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55581.1Skamil	    "without signal to be sent\n");
55591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55601.1Skamil
55611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55631.1Skamil
55641.1Skamil	validate_status_exited(status, exitval);
55651.1Skamil
55661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55681.1Skamil}
55691.1Skamil#endif
55701.1Skamil
55711.1SkamilATF_TC(signal5);
55721.1SkamilATF_TC_HEAD(signal5, tc)
55731.1Skamil{
55741.1Skamil	atf_tc_set_md_var(tc, "descr",
55751.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55761.1Skamil	    "catching exec() breakpoint");
55771.1Skamil}
55781.1Skamil
55791.1SkamilATF_TC_BODY(signal5, tc)
55801.1Skamil{
55811.1Skamil	const int exitval = 5;
55821.1Skamil	const int sigval = SIGSTOP;
55831.1Skamil	const int sigmasked = SIGTRAP;
55841.1Skamil	pid_t child, wpid;
55851.1Skamil#if defined(TWAIT_HAVE_STATUS)
55861.1Skamil	int status;
55871.1Skamil#endif
55881.1Skamil	sigset_t intmask;
55891.1Skamil
55901.14Schristos	atf_tc_expect_fail("wrong signal");
55911.14Schristos
55921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55941.1Skamil	if (child == 0) {
55951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55971.1Skamil
55981.1Skamil		sigemptyset(&intmask);
55991.1Skamil		sigaddset(&intmask, sigmasked);
56001.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56011.1Skamil
56021.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56031.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56041.1Skamil
56051.13Schristos		DPRINTF("Before calling execve(2) from child\n");
56061.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
56071.1Skamil
56081.13Schristos		DPRINTF("Before exiting of the child process\n");
56091.1Skamil		_exit(exitval);
56101.1Skamil	}
56111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56121.1Skamil
56131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56151.1Skamil
56161.1Skamil	validate_status_stopped(status, sigval);
56171.1Skamil
56181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56191.1Skamil	    "without signal to be sent\n");
56201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56211.1Skamil
56221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56241.1Skamil
56251.1Skamil	validate_status_stopped(status, sigmasked);
56261.1Skamil
56271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56281.1Skamil	    "without signal to be sent\n");
56291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56301.1Skamil
56311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56331.1Skamil
56341.1Skamil	validate_status_exited(status, exitval);
56351.1Skamil
56361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56381.1Skamil}
56391.1Skamil
56401.1Skamil#if defined(TWAIT_HAVE_PID)
56411.1SkamilATF_TC(signal6);
56421.1SkamilATF_TC_HEAD(signal6, tc)
56431.1Skamil{
56441.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
56451.1Skamil	atf_tc_set_md_var(tc, "descr",
56461.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
56471.1Skamil	    "catching PTRACE_FORK breakpoint");
56481.1Skamil}
56491.1Skamil
56501.1SkamilATF_TC_BODY(signal6, tc)
56511.1Skamil{
56521.1Skamil	const int exitval = 5;
56531.1Skamil	const int exitval2 = 15;
56541.1Skamil	const int sigval = SIGSTOP;
56551.1Skamil	const int sigmasked = SIGTRAP;
56561.1Skamil	pid_t child, child2, wpid;
56571.1Skamil#if defined(TWAIT_HAVE_STATUS)
56581.1Skamil	int status;
56591.1Skamil#endif
56601.1Skamil	sigset_t intmask;
56611.1Skamil	ptrace_state_t state;
56621.1Skamil	const int slen = sizeof(state);
56631.1Skamil	ptrace_event_t event;
56641.1Skamil	const int elen = sizeof(event);
56651.1Skamil
56661.14Schristos	atf_tc_expect_timeout("PR kern/51918");
56671.14Schristos
56681.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56691.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56701.1Skamil	if (child == 0) {
56711.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56721.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56731.1Skamil
56741.1Skamil		sigemptyset(&intmask);
56751.1Skamil		sigaddset(&intmask, sigmasked);
56761.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56771.1Skamil
56781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56801.1Skamil
56811.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
56821.1Skamil
56831.1Skamil		if (child2 == 0)
56841.1Skamil			_exit(exitval2);
56851.1Skamil
56861.1Skamil		FORKEE_REQUIRE_SUCCESS
56871.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
56881.1Skamil
56891.1Skamil		forkee_status_exited(status, exitval2);
56901.1Skamil
56911.13Schristos		DPRINTF("Before exiting of the child process\n");
56921.1Skamil		_exit(exitval);
56931.1Skamil	}
56941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56951.1Skamil
56961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56981.1Skamil
56991.1Skamil	validate_status_stopped(status, sigval);
57001.1Skamil
57011.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
57021.1Skamil	event.pe_set_event = PTRACE_FORK;
57031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
57041.1Skamil
57051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57061.1Skamil	    "without signal to be sent\n");
57071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57081.1Skamil
57091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57111.1Skamil
57121.1Skamil	validate_status_stopped(status, sigmasked);
57131.1Skamil
57141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
57151.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
57161.1Skamil
57171.1Skamil	child2 = state.pe_other_pid;
57181.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
57191.1Skamil
57201.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
57211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
57221.1Skamil	    child2);
57231.1Skamil
57241.1Skamil	validate_status_stopped(status, SIGTRAP);
57251.1Skamil
57261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
57271.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
57281.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
57291.1Skamil
57301.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
57311.1Skamil	    "without signal to be sent\n");
57321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
57331.1Skamil
57341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57351.1Skamil	    "without signal to be sent\n");
57361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57371.1Skamil
57381.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
57391.1Skamil	    TWAIT_FNAME);
57401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
57411.1Skamil	    child2);
57421.1Skamil
57431.1Skamil	validate_status_exited(status, exitval2);
57441.1Skamil
57451.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
57461.1Skamil	    TWAIT_FNAME);
57471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
57481.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
57491.1Skamil
57501.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
57511.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
57521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57531.1Skamil
57541.1Skamil	validate_status_stopped(status, SIGCHLD);
57551.1Skamil
57561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57571.1Skamil	    "without signal to be sent\n");
57581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57591.1Skamil
57601.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
57611.1Skamil	    TWAIT_FNAME);
57621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57631.1Skamil
57641.1Skamil	validate_status_exited(status, exitval);
57651.1Skamil
57661.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
57671.1Skamil	    TWAIT_FNAME);
57681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57691.1Skamil}
57701.1Skamil#endif
57711.1Skamil
57721.1Skamil#if defined(TWAIT_HAVE_PID)
57731.1SkamilATF_TC(signal7);
57741.1SkamilATF_TC_HEAD(signal7, tc)
57751.1Skamil{
57761.1Skamil	atf_tc_set_md_var(tc, "descr",
57771.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57781.1Skamil	    "catching PTRACE_VFORK breakpoint");
57791.1Skamil}
57801.1Skamil
57811.1SkamilATF_TC_BODY(signal7, tc)
57821.1Skamil{
57831.1Skamil	const int exitval = 5;
57841.1Skamil	const int exitval2 = 15;
57851.1Skamil	const int sigval = SIGSTOP;
57861.1Skamil	const int sigmasked = SIGTRAP;
57871.1Skamil	pid_t child, child2, wpid;
57881.1Skamil#if defined(TWAIT_HAVE_STATUS)
57891.1Skamil	int status;
57901.1Skamil#endif
57911.1Skamil	sigset_t intmask;
57921.1Skamil	ptrace_state_t state;
57931.1Skamil	const int slen = sizeof(state);
57941.1Skamil	ptrace_event_t event;
57951.1Skamil	const int elen = sizeof(event);
57961.1Skamil
57971.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
57981.14Schristos
57991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58011.1Skamil	if (child == 0) {
58021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58041.1Skamil
58051.1Skamil		sigemptyset(&intmask);
58061.1Skamil		sigaddset(&intmask, sigmasked);
58071.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58081.1Skamil
58091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58111.1Skamil
58121.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
58131.1Skamil
58141.1Skamil		if (child2 == 0)
58151.1Skamil			_exit(exitval2);
58161.1Skamil
58171.1Skamil		FORKEE_REQUIRE_SUCCESS
58181.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
58191.1Skamil
58201.1Skamil		forkee_status_exited(status, exitval2);
58211.1Skamil
58221.13Schristos		DPRINTF("Before exiting of the child process\n");
58231.1Skamil		_exit(exitval);
58241.1Skamil	}
58251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58261.1Skamil
58271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58291.1Skamil
58301.1Skamil	validate_status_stopped(status, sigval);
58311.1Skamil
58321.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
58331.1Skamil	event.pe_set_event = PTRACE_VFORK;
58341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
58351.1Skamil
58361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58371.1Skamil	    "without signal to be sent\n");
58381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58391.1Skamil
58401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58421.1Skamil
58431.1Skamil	validate_status_stopped(status, sigmasked);
58441.1Skamil
58451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
58461.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
58471.1Skamil
58481.1Skamil	child2 = state.pe_other_pid;
58491.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
58501.1Skamil
58511.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
58521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58531.1Skamil	    child2);
58541.1Skamil
58551.1Skamil	validate_status_stopped(status, SIGTRAP);
58561.1Skamil
58571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
58581.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
58591.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
58601.1Skamil
58611.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
58621.1Skamil	    "without signal to be sent\n");
58631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
58641.1Skamil
58651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58661.1Skamil	    "without signal to be sent\n");
58671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58681.1Skamil
58691.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
58701.1Skamil	    TWAIT_FNAME);
58711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58721.1Skamil	    child2);
58731.1Skamil
58741.1Skamil	validate_status_exited(status, exitval2);
58751.1Skamil
58761.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
58771.1Skamil	    TWAIT_FNAME);
58781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
58791.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
58801.1Skamil
58811.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
58821.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
58831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58841.1Skamil
58851.1Skamil	validate_status_stopped(status, SIGCHLD);
58861.1Skamil
58871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58881.1Skamil	    "without signal to be sent\n");
58891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58901.1Skamil
58911.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
58921.1Skamil	    TWAIT_FNAME);
58931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58941.1Skamil
58951.1Skamil	validate_status_exited(status, exitval);
58961.1Skamil
58971.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
58981.1Skamil	    TWAIT_FNAME);
58991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59001.1Skamil}
59011.1Skamil#endif
59021.1Skamil
59031.1SkamilATF_TC(signal8);
59041.1SkamilATF_TC_HEAD(signal8, tc)
59051.1Skamil{
59061.1Skamil	atf_tc_set_md_var(tc, "descr",
59071.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59081.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
59091.1Skamil}
59101.1Skamil
59111.1SkamilATF_TC_BODY(signal8, tc)
59121.1Skamil{
59131.1Skamil	const int exitval = 5;
59141.1Skamil	const int exitval2 = 15;
59151.1Skamil	const int sigval = SIGSTOP;
59161.1Skamil	const int sigmasked = SIGTRAP;
59171.1Skamil	pid_t child, child2, wpid;
59181.1Skamil#if defined(TWAIT_HAVE_STATUS)
59191.1Skamil	int status;
59201.1Skamil#endif
59211.1Skamil	sigset_t intmask;
59221.1Skamil	ptrace_state_t state;
59231.1Skamil	const int slen = sizeof(state);
59241.1Skamil	ptrace_event_t event;
59251.1Skamil	const int elen = sizeof(event);
59261.1Skamil
59271.14Schristos	atf_tc_expect_fail("PR kern/51918");
59281.14Schristos
59291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59311.1Skamil	if (child == 0) {
59321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59341.1Skamil
59351.1Skamil		sigemptyset(&intmask);
59361.1Skamil		sigaddset(&intmask, sigmasked);
59371.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59381.1Skamil
59391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59411.1Skamil
59421.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
59431.1Skamil
59441.1Skamil		if (child2 == 0)
59451.1Skamil			_exit(exitval2);
59461.1Skamil
59471.1Skamil		FORKEE_REQUIRE_SUCCESS
59481.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
59491.1Skamil
59501.1Skamil		forkee_status_exited(status, exitval2);
59511.1Skamil
59521.13Schristos		DPRINTF("Before exiting of the child process\n");
59531.1Skamil		_exit(exitval);
59541.1Skamil	}
59551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59561.1Skamil
59571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59591.1Skamil
59601.1Skamil	validate_status_stopped(status, sigval);
59611.1Skamil
59621.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
59631.1Skamil	    child);
59641.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
59651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
59661.1Skamil
59671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59681.1Skamil	    "without signal to be sent\n");
59691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59701.1Skamil
59711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59731.1Skamil
59741.1Skamil	validate_status_stopped(status, sigmasked);
59751.1Skamil
59761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
59771.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
59781.1Skamil
59791.1Skamil	child2 = state.pe_other_pid;
59801.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
59811.1Skamil
59821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59831.1Skamil	    "without signal to be sent\n");
59841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59851.1Skamil
59861.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
59871.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
59881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59891.1Skamil
59901.1Skamil	validate_status_stopped(status, SIGCHLD);
59911.1Skamil
59921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59931.1Skamil	    "without signal to be sent\n");
59941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59951.1Skamil
59961.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
59971.1Skamil	    TWAIT_FNAME);
59981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59991.1Skamil
60001.1Skamil	validate_status_exited(status, exitval);
60011.1Skamil
60021.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60031.1Skamil	    TWAIT_FNAME);
60041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60051.1Skamil}
60061.1Skamil
60071.1SkamilATF_TC(signal9);
60081.1SkamilATF_TC_HEAD(signal9, tc)
60091.1Skamil{
60101.1Skamil	atf_tc_set_md_var(tc, "descr",
60111.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
60121.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
60131.1Skamil}
60141.1Skamil
60151.1SkamilATF_TC_BODY(signal9, tc)
60161.1Skamil{
60171.1Skamil	const int exitval = 5;
60181.1Skamil	const int sigval = SIGSTOP;
60191.1Skamil	const int sigmasked = SIGTRAP;
60201.1Skamil	pid_t child, wpid;
60211.1Skamil#if defined(TWAIT_HAVE_STATUS)
60221.1Skamil	int status;
60231.1Skamil#endif
60241.1Skamil	sigset_t intmask;
60251.1Skamil	ptrace_state_t state;
60261.1Skamil	const int slen = sizeof(state);
60271.1Skamil	ptrace_event_t event;
60281.1Skamil	const int elen = sizeof(event);
60291.1Skamil	ucontext_t uc;
60301.1Skamil	lwpid_t lid;
60311.1Skamil	static const size_t ssize = 16*1024;
60321.1Skamil	void *stack;
60331.1Skamil
60341.14Schristos	atf_tc_expect_fail("PR kern/51918");
60351.14Schristos
60361.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60371.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60381.1Skamil	if (child == 0) {
60391.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60401.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60411.1Skamil
60421.1Skamil		sigemptyset(&intmask);
60431.1Skamil		sigaddset(&intmask, sigmasked);
60441.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60451.1Skamil
60461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60481.1Skamil
60491.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
60501.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
60511.1Skamil
60521.13Schristos		DPRINTF("Before making context for new lwp in child\n");
60531.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
60541.1Skamil
60551.13Schristos		DPRINTF("Before creating new in child\n");
60561.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
60571.1Skamil
60581.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
60591.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
60601.1Skamil
60611.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
60621.1Skamil		    "are the same\n", lid, the_lwp_id);
60631.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
60641.1Skamil
60651.13Schristos		DPRINTF("Before exiting of the child process\n");
60661.1Skamil		_exit(exitval);
60671.1Skamil	}
60681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60691.1Skamil
60701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60721.1Skamil
60731.1Skamil	validate_status_stopped(status, sigval);
60741.1Skamil
60751.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
60761.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
60771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60781.1Skamil
60791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60801.1Skamil	    "without signal to be sent\n");
60811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60821.1Skamil
60831.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60841.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
60851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60861.1Skamil
60871.1Skamil	validate_status_stopped(status, sigmasked);
60881.1Skamil
60891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60901.1Skamil
60911.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
60921.1Skamil
60931.1Skamil	lid = state.pe_lwp;
60941.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
60951.1Skamil
60961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60971.1Skamil	    "without signal to be sent\n");
60981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60991.1Skamil
61001.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61011.1Skamil	    TWAIT_FNAME);
61021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61031.1Skamil
61041.1Skamil	validate_status_exited(status, exitval);
61051.1Skamil
61061.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61071.1Skamil	    TWAIT_FNAME);
61081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61091.1Skamil}
61101.1Skamil
61111.1SkamilATF_TC(signal10);
61121.1SkamilATF_TC_HEAD(signal10, tc)
61131.1Skamil{
61141.1Skamil	atf_tc_set_md_var(tc, "descr",
61151.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61161.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
61171.1Skamil}
61181.1Skamil
61191.1SkamilATF_TC_BODY(signal10, tc)
61201.1Skamil{
61211.1Skamil	const int exitval = 5;
61221.1Skamil	const int sigval = SIGSTOP;
61231.1Skamil	const int sigmasked = SIGTRAP;
61241.1Skamil	pid_t child, wpid;
61251.1Skamil#if defined(TWAIT_HAVE_STATUS)
61261.1Skamil	int status;
61271.1Skamil#endif
61281.1Skamil	sigset_t intmask;
61291.1Skamil	ptrace_state_t state;
61301.1Skamil	const int slen = sizeof(state);
61311.1Skamil	ptrace_event_t event;
61321.1Skamil	const int elen = sizeof(event);
61331.1Skamil	ucontext_t uc;
61341.1Skamil	lwpid_t lid;
61351.1Skamil	static const size_t ssize = 16*1024;
61361.1Skamil	void *stack;
61371.1Skamil
61381.14Schristos	atf_tc_expect_fail("PR kern/51918");
61391.14Schristos
61401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61421.1Skamil	if (child == 0) {
61431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61451.1Skamil
61461.1Skamil		sigemptyset(&intmask);
61471.1Skamil		sigaddset(&intmask, sigmasked);
61481.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61491.1Skamil
61501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61521.1Skamil
61531.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
61541.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
61551.1Skamil
61561.13Schristos		DPRINTF("Before making context for new lwp in child\n");
61571.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
61581.1Skamil
61591.13Schristos		DPRINTF("Before creating new in child\n");
61601.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
61611.1Skamil
61621.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
61631.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
61641.1Skamil
61651.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
61661.1Skamil		    "are the same\n", lid, the_lwp_id);
61671.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
61681.1Skamil
61691.13Schristos		DPRINTF("Before exiting of the child process\n");
61701.1Skamil		_exit(exitval);
61711.1Skamil	}
61721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61731.1Skamil
61741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61761.1Skamil
61771.1Skamil	validate_status_stopped(status, sigval);
61781.1Skamil
61791.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
61801.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
61811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
61821.1Skamil
61831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61841.1Skamil	    "without signal to be sent\n");
61851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61861.1Skamil
61871.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61881.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
61891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61901.1Skamil
61911.1Skamil	validate_status_stopped(status, sigmasked);
61921.1Skamil
61931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61941.1Skamil
61951.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
61961.1Skamil
61971.1Skamil	lid = state.pe_lwp;
61981.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
61991.1Skamil
62001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62011.1Skamil	    "without signal to be sent\n");
62021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62031.1Skamil
62041.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62051.1Skamil	    TWAIT_FNAME);
62061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62071.1Skamil
62081.1Skamil	validate_status_exited(status, exitval);
62091.1Skamil
62101.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62111.1Skamil	    TWAIT_FNAME);
62121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62131.1Skamil}
62141.1Skamil
62151.1Skamilstatic void
62161.1Skamillwp_main_stop(void *arg)
62171.1Skamil{
62181.1Skamil	the_lwp_id = _lwp_self();
62191.1Skamil
62201.1Skamil	raise(SIGTRAP);
62211.1Skamil
62221.1Skamil	_lwp_exit();
62231.1Skamil}
62241.1Skamil
62251.1SkamilATF_TC(suspend1);
62261.1SkamilATF_TC_HEAD(suspend1, tc)
62271.1Skamil{
62281.1Skamil	atf_tc_set_md_var(tc, "descr",
62291.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
62301.1Skamil	    "resumed by a tracee");
62311.1Skamil}
62321.1Skamil
62331.1SkamilATF_TC_BODY(suspend1, tc)
62341.1Skamil{
62351.1Skamil	const int exitval = 5;
62361.1Skamil	const int sigval = SIGSTOP;
62371.1Skamil	pid_t child, wpid;
62381.1Skamil#if defined(TWAIT_HAVE_STATUS)
62391.1Skamil	int status;
62401.1Skamil#endif
62411.1Skamil	ucontext_t uc;
62421.1Skamil	lwpid_t lid;
62431.1Skamil	static const size_t ssize = 16*1024;
62441.1Skamil	void *stack;
62451.1Skamil	struct ptrace_lwpinfo pl;
62461.1Skamil	struct ptrace_siginfo psi;
62471.1Skamil	volatile int go = 0;
62481.1Skamil
62491.17Skamil	// Feature pending for refactoring
62501.17Skamil	atf_tc_expect_fail("PR kern/51995");
62511.17Skamil
62521.16Skamil	// Hangs with qemu
62531.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
62541.16Skamil
62551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62571.1Skamil	if (child == 0) {
62581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62601.1Skamil
62611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62631.1Skamil
62641.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
62651.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
62661.1Skamil
62671.13Schristos		DPRINTF("Before making context for new lwp in child\n");
62681.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
62691.1Skamil
62701.13Schristos		DPRINTF("Before creating new in child\n");
62711.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
62721.1Skamil
62731.1Skamil		while (go == 0)
62741.1Skamil			continue;
62751.1Skamil
62761.1Skamil		raise(SIGINT);
62771.1Skamil
62781.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
62791.1Skamil
62801.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
62811.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
62821.1Skamil
62831.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
62841.1Skamil		    "are the same\n", lid, the_lwp_id);
62851.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
62861.1Skamil
62871.13Schristos		DPRINTF("Before exiting of the child process\n");
62881.1Skamil		_exit(exitval);
62891.1Skamil	}
62901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62911.1Skamil
62921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62941.1Skamil
62951.1Skamil	validate_status_stopped(status, sigval);
62961.1Skamil
62971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62981.1Skamil	    "without signal to be sent\n");
62991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63001.1Skamil
63011.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63021.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
63031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63041.1Skamil
63051.1Skamil	validate_status_stopped(status, SIGTRAP);
63061.1Skamil
63071.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
63081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
63091.1Skamil
63101.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
63111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
63121.1Skamil
63131.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
63141.1Skamil	    child, getpid());
63151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
63161.1Skamil
63171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63181.1Skamil	    "without signal to be sent\n");
63191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63201.1Skamil
63211.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63221.1Skamil	    "SIGINT\n", TWAIT_FNAME);
63231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63241.1Skamil
63251.1Skamil	validate_status_stopped(status, SIGINT);
63261.1Skamil
63271.1Skamil	pl.pl_lwpid = 0;
63281.1Skamil
63291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
63301.1Skamil	while (pl.pl_lwpid != 0) {
63311.1Skamil
63321.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
63331.1Skamil		switch (pl.pl_lwpid) {
63341.1Skamil		case 1:
63351.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
63361.1Skamil			break;
63371.1Skamil		case 2:
63381.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
63391.1Skamil			break;
63401.1Skamil		}
63411.1Skamil	}
63421.1Skamil
63431.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63441.1Skamil	    "without signal to be sent\n");
63451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63461.1Skamil
63471.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63481.1Skamil	    TWAIT_FNAME);
63491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63501.1Skamil
63511.1Skamil	validate_status_exited(status, exitval);
63521.1Skamil
63531.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63541.1Skamil	    TWAIT_FNAME);
63551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63561.1Skamil}
63571.1Skamil
63581.1SkamilATF_TC(suspend2);
63591.1SkamilATF_TC_HEAD(suspend2, tc)
63601.1Skamil{
63611.1Skamil	atf_tc_set_md_var(tc, "descr",
63621.1Skamil	    "Verify that the while the only thread within a process is "
63631.1Skamil	    "suspended, the whole process cannot be unstopped");
63641.1Skamil}
63651.1Skamil
63661.1SkamilATF_TC_BODY(suspend2, tc)
63671.1Skamil{
63681.1Skamil	const int exitval = 5;
63691.1Skamil	const int sigval = SIGSTOP;
63701.1Skamil	pid_t child, wpid;
63711.1Skamil#if defined(TWAIT_HAVE_STATUS)
63721.1Skamil	int status;
63731.1Skamil#endif
63741.1Skamil	struct ptrace_siginfo psi;
63751.1Skamil
63761.17Skamil	// Feature pending for refactoring
63771.17Skamil	atf_tc_expect_fail("PR kern/51995");
63781.17Skamil
63791.16Skamil	// Hangs with qemu
63801.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
63811.16Skamil
63821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63841.1Skamil	if (child == 0) {
63851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63871.1Skamil
63881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63901.1Skamil
63911.13Schristos		DPRINTF("Before exiting of the child process\n");
63921.1Skamil		_exit(exitval);
63931.1Skamil	}
63941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63951.1Skamil
63961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63981.1Skamil
63991.1Skamil	validate_status_stopped(status, sigval);
64001.1Skamil
64011.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
64021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
64031.1Skamil
64041.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
64051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
64061.1Skamil
64071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64081.1Skamil	    "without signal to be sent\n");
64091.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
64101.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
64111.1Skamil
64121.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
64131.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
64141.1Skamil
64151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64161.1Skamil	    "without signal to be sent\n");
64171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64181.1Skamil
64191.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64201.1Skamil	    TWAIT_FNAME);
64211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64221.1Skamil
64231.1Skamil	validate_status_exited(status, exitval);
64241.1Skamil
64251.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64261.1Skamil	    TWAIT_FNAME);
64271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64281.1Skamil}
64291.1Skamil
64301.1SkamilATF_TC(resume1);
64311.1SkamilATF_TC_HEAD(resume1, tc)
64321.1Skamil{
64331.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
64341.1Skamil	atf_tc_set_md_var(tc, "descr",
64351.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
64361.1Skamil	    "resumed by the debugger");
64371.1Skamil}
64381.1Skamil
64391.1SkamilATF_TC_BODY(resume1, tc)
64401.1Skamil{
64411.1Skamil	struct msg_fds fds;
64421.1Skamil	const int exitval = 5;
64431.1Skamil	const int sigval = SIGSTOP;
64441.1Skamil	pid_t child, wpid;
64451.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
64461.1Skamil#if defined(TWAIT_HAVE_STATUS)
64471.1Skamil	int status;
64481.1Skamil#endif
64491.1Skamil	ucontext_t uc;
64501.1Skamil	lwpid_t lid;
64511.1Skamil	static const size_t ssize = 16*1024;
64521.1Skamil	void *stack;
64531.1Skamil	struct ptrace_lwpinfo pl;
64541.1Skamil	struct ptrace_siginfo psi;
64551.1Skamil
64561.17Skamil	// Feature pending for refactoring
64571.17Skamil	atf_tc_expect_fail("PR kern/51995");
64581.17Skamil
64591.15Schristos	// Hangs with qemu
64601.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
64611.1Skamil
64621.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
64631.1Skamil
64641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64661.1Skamil	if (child == 0) {
64671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64691.1Skamil
64701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64721.1Skamil
64731.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64741.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64751.1Skamil
64761.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64771.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
64781.1Skamil
64791.13Schristos		DPRINTF("Before creating new in child\n");
64801.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64811.1Skamil
64821.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
64831.1Skamil
64841.1Skamil		raise(SIGINT);
64851.1Skamil
64861.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64871.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64881.1Skamil
64891.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64901.1Skamil		    "are the same\n", lid, the_lwp_id);
64911.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64921.1Skamil
64931.13Schristos		DPRINTF("Before exiting of the child process\n");
64941.1Skamil		_exit(exitval);
64951.1Skamil	}
64961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64971.1Skamil
64981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65001.1Skamil
65011.1Skamil	validate_status_stopped(status, sigval);
65021.1Skamil
65031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65041.1Skamil	    "without signal to be sent\n");
65051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65061.1Skamil
65071.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65081.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65101.1Skamil
65111.1Skamil	validate_status_stopped(status, SIGTRAP);
65121.1Skamil
65131.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
65141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
65151.1Skamil
65161.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
65171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
65181.1Skamil
65191.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
65201.1Skamil
65211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65221.1Skamil	    "without signal to be sent\n");
65231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65241.1Skamil
65251.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65261.1Skamil	    "SIGINT\n", TWAIT_FNAME);
65271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65281.1Skamil
65291.1Skamil	validate_status_stopped(status, SIGINT);
65301.1Skamil
65311.1Skamil	pl.pl_lwpid = 0;
65321.1Skamil
65331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
65341.1Skamil	while (pl.pl_lwpid != 0) {
65351.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
65361.1Skamil		switch (pl.pl_lwpid) {
65371.1Skamil		case 1:
65381.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
65391.1Skamil			break;
65401.1Skamil		case 2:
65411.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
65421.1Skamil			break;
65431.1Skamil		}
65441.1Skamil	}
65451.1Skamil
65461.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
65471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
65481.1Skamil
65491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65501.1Skamil	    "without signal to be sent\n");
65511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65521.1Skamil
65531.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65541.1Skamil	    TWAIT_FNAME);
65551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65561.1Skamil
65571.1Skamil	validate_status_exited(status, exitval);
65581.1Skamil
65591.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65601.1Skamil	    TWAIT_FNAME);
65611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65621.1Skamil
65631.1Skamil	msg_close(&fds);
65641.1Skamil
65651.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
65661.1Skamil	sleep(10);
65671.1Skamil}
65681.1Skamil
65691.1SkamilATF_TC(syscall1);
65701.1SkamilATF_TC_HEAD(syscall1, tc)
65711.1Skamil{
65721.1Skamil	atf_tc_set_md_var(tc, "descr",
65731.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
65741.1Skamil}
65751.1Skamil
65761.1SkamilATF_TC_BODY(syscall1, tc)
65771.1Skamil{
65781.1Skamil	const int exitval = 5;
65791.1Skamil	const int sigval = SIGSTOP;
65801.1Skamil	pid_t child, wpid;
65811.1Skamil#if defined(TWAIT_HAVE_STATUS)
65821.1Skamil	int status;
65831.1Skamil#endif
65841.1Skamil	struct ptrace_siginfo info;
65851.1Skamil	memset(&info, 0, sizeof(info));
65861.1Skamil
65871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65891.1Skamil	if (child == 0) {
65901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65921.1Skamil
65931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65951.1Skamil
65961.1Skamil		syscall(SYS_getpid);
65971.1Skamil
65981.13Schristos		DPRINTF("Before exiting of the child process\n");
65991.1Skamil		_exit(exitval);
66001.1Skamil	}
66011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66021.1Skamil
66031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66051.1Skamil
66061.1Skamil	validate_status_stopped(status, sigval);
66071.1Skamil
66081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66091.1Skamil	    "without signal to be sent\n");
66101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66111.1Skamil
66121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66141.1Skamil
66151.1Skamil	validate_status_stopped(status, SIGTRAP);
66161.1Skamil
66171.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
66181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
66191.1Skamil
66201.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
66211.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
66221.1Skamil
66231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66241.1Skamil	    "without signal to be sent\n");
66251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66261.1Skamil
66271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66291.1Skamil
66301.1Skamil	validate_status_stopped(status, SIGTRAP);
66311.1Skamil
66321.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
66331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
66341.1Skamil
66351.13Schristos	DPRINTF("Before checking siginfo_t\n");
66361.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
66371.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
66381.1Skamil
66391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66401.1Skamil	    "without signal to be sent\n");
66411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66421.1Skamil
66431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66451.1Skamil
66461.1Skamil	validate_status_exited(status, exitval);
66471.1Skamil
66481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66501.1Skamil}
66511.1Skamil
66521.1SkamilATF_TC(syscallemu1);
66531.1SkamilATF_TC_HEAD(syscallemu1, tc)
66541.1Skamil{
66551.1Skamil	atf_tc_set_md_var(tc, "descr",
66561.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
66571.1Skamil}
66581.1Skamil
66591.1SkamilATF_TC_BODY(syscallemu1, tc)
66601.1Skamil{
66611.1Skamil	const int exitval = 5;
66621.1Skamil	const int sigval = SIGSTOP;
66631.1Skamil	pid_t child, wpid;
66641.1Skamil#if defined(TWAIT_HAVE_STATUS)
66651.1Skamil	int status;
66661.1Skamil#endif
66671.1Skamil
66681.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
66691.6Skamil	/* syscallemu does not work on sparc (32-bit) */
66701.6Skamil	atf_tc_expect_fail("PR kern/52166");
66711.6Skamil#endif
66721.6Skamil
66731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66751.1Skamil	if (child == 0) {
66761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66781.1Skamil
66791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66811.1Skamil
66821.1Skamil		syscall(SYS_exit, 100);
66831.1Skamil
66841.13Schristos		DPRINTF("Before exiting of the child process\n");
66851.1Skamil		_exit(exitval);
66861.1Skamil	}
66871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66881.1Skamil
66891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66911.1Skamil
66921.1Skamil	validate_status_stopped(status, sigval);
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("Set SYSCALLEMU for intercepted syscall\n");
67041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
67051.1Skamil
67061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67071.1Skamil	    "without signal to be sent\n");
67081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
67091.1Skamil
67101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67121.1Skamil
67131.1Skamil	validate_status_stopped(status, SIGTRAP);
67141.1Skamil
67151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67161.1Skamil	    "without signal to be sent\n");
67171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67181.1Skamil
67191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67211.1Skamil
67221.1Skamil	validate_status_exited(status, exitval);
67231.1Skamil
67241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67261.1Skamil}
67271.1Skamil
67281.26Skamil#if defined(TWAIT_HAVE_PID)
67291.26SkamilATF_TC(race1);
67301.26SkamilATF_TC_HEAD(race1, tc)
67311.26Skamil{
67321.26Skamil	atf_tc_set_md_var(tc, "descr",
67331.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
67341.26Skamil	    "process and no other error is reported");
67351.26Skamil}
67361.26Skamil
67371.26SkamilATF_TC_BODY(race1, tc)
67381.26Skamil{
67391.26Skamil	time_t start, end;
67401.26Skamil	double diff;
67411.26Skamil	unsigned long N = 0;
67421.26Skamil
67431.26Skamil	/* Reuse this test with attach1 */
67441.26Skamil
67451.26Skamil	start = time(NULL);
67461.26Skamil	while (true) {
67471.26Skamil		DPRINTF("Step: %lu\n", N);
67481.26Skamil		attach1_raw(true);
67491.26Skamil		end = time(NULL);
67501.26Skamil		diff = difftime(end, start);
67511.26Skamil		if (diff >= 5.0)
67521.26Skamil			break;
67531.26Skamil		++N;
67541.26Skamil	}
67551.26Skamil	DPRINTF("Iterations: %lu\n", N);
67561.26Skamil}
67571.26Skamil#endif
67581.26Skamil
67591.1Skamil#include "t_ptrace_amd64_wait.h"
67601.1Skamil#include "t_ptrace_i386_wait.h"
67611.1Skamil#include "t_ptrace_x86_wait.h"
67621.1Skamil
67631.1SkamilATF_TP_ADD_TCS(tp)
67641.1Skamil{
67651.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
67661.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
67671.33Skamil
67681.36Skamil	ATF_TP_ADD_TC(tp, traceme_raise1);
67691.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
67701.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
67711.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
67721.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
67731.33Skamil
67741.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
67751.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
67761.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
67771.34Skamil
67781.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler1);
67791.35Skamil//	ATF_TP_ADD_TC(tp, traceme_signal_nohandler2); // not yet
67801.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler3);
67811.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler4);
67821.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);
67831.1Skamil
67841.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
67851.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
67861.1Skamil	ATF_TP_ADD_TC(tp, attach3);
67871.1Skamil	ATF_TP_ADD_TC(tp, attach4);
67881.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
67891.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
67901.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
67911.1Skamil
67921.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
67931.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
67941.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
67951.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
67961.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
67971.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
67981.1Skamil
67991.31Skamil	ATF_TP_ADD_TC(tp, fork1);
68001.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
68011.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
68021.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
68031.31Skamil	ATF_TP_ADD_TC(tp, fork5);
68041.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
68051.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
68061.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
68071.31Skamil
68081.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
68091.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
68101.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
68111.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
68121.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
68131.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
68141.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
68151.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
68161.1Skamil
68171.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
68181.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
68191.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
68201.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
68211.1Skamil
68221.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
68231.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
68241.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
68251.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
68261.1Skamil
68271.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
68281.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
68291.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
68301.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
68311.1Skamil
68321.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
68331.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
68341.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
68351.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
68361.1Skamil
68371.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
68381.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
68391.1Skamil
68401.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
68411.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
68421.1Skamil
68431.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
68441.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
68451.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
68461.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
68471.1Skamil
68481.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
68491.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
68501.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
68511.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
68521.1Skamil
68531.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
68541.1Skamil
68551.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
68561.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
68571.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
68581.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
68591.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
68601.1Skamil
68611.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
68621.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
68631.1Skamil
68641.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
68651.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
68661.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
68671.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
68681.1Skamil
68691.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
68701.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
68711.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
68721.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
68731.2Skamil
68741.1Skamil	ATF_TP_ADD_TC(tp, kill1);
68751.1Skamil	ATF_TP_ADD_TC(tp, kill2);
68761.1Skamil
68771.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
68781.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
68791.1Skamil
68801.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
68811.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
68821.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
68831.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
68841.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
68851.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
68861.1Skamil
68871.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
68881.1Skamil
68891.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
68901.1Skamil
68911.1Skamil	ATF_TP_ADD_TC(tp, signal1);
68921.1Skamil	ATF_TP_ADD_TC(tp, signal2);
68931.1Skamil	ATF_TP_ADD_TC(tp, signal3);
68941.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
68951.1Skamil	ATF_TP_ADD_TC(tp, signal5);
68961.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
68971.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
68981.1Skamil	ATF_TP_ADD_TC(tp, signal8);
68991.1Skamil	ATF_TP_ADD_TC(tp, signal9);
69001.1Skamil	ATF_TP_ADD_TC(tp, signal10);
69011.1Skamil
69021.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
69031.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
69041.1Skamil
69051.1Skamil	ATF_TP_ADD_TC(tp, resume1);
69061.1Skamil
69071.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
69081.1Skamil
69091.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
69101.1Skamil
69111.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
69121.26Skamil
69131.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
69141.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
69151.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
69161.1Skamil
69171.1Skamil	return atf_no_error();
69181.1Skamil}
6919