t_ptrace_wait.c revision 1.34
11.34Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.34 2018/04/28 00:14:37 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.34Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.34 2018/04/28 00:14:37 kamil Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/types.h>
341.1Skamil#include <sys/ptrace.h>
351.1Skamil#include <sys/resource.h>
361.1Skamil#include <sys/stat.h>
371.1Skamil#include <sys/syscall.h>
381.1Skamil#include <sys/sysctl.h>
391.1Skamil#include <sys/wait.h>
401.1Skamil#include <machine/reg.h>
411.1Skamil#include <elf.h>
421.1Skamil#include <err.h>
431.1Skamil#include <errno.h>
441.1Skamil#include <lwp.h>
451.1Skamil#include <sched.h>
461.1Skamil#include <signal.h>
471.1Skamil#include <stdint.h>
481.1Skamil#include <stdio.h>
491.1Skamil#include <stdlib.h>
501.1Skamil#include <strings.h>
511.26Skamil#include <time.h>
521.1Skamil#include <unistd.h>
531.1Skamil
541.1Skamil#include <atf-c.h>
551.1Skamil
561.1Skamil#include "h_macros.h"
571.1Skamil
581.1Skamil#include "t_ptrace_wait.h"
591.1Skamil#include "msg.h"
601.1Skamil
611.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
621.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
631.1Skamil
641.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
651.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
661.1Skamil
671.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
681.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
691.1Skamil
701.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
711.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
721.13Schristos
731.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
741.13Schristos    strerror(errno))
751.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
761.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
771.13Schristos
781.13Schristosstatic int debug = 0;
791.13Schristos
801.13Schristos#define DPRINTF(a, ...)	do  \
811.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
821.13Schristos    while (/*CONSTCOND*/0)
831.1Skamil
841.34Skamil/// ----------------------------------------------------------------------------
851.34Skamil
861.33Skamilstatic void
871.33Skamiltraceme_raise(int sigval)
881.1Skamil{
891.1Skamil	const int exitval = 5;
901.1Skamil	pid_t child, wpid;
911.1Skamil#if defined(TWAIT_HAVE_STATUS)
921.1Skamil	int status;
931.1Skamil#endif
941.1Skamil
951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
971.1Skamil	if (child == 0) {
981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1001.1Skamil
1011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1031.1Skamil
1041.13Schristos		DPRINTF("Before exiting of the child process\n");
1051.1Skamil		_exit(exitval);
1061.1Skamil	}
1071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1081.1Skamil
1091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1111.1Skamil
1121.1Skamil	validate_status_stopped(status, sigval);
1131.1Skamil
1141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
1151.1Skamil	    "without signal to be sent\n");
1161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1171.1Skamil
1181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1201.1Skamil
1211.1Skamil	validate_status_exited(status, exitval);
1221.1Skamil
1231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1251.1Skamil}
1261.1Skamil
1271.33Skamil#define TRACEME_RAISE(test, sig)						\
1281.33SkamilATF_TC(test);									\
1291.33SkamilATF_TC_HEAD(test, tc)								\
1301.33Skamil{										\
1311.33Skamil	atf_tc_set_md_var(tc, "descr",						\
1321.33Skamil	    "Verify " #sig " followed by _exit(2) in a child");			\
1331.33Skamil}										\
1341.33Skamil										\
1351.33SkamilATF_TC_BODY(test, tc)								\
1361.33Skamil{										\
1371.33Skamil										\
1381.33Skamil	traceme_raise(sig);							\
1391.33Skamil}
1401.33Skamil
1411.33Skamil//TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ // not yet
1421.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
1431.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
1441.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
1451.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
1461.33Skamil
1471.34Skamil/// ----------------------------------------------------------------------------
1481.1Skamil
1491.1Skamilstatic void
1501.34Skamiltraceme_sighandler_catch(int sigsent, void (*sah)(int arg), int *traceme_caught)
1511.1Skamil{
1521.1Skamil	const int exitval = 5;
1531.34Skamil	const int sigval = SIGSTOP;
1541.1Skamil	pid_t child, wpid;
1551.1Skamil	struct sigaction sa;
1561.1Skamil#if defined(TWAIT_HAVE_STATUS)
1571.1Skamil	int status;
1581.1Skamil#endif
1591.1Skamil
1601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1621.1Skamil	if (child == 0) {
1631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1651.1Skamil
1661.34Skamil		sa.sa_handler = sah;
1671.1Skamil		sa.sa_flags = SA_SIGINFO;
1681.1Skamil		sigemptyset(&sa.sa_mask);
1691.1Skamil
1701.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1711.1Skamil
1721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1741.1Skamil
1751.34Skamil		FORKEE_ASSERT_EQ(*traceme_caught, 1);
1761.1Skamil
1771.13Schristos		DPRINTF("Before exiting of the child process\n");
1781.1Skamil		_exit(exitval);
1791.1Skamil	}
1801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1811.1Skamil
1821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1841.1Skamil
1851.1Skamil	validate_status_stopped(status, sigval);
1861.1Skamil
1871.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
1881.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
1891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1901.1Skamil
1911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1931.1Skamil
1941.1Skamil	validate_status_exited(status, exitval);
1951.1Skamil
1961.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1981.1Skamil}
1991.1Skamil
2001.34Skamil#define TRACEME_SIGHANDLER_CATCH(test, sig)					\
2011.34SkamilATF_TC(test);									\
2021.34SkamilATF_TC_HEAD(test, tc)								\
2031.34Skamil{										\
2041.34Skamil	atf_tc_set_md_var(tc, "descr",						\
2051.34Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
2061.34Skamil	    "handled correctly and caught by a signal handler");		\
2071.34Skamil}										\
2081.34Skamil										\
2091.34Skamilstatic int test##_caught = 0;							\
2101.34Skamil										\
2111.34Skamilstatic void									\
2121.34Skamiltest##_sighandler(int arg)							\
2131.34Skamil{										\
2141.34Skamil	FORKEE_ASSERT_EQ(arg, sig);						\
2151.34Skamil										\
2161.34Skamil	++ test##_caught;							\
2171.34Skamil}										\
2181.34Skamil										\
2191.34SkamilATF_TC_BODY(test, tc)								\
2201.34Skamil{										\
2211.34Skamil										\
2221.34Skamil	traceme_sighandler_catch(sig, test##_sighandler, & test##_caught);	\
2231.34Skamil}
2241.34Skamil
2251.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered.
2261.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch1, SIGABRT) /* abort trap */
2271.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch2, SIGHUP)  /* hangup */
2281.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch3, SIGCONT) /* continued? */
2291.34Skamil
2301.34Skamil/// ----------------------------------------------------------------------------
2311.34Skamil
2321.1SkamilATF_TC(traceme3);
2331.1SkamilATF_TC_HEAD(traceme3, tc)
2341.1Skamil{
2351.1Skamil	atf_tc_set_md_var(tc, "descr",
2361.1Skamil	    "Verify SIGSTOP followed by termination by a signal in a child");
2371.1Skamil}
2381.1Skamil
2391.1SkamilATF_TC_BODY(traceme3, tc)
2401.1Skamil{
2411.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
2421.1Skamil	pid_t child, wpid;
2431.1Skamil#if defined(TWAIT_HAVE_STATUS)
2441.1Skamil	int status;
2451.1Skamil#endif
2461.1Skamil
2471.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2481.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2491.1Skamil	if (child == 0) {
2501.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2511.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2521.1Skamil
2531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2551.1Skamil
2561.1Skamil		/* NOTREACHED */
2571.1Skamil		FORKEE_ASSERTX(0 &&
2581.1Skamil		    "Child should be terminated by a signal from its parent");
2591.1Skamil	}
2601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2611.1Skamil
2621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2641.1Skamil
2651.1Skamil	validate_status_stopped(status, sigval);
2661.1Skamil
2671.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2681.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2701.1Skamil
2711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2731.1Skamil
2741.1Skamil	validate_status_signaled(status, sigsent, 0);
2751.1Skamil
2761.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2781.1Skamil}
2791.1Skamil
2801.1Skamil#if defined(TWAIT_HAVE_PID)
2811.1SkamilATF_TC(attach1);
2821.1SkamilATF_TC_HEAD(attach1, tc)
2831.1Skamil{
2841.1Skamil	atf_tc_set_md_var(tc, "descr",
2851.1Skamil	    "Assert that tracer sees process termination before the parent");
2861.1Skamil}
2871.1Skamil
2881.26Skamilstatic void
2891.26Skamilattach1_raw(bool raw)
2901.1Skamil{
2911.1Skamil	struct msg_fds parent_tracee, parent_tracer;
2921.1Skamil	const int exitval_tracee = 5;
2931.1Skamil	const int exitval_tracer = 10;
2941.1Skamil	pid_t tracee, tracer, wpid;
2951.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2961.1Skamil#if defined(TWAIT_HAVE_STATUS)
2971.1Skamil	int status;
2981.1Skamil#endif
2991.1Skamil
3001.13Schristos	DPRINTF("Spawn tracee\n");
3011.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3021.1Skamil	tracee = atf_utils_fork();
3031.1Skamil	if (tracee == 0) {
3041.1Skamil		// Wait for parent to let us exit
3051.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3061.1Skamil		_exit(exitval_tracee);
3071.1Skamil	}
3081.1Skamil
3091.13Schristos	DPRINTF("Spawn debugger\n");
3101.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3111.1Skamil	tracer = atf_utils_fork();
3121.1Skamil	if (tracer == 0) {
3131.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3141.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3151.1Skamil
3161.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3171.1Skamil		FORKEE_REQUIRE_SUCCESS(
3181.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3191.1Skamil
3201.1Skamil		forkee_status_stopped(status, SIGSTOP);
3211.1Skamil
3221.1Skamil		/* Resume tracee with PT_CONTINUE */
3231.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3241.1Skamil
3251.1Skamil		/* Inform parent that tracer has attached to tracee */
3261.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3271.1Skamil
3281.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3291.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3301.1Skamil
3311.1Skamil		/* Wait for tracee and assert that it exited */
3321.1Skamil		FORKEE_REQUIRE_SUCCESS(
3331.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3341.1Skamil
3351.1Skamil		forkee_status_exited(status, exitval_tracee);
3361.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3371.1Skamil
3381.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3391.1Skamil		_exit(exitval_tracer);
3401.1Skamil	}
3411.1Skamil
3421.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3431.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3441.1Skamil
3451.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3461.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3471.1Skamil
3481.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3491.26Skamil	if (raw)
3501.26Skamil		await_zombie_raw(tracee, 0);
3511.26Skamil	else
3521.26Skamil		await_zombie(tracee);
3531.1Skamil
3541.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3551.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3561.1Skamil	    TWAIT_FNAME);
3571.1Skamil	TWAIT_REQUIRE_SUCCESS(
3581.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
3591.1Skamil
3601.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
3611.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
3621.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3631.1Skamil	    TWAIT_FNAME);
3641.1Skamil
3651.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
3661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3671.1Skamil	    tracer);
3681.1Skamil
3691.1Skamil	validate_status_exited(status, exitval_tracer);
3701.1Skamil
3711.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
3721.1Skamil	    TWAIT_FNAME);
3731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
3741.1Skamil	    tracee);
3751.1Skamil
3761.1Skamil	validate_status_exited(status, exitval_tracee);
3771.1Skamil
3781.1Skamil	msg_close(&parent_tracer);
3791.1Skamil	msg_close(&parent_tracee);
3801.1Skamil}
3811.26Skamil
3821.26SkamilATF_TC_BODY(attach1, tc)
3831.26Skamil{
3841.26Skamil
3851.26Skamil	/* Reuse this test with race1 */
3861.26Skamil	attach1_raw(false);
3871.26Skamil}
3881.26Skamil
3891.1Skamil#endif
3901.1Skamil
3911.1Skamil#if defined(TWAIT_HAVE_PID)
3921.1SkamilATF_TC(attach2);
3931.1SkamilATF_TC_HEAD(attach2, tc)
3941.1Skamil{
3951.1Skamil	atf_tc_set_md_var(tc, "descr",
3961.1Skamil	    "Assert that any tracer sees process termination before its "
3971.1Skamil	    "parent");
3981.1Skamil}
3991.1Skamil
4001.1SkamilATF_TC_BODY(attach2, tc)
4011.1Skamil{
4021.1Skamil	struct msg_fds parent_tracer, parent_tracee;
4031.1Skamil	const int exitval_tracee = 5;
4041.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
4051.1Skamil	pid_t tracee, tracer, wpid;
4061.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4071.1Skamil#if defined(TWAIT_HAVE_STATUS)
4081.1Skamil	int status;
4091.1Skamil#endif
4101.1Skamil
4111.13Schristos	DPRINTF("Spawn tracee\n");
4121.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4131.1Skamil	tracee = atf_utils_fork();
4141.1Skamil	if (tracee == 0) {
4151.1Skamil		/* Wait for message from the parent */
4161.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4171.1Skamil		_exit(exitval_tracee);
4181.1Skamil	}
4191.1Skamil
4201.13Schristos	DPRINTF("Spawn debugger\n");
4211.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4221.1Skamil	tracer = atf_utils_fork();
4231.1Skamil	if (tracer == 0) {
4241.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4251.1Skamil		tracer = atf_utils_fork();
4261.1Skamil		if (tracer != 0)
4271.1Skamil			_exit(exitval_tracer1);
4281.1Skamil
4291.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4301.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4311.1Skamil
4321.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4331.1Skamil		FORKEE_REQUIRE_SUCCESS(
4341.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4351.1Skamil
4361.1Skamil		forkee_status_stopped(status, SIGSTOP);
4371.1Skamil
4381.1Skamil		/* Resume tracee with PT_CONTINUE */
4391.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4401.1Skamil
4411.1Skamil		/* Inform parent that tracer has attached to tracee */
4421.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4431.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4441.1Skamil
4451.1Skamil		/* Wait for tracee and assert that it exited */
4461.1Skamil		FORKEE_REQUIRE_SUCCESS(
4471.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4481.1Skamil
4491.1Skamil		forkee_status_exited(status, exitval_tracee);
4501.1Skamil
4511.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4521.1Skamil		_exit(exitval_tracer2);
4531.1Skamil	}
4541.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4551.1Skamil	    "%s()\n", TWAIT_FNAME);
4561.1Skamil	TWAIT_REQUIRE_SUCCESS(
4571.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4581.1Skamil
4591.1Skamil	validate_status_exited(status, exitval_tracer1);
4601.1Skamil
4611.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4621.1Skamil	    TWAIT_FNAME);
4631.1Skamil	TWAIT_REQUIRE_SUCCESS(
4641.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4651.1Skamil
4661.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4671.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
4681.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4691.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
4701.1Skamil
4711.13Schristos	DPRINTF("Detect that tracee is zombie\n");
4721.1Skamil	await_zombie(tracee);
4731.1Skamil
4741.13Schristos	DPRINTF("Assert that there is no status about tracee - "
4751.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4761.1Skamil	TWAIT_REQUIRE_SUCCESS(
4771.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4781.1Skamil
4791.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
4801.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
4811.1Skamil
4821.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4831.1Skamil	    TWAIT_FNAME);
4841.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
4851.1Skamil	    tracee);
4861.1Skamil
4871.1Skamil	validate_status_exited(status, exitval_tracee);
4881.1Skamil
4891.1Skamil	msg_close(&parent_tracer);
4901.1Skamil	msg_close(&parent_tracee);
4911.1Skamil}
4921.1Skamil#endif
4931.1Skamil
4941.1SkamilATF_TC(attach3);
4951.1SkamilATF_TC_HEAD(attach3, tc)
4961.1Skamil{
4971.1Skamil	atf_tc_set_md_var(tc, "descr",
4981.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
4991.1Skamil}
5001.1Skamil
5011.1SkamilATF_TC_BODY(attach3, tc)
5021.1Skamil{
5031.1Skamil	struct msg_fds parent_tracee;
5041.1Skamil	const int exitval_tracee = 5;
5051.1Skamil	pid_t tracee, wpid;
5061.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5071.1Skamil#if defined(TWAIT_HAVE_STATUS)
5081.1Skamil	int status;
5091.1Skamil#endif
5101.1Skamil
5111.13Schristos	DPRINTF("Spawn tracee\n");
5121.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5131.1Skamil	tracee = atf_utils_fork();
5141.1Skamil	if (tracee == 0) {
5151.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5161.13Schristos		DPRINTF("Parent should now attach to tracee\n");
5171.1Skamil
5181.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5191.1Skamil		/* Wait for message from the parent */
5201.1Skamil		_exit(exitval_tracee);
5211.1Skamil	}
5221.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5231.1Skamil
5241.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5261.1Skamil
5271.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5281.1Skamil	    TWAIT_FNAME);
5291.1Skamil	TWAIT_REQUIRE_SUCCESS(
5301.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5311.1Skamil
5321.1Skamil	validate_status_stopped(status, SIGSTOP);
5331.1Skamil
5341.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5361.1Skamil
5371.13Schristos	DPRINTF("Let the tracee exit now\n");
5381.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5391.1Skamil
5401.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5411.1Skamil	TWAIT_REQUIRE_SUCCESS(
5421.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5431.1Skamil
5441.1Skamil	validate_status_exited(status, exitval_tracee);
5451.1Skamil
5461.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5481.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5491.1Skamil
5501.1Skamil	msg_close(&parent_tracee);
5511.1Skamil}
5521.1Skamil
5531.1SkamilATF_TC(attach4);
5541.1SkamilATF_TC_HEAD(attach4, tc)
5551.1Skamil{
5561.1Skamil	atf_tc_set_md_var(tc, "descr",
5571.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
5581.1Skamil}
5591.1Skamil
5601.1SkamilATF_TC_BODY(attach4, tc)
5611.1Skamil{
5621.1Skamil	struct msg_fds parent_tracee;
5631.1Skamil	const int exitval_tracer = 5;
5641.1Skamil	pid_t tracer, wpid;
5651.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5661.1Skamil#if defined(TWAIT_HAVE_STATUS)
5671.1Skamil	int status;
5681.1Skamil#endif
5691.1Skamil
5701.13Schristos	DPRINTF("Spawn tracer\n");
5711.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5721.1Skamil	tracer = atf_utils_fork();
5731.1Skamil	if (tracer == 0) {
5741.1Skamil
5751.1Skamil		/* Wait for message from the parent */
5761.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5771.1Skamil
5781.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
5791.1Skamil		    getppid());
5801.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
5811.1Skamil
5821.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
5831.1Skamil		    TWAIT_FNAME);
5841.1Skamil		FORKEE_REQUIRE_SUCCESS(
5851.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
5861.1Skamil
5871.1Skamil		forkee_status_stopped(status, SIGSTOP);
5881.1Skamil
5891.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
5901.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
5911.1Skamil		    != -1);
5921.1Skamil
5931.1Skamil		/* Tell parent we are ready */
5941.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
5951.1Skamil
5961.1Skamil		_exit(exitval_tracer);
5971.1Skamil	}
5981.1Skamil
5991.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
6001.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6011.13Schristos	DPRINTF("Allow the tracer to exit now\n");
6021.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
6031.1Skamil
6041.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
6051.1Skamil	TWAIT_REQUIRE_SUCCESS(
6061.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6071.1Skamil
6081.1Skamil	validate_status_exited(status, exitval_tracer);
6091.1Skamil
6101.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
6111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6121.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
6131.1Skamil
6141.1Skamil	msg_close(&parent_tracee);
6151.1Skamil}
6161.1Skamil
6171.1Skamil#if defined(TWAIT_HAVE_PID)
6181.1SkamilATF_TC(attach5);
6191.1SkamilATF_TC_HEAD(attach5, tc)
6201.1Skamil{
6211.1Skamil	atf_tc_set_md_var(tc, "descr",
6221.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6231.1Skamil	    "(check getppid(2))");
6241.1Skamil}
6251.1Skamil
6261.1SkamilATF_TC_BODY(attach5, tc)
6271.1Skamil{
6281.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6291.1Skamil	const int exitval_tracee = 5;
6301.1Skamil	const int exitval_tracer = 10;
6311.1Skamil	pid_t parent, tracee, tracer, wpid;
6321.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6331.1Skamil#if defined(TWAIT_HAVE_STATUS)
6341.1Skamil	int status;
6351.1Skamil#endif
6361.1Skamil
6371.13Schristos	DPRINTF("Spawn tracee\n");
6381.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6391.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6401.1Skamil	tracee = atf_utils_fork();
6411.1Skamil	if (tracee == 0) {
6421.1Skamil		parent = getppid();
6431.1Skamil
6441.1Skamil		/* Emit message to the parent */
6451.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6461.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6471.1Skamil
6481.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6491.1Skamil
6501.1Skamil		_exit(exitval_tracee);
6511.1Skamil	}
6521.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6531.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6541.1Skamil
6551.13Schristos	DPRINTF("Spawn debugger\n");
6561.1Skamil	tracer = atf_utils_fork();
6571.1Skamil	if (tracer == 0) {
6581.1Skamil		/* No IPC to communicate with the child */
6591.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6601.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6611.1Skamil
6621.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6631.1Skamil		FORKEE_REQUIRE_SUCCESS(
6641.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6651.1Skamil
6661.1Skamil		forkee_status_stopped(status, SIGSTOP);
6671.1Skamil
6681.1Skamil		/* Resume tracee with PT_CONTINUE */
6691.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6701.1Skamil
6711.1Skamil		/* Inform parent that tracer has attached to tracee */
6721.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
6731.1Skamil
6741.1Skamil		/* Wait for parent to tell use that tracee should have exited */
6751.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
6761.1Skamil
6771.1Skamil		/* Wait for tracee and assert that it exited */
6781.1Skamil		FORKEE_REQUIRE_SUCCESS(
6791.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6801.1Skamil
6811.1Skamil		forkee_status_exited(status, exitval_tracee);
6821.1Skamil
6831.13Schristos		DPRINTF("Before exiting of the tracer process\n");
6841.1Skamil		_exit(exitval_tracer);
6851.1Skamil	}
6861.1Skamil
6871.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
6881.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
6891.1Skamil
6901.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
6911.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
6921.1Skamil
6931.13Schristos	DPRINTF("Detect that tracee is zombie\n");
6941.1Skamil	await_zombie(tracee);
6951.1Skamil
6961.13Schristos	DPRINTF("Assert that there is no status about tracee - "
6971.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
6981.1Skamil	TWAIT_REQUIRE_SUCCESS(
6991.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7001.1Skamil
7011.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7021.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
7031.1Skamil
7041.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7061.1Skamil	    tracer);
7071.1Skamil
7081.1Skamil	validate_status_exited(status, exitval_tracer);
7091.1Skamil
7101.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7111.1Skamil	    TWAIT_FNAME);
7121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7131.1Skamil	    tracee);
7141.1Skamil
7151.1Skamil	validate_status_exited(status, exitval_tracee);
7161.1Skamil
7171.1Skamil	msg_close(&parent_tracer);
7181.1Skamil	msg_close(&parent_tracee);
7191.1Skamil}
7201.1Skamil#endif
7211.1Skamil
7221.1Skamil#if defined(TWAIT_HAVE_PID)
7231.1SkamilATF_TC(attach6);
7241.1SkamilATF_TC_HEAD(attach6, tc)
7251.1Skamil{
7261.1Skamil	atf_tc_set_md_var(tc, "descr",
7271.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7281.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7291.1Skamil}
7301.1Skamil
7311.1SkamilATF_TC_BODY(attach6, tc)
7321.1Skamil{
7331.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7341.1Skamil	const int exitval_tracee = 5;
7351.1Skamil	const int exitval_tracer = 10;
7361.1Skamil	pid_t parent, tracee, tracer, wpid;
7371.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7381.1Skamil#if defined(TWAIT_HAVE_STATUS)
7391.1Skamil	int status;
7401.1Skamil#endif
7411.1Skamil	int name[CTL_MAXNAME];
7421.1Skamil	struct kinfo_proc2 kp;
7431.1Skamil	size_t len = sizeof(kp);
7441.1Skamil	unsigned int namelen;
7451.1Skamil
7461.13Schristos	DPRINTF("Spawn tracee\n");
7471.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7481.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7491.1Skamil	tracee = atf_utils_fork();
7501.1Skamil	if (tracee == 0) {
7511.1Skamil		parent = getppid();
7521.1Skamil
7531.1Skamil		/* Emit message to the parent */
7541.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7551.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7561.1Skamil
7571.1Skamil		namelen = 0;
7581.1Skamil		name[namelen++] = CTL_KERN;
7591.1Skamil		name[namelen++] = KERN_PROC2;
7601.1Skamil		name[namelen++] = KERN_PROC_PID;
7611.1Skamil		name[namelen++] = getpid();
7621.1Skamil		name[namelen++] = len;
7631.1Skamil		name[namelen++] = 1;
7641.1Skamil
7651.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
7661.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
7671.1Skamil
7681.1Skamil		_exit(exitval_tracee);
7691.1Skamil	}
7701.1Skamil
7711.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
7721.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
7731.1Skamil
7741.13Schristos	DPRINTF("Spawn debugger\n");
7751.1Skamil	tracer = atf_utils_fork();
7761.1Skamil	if (tracer == 0) {
7771.1Skamil		/* No IPC to communicate with the child */
7781.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
7791.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7801.1Skamil
7811.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
7821.1Skamil		FORKEE_REQUIRE_SUCCESS(
7831.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7841.1Skamil
7851.1Skamil		forkee_status_stopped(status, SIGSTOP);
7861.1Skamil
7871.1Skamil		/* Resume tracee with PT_CONTINUE */
7881.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7891.1Skamil
7901.1Skamil		/* Inform parent that tracer has attached to tracee */
7911.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
7921.1Skamil
7931.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
7941.1Skamil
7951.1Skamil		/* Wait for tracee and assert that it exited */
7961.1Skamil		FORKEE_REQUIRE_SUCCESS(
7971.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7981.1Skamil
7991.1Skamil		forkee_status_exited(status, exitval_tracee);
8001.1Skamil
8011.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8021.1Skamil		_exit(exitval_tracer);
8031.1Skamil	}
8041.1Skamil
8051.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8061.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8071.1Skamil
8081.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8091.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8101.1Skamil
8111.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8121.1Skamil	await_zombie(tracee);
8131.1Skamil
8141.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8151.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8161.1Skamil	TWAIT_REQUIRE_SUCCESS(
8171.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8181.1Skamil
8191.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8201.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8211.1Skamil
8221.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8231.1Skamil	    TWAIT_FNAME);
8241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8251.1Skamil	    tracer);
8261.1Skamil
8271.1Skamil	validate_status_exited(status, exitval_tracer);
8281.1Skamil
8291.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8301.1Skamil	    TWAIT_FNAME);
8311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8321.1Skamil	    tracee);
8331.1Skamil
8341.1Skamil	validate_status_exited(status, exitval_tracee);
8351.1Skamil
8361.1Skamil	msg_close(&parent_tracee);
8371.1Skamil	msg_close(&parent_tracer);
8381.1Skamil}
8391.1Skamil#endif
8401.1Skamil
8411.1Skamil#if defined(TWAIT_HAVE_PID)
8421.1SkamilATF_TC(attach7);
8431.1SkamilATF_TC_HEAD(attach7, tc)
8441.1Skamil{
8451.1Skamil	atf_tc_set_md_var(tc, "descr",
8461.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8471.1Skamil	    "(check /proc/curproc/status 3rd column)");
8481.1Skamil}
8491.1Skamil
8501.1SkamilATF_TC_BODY(attach7, tc)
8511.1Skamil{
8521.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8531.1Skamil	int rv;
8541.1Skamil	const int exitval_tracee = 5;
8551.1Skamil	const int exitval_tracer = 10;
8561.1Skamil	pid_t parent, tracee, tracer, wpid;
8571.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8581.1Skamil#if defined(TWAIT_HAVE_STATUS)
8591.1Skamil	int status;
8601.1Skamil#endif
8611.1Skamil	FILE *fp;
8621.1Skamil	struct stat st;
8631.1Skamil	const char *fname = "/proc/curproc/status";
8641.1Skamil	char s_executable[MAXPATHLEN];
8651.1Skamil	int s_pid, s_ppid;
8661.1Skamil	/*
8671.1Skamil	 * Format:
8681.1Skamil	 *  EXECUTABLE PID PPID ...
8691.1Skamil	 */
8701.1Skamil
8711.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
8721.1Skamil	if (rv != 0) {
8731.1Skamil		atf_tc_skip("/proc/curproc/status not found");
8741.1Skamil	}
8751.1Skamil
8761.13Schristos	DPRINTF("Spawn tracee\n");
8771.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8781.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8791.1Skamil	tracee = atf_utils_fork();
8801.1Skamil	if (tracee == 0) {
8811.1Skamil		parent = getppid();
8821.1Skamil
8831.1Skamil		// Wait for parent to let us exit
8841.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
8851.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
8861.1Skamil
8871.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
8881.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
8891.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
8901.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
8911.1Skamil
8921.1Skamil		_exit(exitval_tracee);
8931.1Skamil	}
8941.1Skamil
8951.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
8961.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
8971.1Skamil
8981.13Schristos	DPRINTF("Spawn debugger\n");
8991.1Skamil	tracer = atf_utils_fork();
9001.1Skamil	if (tracer == 0) {
9011.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9021.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9031.1Skamil
9041.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9051.1Skamil		FORKEE_REQUIRE_SUCCESS(
9061.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9071.1Skamil
9081.1Skamil		forkee_status_stopped(status, SIGSTOP);
9091.1Skamil
9101.1Skamil		/* Resume tracee with PT_CONTINUE */
9111.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9121.1Skamil
9131.1Skamil		/* Inform parent that tracer has attached to tracee */
9141.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9151.1Skamil
9161.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9171.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9181.1Skamil
9191.1Skamil		/* Wait for tracee and assert that it exited */
9201.1Skamil		FORKEE_REQUIRE_SUCCESS(
9211.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9221.1Skamil
9231.1Skamil		forkee_status_exited(status, exitval_tracee);
9241.1Skamil
9251.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9261.1Skamil		_exit(exitval_tracer);
9271.1Skamil	}
9281.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9291.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9301.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9311.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9321.1Skamil
9331.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9341.1Skamil	await_zombie(tracee);
9351.1Skamil
9361.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9371.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9381.1Skamil	TWAIT_REQUIRE_SUCCESS(
9391.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9401.1Skamil
9411.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9421.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9431.1Skamil
9441.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9451.1Skamil	    TWAIT_FNAME);
9461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9471.1Skamil	    tracer);
9481.1Skamil
9491.1Skamil	validate_status_exited(status, exitval_tracer);
9501.1Skamil
9511.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9521.1Skamil	    TWAIT_FNAME);
9531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9541.1Skamil	    tracee);
9551.1Skamil
9561.1Skamil	validate_status_exited(status, exitval_tracee);
9571.1Skamil
9581.1Skamil	msg_close(&parent_tracee);
9591.1Skamil	msg_close(&parent_tracer);
9601.1Skamil}
9611.1Skamil#endif
9621.1Skamil
9631.1SkamilATF_TC(eventmask1);
9641.1SkamilATF_TC_HEAD(eventmask1, tc)
9651.1Skamil{
9661.1Skamil	atf_tc_set_md_var(tc, "descr",
9671.1Skamil	    "Verify that empty EVENT_MASK is preserved");
9681.1Skamil}
9691.1Skamil
9701.1SkamilATF_TC_BODY(eventmask1, tc)
9711.1Skamil{
9721.1Skamil	const int exitval = 5;
9731.1Skamil	const int sigval = SIGSTOP;
9741.1Skamil	pid_t child, wpid;
9751.1Skamil#if defined(TWAIT_HAVE_STATUS)
9761.1Skamil	int status;
9771.1Skamil#endif
9781.1Skamil	ptrace_event_t set_event, get_event;
9791.1Skamil	const int len = sizeof(ptrace_event_t);
9801.1Skamil
9811.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
9821.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
9831.1Skamil	if (child == 0) {
9841.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
9851.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
9861.1Skamil
9871.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
9881.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
9891.1Skamil
9901.13Schristos		DPRINTF("Before exiting of the child process\n");
9911.1Skamil		_exit(exitval);
9921.1Skamil	}
9931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
9941.1Skamil
9951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
9961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
9971.1Skamil
9981.1Skamil	validate_status_stopped(status, sigval);
9991.1Skamil
10001.1Skamil	set_event.pe_set_event = 0;
10011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10031.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10041.1Skamil
10051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10061.1Skamil	    "without signal to be sent\n");
10071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10081.1Skamil
10091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10111.1Skamil
10121.1Skamil	validate_status_exited(status, exitval);
10131.1Skamil
10141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10161.1Skamil}
10171.1Skamil
10181.1SkamilATF_TC(eventmask2);
10191.1SkamilATF_TC_HEAD(eventmask2, tc)
10201.1Skamil{
10211.1Skamil	atf_tc_set_md_var(tc, "descr",
10221.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10231.1Skamil}
10241.1Skamil
10251.1SkamilATF_TC_BODY(eventmask2, tc)
10261.1Skamil{
10271.1Skamil	const int exitval = 5;
10281.1Skamil	const int sigval = SIGSTOP;
10291.1Skamil	pid_t child, wpid;
10301.1Skamil#if defined(TWAIT_HAVE_STATUS)
10311.1Skamil	int status;
10321.1Skamil#endif
10331.1Skamil	ptrace_event_t set_event, get_event;
10341.1Skamil	const int len = sizeof(ptrace_event_t);
10351.1Skamil
10361.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10371.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10381.1Skamil	if (child == 0) {
10391.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10401.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10411.1Skamil
10421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10441.1Skamil
10451.13Schristos		DPRINTF("Before exiting of the child process\n");
10461.1Skamil		_exit(exitval);
10471.1Skamil	}
10481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10491.1Skamil
10501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10521.1Skamil
10531.1Skamil	validate_status_stopped(status, sigval);
10541.1Skamil
10551.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10581.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10591.1Skamil
10601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10611.1Skamil	    "without signal to be sent\n");
10621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10631.1Skamil
10641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10661.1Skamil
10671.1Skamil	validate_status_exited(status, exitval);
10681.1Skamil
10691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10711.1Skamil}
10721.1Skamil
10731.1SkamilATF_TC(eventmask3);
10741.1SkamilATF_TC_HEAD(eventmask3, tc)
10751.1Skamil{
10761.1Skamil	atf_tc_set_md_var(tc, "descr",
10771.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
10781.1Skamil}
10791.1Skamil
10801.1SkamilATF_TC_BODY(eventmask3, tc)
10811.1Skamil{
10821.1Skamil	const int exitval = 5;
10831.1Skamil	const int sigval = SIGSTOP;
10841.1Skamil	pid_t child, wpid;
10851.1Skamil#if defined(TWAIT_HAVE_STATUS)
10861.1Skamil	int status;
10871.1Skamil#endif
10881.1Skamil	ptrace_event_t set_event, get_event;
10891.1Skamil	const int len = sizeof(ptrace_event_t);
10901.1Skamil
10911.14Schristos	atf_tc_expect_fail("PR kern/51630");
10921.14Schristos
10931.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10941.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10951.1Skamil	if (child == 0) {
10961.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10971.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10981.1Skamil
10991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11011.1Skamil
11021.13Schristos		DPRINTF("Before exiting of the child process\n");
11031.1Skamil		_exit(exitval);
11041.1Skamil	}
11051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11061.1Skamil
11071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11091.1Skamil
11101.1Skamil	validate_status_stopped(status, sigval);
11111.1Skamil
11121.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
11131.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
11141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11151.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11161.1Skamil
11171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11181.1Skamil	    "without signal to be sent\n");
11191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11201.1Skamil
11211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11231.1Skamil
11241.1Skamil	validate_status_exited(status, exitval);
11251.1Skamil
11261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11281.1Skamil}
11291.1Skamil
11301.1SkamilATF_TC(eventmask4);
11311.1SkamilATF_TC_HEAD(eventmask4, tc)
11321.1Skamil{
11331.1Skamil	atf_tc_set_md_var(tc, "descr",
11341.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11351.1Skamil}
11361.1Skamil
11371.1SkamilATF_TC_BODY(eventmask4, tc)
11381.1Skamil{
11391.1Skamil	const int exitval = 5;
11401.1Skamil	const int sigval = SIGSTOP;
11411.1Skamil	pid_t child, wpid;
11421.1Skamil#if defined(TWAIT_HAVE_STATUS)
11431.1Skamil	int status;
11441.1Skamil#endif
11451.1Skamil	ptrace_event_t set_event, get_event;
11461.1Skamil	const int len = sizeof(ptrace_event_t);
11471.1Skamil
11481.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11491.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11501.1Skamil	if (child == 0) {
11511.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11521.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11531.1Skamil
11541.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11551.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11561.1Skamil
11571.13Schristos		DPRINTF("Before exiting of the child process\n");
11581.1Skamil		_exit(exitval);
11591.1Skamil	}
11601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11611.1Skamil
11621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11641.1Skamil
11651.1Skamil	validate_status_stopped(status, sigval);
11661.1Skamil
11671.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
11681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11701.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11711.1Skamil
11721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11731.1Skamil	    "without signal to be sent\n");
11741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11751.1Skamil
11761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11781.1Skamil
11791.1Skamil	validate_status_exited(status, exitval);
11801.1Skamil
11811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11831.1Skamil}
11841.1Skamil
11851.1SkamilATF_TC(eventmask5);
11861.1SkamilATF_TC_HEAD(eventmask5, tc)
11871.1Skamil{
11881.1Skamil	atf_tc_set_md_var(tc, "descr",
11891.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
11901.1Skamil}
11911.1Skamil
11921.1SkamilATF_TC_BODY(eventmask5, tc)
11931.1Skamil{
11941.1Skamil	const int exitval = 5;
11951.1Skamil	const int sigval = SIGSTOP;
11961.1Skamil	pid_t child, wpid;
11971.1Skamil#if defined(TWAIT_HAVE_STATUS)
11981.1Skamil	int status;
11991.1Skamil#endif
12001.1Skamil	ptrace_event_t set_event, get_event;
12011.1Skamil	const int len = sizeof(ptrace_event_t);
12021.1Skamil
12031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12051.1Skamil	if (child == 0) {
12061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12081.1Skamil
12091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12111.1Skamil
12121.13Schristos		DPRINTF("Before exiting of the child process\n");
12131.1Skamil		_exit(exitval);
12141.1Skamil	}
12151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12161.1Skamil
12171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12191.1Skamil
12201.1Skamil	validate_status_stopped(status, sigval);
12211.1Skamil
12221.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12251.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12261.1Skamil
12271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12281.1Skamil	    "without signal to be sent\n");
12291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12301.1Skamil
12311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12331.1Skamil
12341.1Skamil	validate_status_exited(status, exitval);
12351.1Skamil
12361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12381.1Skamil}
12391.1Skamil
12401.1SkamilATF_TC(eventmask6);
12411.1SkamilATF_TC_HEAD(eventmask6, tc)
12421.1Skamil{
12431.1Skamil	atf_tc_set_md_var(tc, "descr",
12441.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12451.1Skamil}
12461.1Skamil
12471.1SkamilATF_TC_BODY(eventmask6, tc)
12481.1Skamil{
12491.1Skamil	const int exitval = 5;
12501.1Skamil	const int sigval = SIGSTOP;
12511.1Skamil	pid_t child, wpid;
12521.1Skamil#if defined(TWAIT_HAVE_STATUS)
12531.1Skamil	int status;
12541.1Skamil#endif
12551.1Skamil	ptrace_event_t set_event, get_event;
12561.1Skamil	const int len = sizeof(ptrace_event_t);
12571.1Skamil
12581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12601.1Skamil	if (child == 0) {
12611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12631.1Skamil
12641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12661.1Skamil
12671.13Schristos		DPRINTF("Before exiting of the child process\n");
12681.1Skamil		_exit(exitval);
12691.1Skamil	}
12701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12711.1Skamil
12721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12741.1Skamil
12751.1Skamil	validate_status_stopped(status, sigval);
12761.1Skamil
12771.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
12781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12801.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12811.1Skamil
12821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12831.1Skamil	    "without signal to be sent\n");
12841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12851.1Skamil
12861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12881.1Skamil
12891.1Skamil	validate_status_exited(status, exitval);
12901.1Skamil
12911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12931.1Skamil}
12941.1Skamil
12951.28Skamilstatic void
12961.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
12971.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
12981.1Skamil{
12991.1Skamil	const int exitval = 5;
13001.1Skamil	const int exitval2 = 15;
13011.1Skamil	const int sigval = SIGSTOP;
13021.31Skamil	pid_t child, child2 = 0, wpid;
13031.1Skamil#if defined(TWAIT_HAVE_STATUS)
13041.1Skamil	int status;
13051.1Skamil#endif
13061.1Skamil	ptrace_state_t state;
13071.1Skamil	const int slen = sizeof(state);
13081.1Skamil	ptrace_event_t event;
13091.1Skamil	const int elen = sizeof(event);
13101.1Skamil
13111.30Skamil	if (trackvfork) {
13121.28Skamil		atf_tc_expect_fail("PR kern/51630");
13131.28Skamil	}
13141.28Skamil
13151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13171.1Skamil	if (child == 0) {
13181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13201.1Skamil
13211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13231.1Skamil
13241.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
13251.1Skamil
13261.1Skamil		if (child2 == 0)
13271.1Skamil			_exit(exitval2);
13281.1Skamil
13291.1Skamil		FORKEE_REQUIRE_SUCCESS
13301.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13311.1Skamil
13321.1Skamil		forkee_status_exited(status, exitval2);
13331.1Skamil
13341.13Schristos		DPRINTF("Before exiting of the child process\n");
13351.1Skamil		_exit(exitval);
13361.1Skamil	}
13371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13381.1Skamil
13391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13411.1Skamil
13421.1Skamil	validate_status_stopped(status, sigval);
13431.1Skamil
13441.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
13451.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
13461.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
13471.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
13481.30Skamil	event.pe_set_event = 0;
13491.30Skamil	if (trackfork)
13501.30Skamil		event.pe_set_event |= PTRACE_FORK;
13511.30Skamil	if (trackvfork)
13521.30Skamil		event.pe_set_event |= PTRACE_VFORK;
13531.30Skamil	if (trackvforkdone)
13541.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
13551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13561.1Skamil
13571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13581.1Skamil	    "without signal to be sent\n");
13591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13601.1Skamil
13611.29Skamil#if defined(TWAIT_HAVE_PID)
13621.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
13631.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
13641.29Skamil		        child);
13651.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
13661.29Skamil		                      child);
13671.1Skamil
13681.29Skamil		validate_status_stopped(status, SIGTRAP);
13691.1Skamil
13701.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
13711.29Skamil		                       slen) != -1);
13721.31Skamil		if (trackfork && fn == fork) {
13731.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
13741.30Skamil			       PTRACE_FORK);
13751.30Skamil		}
13761.31Skamil		if (trackvfork && fn == vfork) {
13771.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
13781.30Skamil			       PTRACE_VFORK);
13791.30Skamil		}
13801.29Skamil
13811.29Skamil		child2 = state.pe_other_pid;
13821.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
13831.29Skamil
13841.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
13851.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
13861.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
13871.29Skamil		    child2);
13881.1Skamil
13891.29Skamil		validate_status_stopped(status, SIGTRAP);
13901.1Skamil
13911.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
13921.29Skamil		                       slen) != -1);
13931.31Skamil		if (trackfork && fn == fork) {
13941.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
13951.30Skamil			       PTRACE_FORK);
13961.30Skamil		}
13971.31Skamil		if (trackvfork && fn == vfork) {
13981.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
13991.30Skamil			       PTRACE_VFORK);
14001.30Skamil		}
14011.30Skamil
14021.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
14031.29Skamil
14041.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
14051.29Skamil		    "and without signal to be sent\n");
14061.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
14071.29Skamil		                != -1);
14081.29Skamil
14091.29Skamil		DPRINTF("Before resuming the child process where it left off "
14101.29Skamil		        "and without signal to be sent\n");
14111.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14121.30Skamil	}
14131.30Skamil#endif
14141.30Skamil
14151.31Skamil	if (trackvforkdone && fn == vfork) {
14161.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
14171.30Skamil		        child);
14181.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
14191.30Skamil		                      child);
14201.30Skamil
14211.30Skamil		validate_status_stopped(status, SIGTRAP);
14221.30Skamil
14231.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
14241.30Skamil		                       slen) != -1);
14251.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
14261.30Skamil
14271.30Skamil		child2 = state.pe_other_pid;
14281.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
14291.30Skamil		        child2);
14301.30Skamil
14311.30Skamil		DPRINTF("Before resuming the child process where it left off "
14321.30Skamil		        "and without signal to be sent\n");
14331.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14341.30Skamil	}
14351.29Skamil
14361.30Skamil#if defined(TWAIT_HAVE_PID)
14371.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
14381.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
14391.29Skamil		        "\n", TWAIT_FNAME);
14401.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14411.29Skamil		    child2);
14421.29Skamil
14431.29Skamil		validate_status_exited(status, exitval2);
14441.29Skamil
14451.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
14461.29Skamil		        "process\n", TWAIT_FNAME);
14471.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
14481.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
14491.29Skamil	}
14501.29Skamil#endif
14511.1Skamil
14521.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14531.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14551.1Skamil
14561.1Skamil	validate_status_stopped(status, SIGCHLD);
14571.1Skamil
14581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14591.1Skamil	    "without signal to be sent\n");
14601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14611.1Skamil
14621.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
14631.1Skamil	    TWAIT_FNAME);
14641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14651.1Skamil
14661.1Skamil	validate_status_exited(status, exitval);
14671.1Skamil
14681.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
14691.1Skamil	    TWAIT_FNAME);
14701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14711.1Skamil}
14721.28Skamil
14731.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
14741.32SkamilATF_TC(name);									\
14751.32SkamilATF_TC_HEAD(name, tc)								\
14761.32Skamil{										\
14771.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
14781.32Skamil}										\
14791.32Skamil										\
14801.32SkamilATF_TC_BODY(name, tc)								\
14811.32Skamil{										\
14821.32Skamil										\
14831.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
14841.32Skamil}
14851.32Skamil
14861.32Skamil#define F false
14871.32Skamil#define T true
14881.32Skamil
14891.32Skamil#define F_IF__0(x)
14901.32Skamil#define F_IF__1(x) x
14911.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
14921.32Skamil#define F_IF_(x,y) F_IF__(x,y)
14931.32Skamil#define F_IF(x,y) F_IF_(x,y)
14941.32Skamil
14951.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
14961.32Skamil        "Verify " #function "(2) called with 0"					\
14971.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
14981.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
14991.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
15001.32Skamil        " in EVENT_MASK."							\
15011.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
15021.32Skamil        F_IF(dparentbit," Detach parent in this test.")
15031.1Skamil
15041.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
15051.31Skamil#if defined(TWAIT_HAVE_PID)
15061.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
15071.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
15081.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
15091.31Skamil#endif
15101.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
15111.31Skamil#if defined(TWAIT_HAVE_PID)
15121.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
15131.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
15141.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
15151.31Skamil#endif
15161.1Skamil
15171.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
15181.31Skamil#if defined(TWAIT_HAVE_PID)
15191.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
15201.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
15211.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
15221.31Skamil#endif
15231.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
15241.31Skamil#if defined(TWAIT_HAVE_PID)
15251.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
15261.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
15271.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
15281.31Skamil#endif
15291.31Skamil
15301.31Skamil
15311.31Skamil
15321.1Skamil
15331.1SkamilATF_TC(io_read_d1);
15341.1SkamilATF_TC_HEAD(io_read_d1, tc)
15351.1Skamil{
15361.1Skamil	atf_tc_set_md_var(tc, "descr",
15371.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
15381.1Skamil}
15391.1Skamil
15401.1SkamilATF_TC_BODY(io_read_d1, tc)
15411.1Skamil{
15421.1Skamil	const int exitval = 5;
15431.1Skamil	const int sigval = SIGSTOP;
15441.1Skamil	pid_t child, wpid;
15451.1Skamil	uint8_t lookup_me = 0;
15461.1Skamil	const uint8_t magic = 0xab;
15471.1Skamil	struct ptrace_io_desc io = {
15481.1Skamil		.piod_op = PIOD_READ_D,
15491.1Skamil		.piod_offs = &lookup_me,
15501.1Skamil		.piod_addr = &lookup_me,
15511.1Skamil		.piod_len = sizeof(lookup_me)
15521.1Skamil	};
15531.1Skamil#if defined(TWAIT_HAVE_STATUS)
15541.1Skamil	int status;
15551.1Skamil#endif
15561.1Skamil
15571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15591.1Skamil	if (child == 0) {
15601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15621.1Skamil
15631.1Skamil		lookup_me = magic;
15641.1Skamil
15651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15671.1Skamil
15681.13Schristos		DPRINTF("Before exiting of the child process\n");
15691.1Skamil		_exit(exitval);
15701.1Skamil	}
15711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15721.1Skamil
15731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15751.1Skamil
15761.1Skamil	validate_status_stopped(status, sigval);
15771.1Skamil
15781.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
15791.1Skamil	    child, getpid());
15801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
15811.1Skamil
15821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
15831.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
15841.1Skamil
15851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15861.1Skamil	    "without signal to be sent\n");
15871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15881.1Skamil
15891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15911.1Skamil
15921.1Skamil	validate_status_exited(status, exitval);
15931.1Skamil
15941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15961.1Skamil}
15971.1Skamil
15981.1SkamilATF_TC(io_read_d2);
15991.1SkamilATF_TC_HEAD(io_read_d2, tc)
16001.1Skamil{
16011.1Skamil	atf_tc_set_md_var(tc, "descr",
16021.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
16031.1Skamil}
16041.1Skamil
16051.1SkamilATF_TC_BODY(io_read_d2, tc)
16061.1Skamil{
16071.1Skamil	const int exitval = 5;
16081.1Skamil	const int sigval = SIGSTOP;
16091.1Skamil	pid_t child, wpid;
16101.1Skamil	uint16_t lookup_me = 0;
16111.1Skamil	const uint16_t magic = 0x1234;
16121.1Skamil	struct ptrace_io_desc io = {
16131.1Skamil		.piod_op = PIOD_READ_D,
16141.1Skamil		.piod_offs = &lookup_me,
16151.1Skamil		.piod_addr = &lookup_me,
16161.1Skamil		.piod_len = sizeof(lookup_me)
16171.1Skamil	};
16181.1Skamil#if defined(TWAIT_HAVE_STATUS)
16191.1Skamil	int status;
16201.1Skamil#endif
16211.1Skamil
16221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16241.1Skamil	if (child == 0) {
16251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16271.1Skamil
16281.1Skamil		lookup_me = magic;
16291.1Skamil
16301.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16311.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16321.1Skamil
16331.13Schristos		DPRINTF("Before exiting of the child process\n");
16341.1Skamil		_exit(exitval);
16351.1Skamil	}
16361.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16371.1Skamil
16381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16401.1Skamil
16411.1Skamil	validate_status_stopped(status, sigval);
16421.1Skamil
16431.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16441.1Skamil	    child, getpid());
16451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16461.1Skamil
16471.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16481.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
16491.1Skamil
16501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16511.1Skamil	    "without signal to be sent\n");
16521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16531.1Skamil
16541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16561.1Skamil
16571.1Skamil	validate_status_exited(status, exitval);
16581.1Skamil
16591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16611.1Skamil}
16621.1Skamil
16631.1SkamilATF_TC(io_read_d3);
16641.1SkamilATF_TC_HEAD(io_read_d3, tc)
16651.1Skamil{
16661.1Skamil	atf_tc_set_md_var(tc, "descr",
16671.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
16681.1Skamil}
16691.1Skamil
16701.1SkamilATF_TC_BODY(io_read_d3, tc)
16711.1Skamil{
16721.1Skamil	const int exitval = 5;
16731.1Skamil	const int sigval = SIGSTOP;
16741.1Skamil	pid_t child, wpid;
16751.1Skamil	uint32_t lookup_me = 0;
16761.1Skamil	const uint32_t magic = 0x1234abcd;
16771.1Skamil	struct ptrace_io_desc io = {
16781.1Skamil		.piod_op = PIOD_READ_D,
16791.1Skamil		.piod_offs = &lookup_me,
16801.1Skamil		.piod_addr = &lookup_me,
16811.1Skamil		.piod_len = sizeof(lookup_me)
16821.1Skamil	};
16831.1Skamil#if defined(TWAIT_HAVE_STATUS)
16841.1Skamil	int status;
16851.1Skamil#endif
16861.1Skamil
16871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16891.1Skamil	if (child == 0) {
16901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16921.1Skamil
16931.1Skamil		lookup_me = magic;
16941.1Skamil
16951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16971.1Skamil
16981.13Schristos		DPRINTF("Before exiting of the child process\n");
16991.1Skamil		_exit(exitval);
17001.1Skamil	}
17011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17021.1Skamil
17031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17051.1Skamil
17061.1Skamil	validate_status_stopped(status, sigval);
17071.1Skamil
17081.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
17091.1Skamil	    child, getpid());
17101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
17111.1Skamil
17121.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
17131.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
17141.1Skamil
17151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17161.1Skamil	    "without signal to be sent\n");
17171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17181.1Skamil
17191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17211.1Skamil
17221.1Skamil	validate_status_exited(status, exitval);
17231.1Skamil
17241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17261.1Skamil}
17271.1Skamil
17281.1SkamilATF_TC(io_read_d4);
17291.1SkamilATF_TC_HEAD(io_read_d4, tc)
17301.1Skamil{
17311.1Skamil	atf_tc_set_md_var(tc, "descr",
17321.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
17331.1Skamil}
17341.1Skamil
17351.1SkamilATF_TC_BODY(io_read_d4, tc)
17361.1Skamil{
17371.1Skamil	const int exitval = 5;
17381.1Skamil	const int sigval = SIGSTOP;
17391.1Skamil	pid_t child, wpid;
17401.1Skamil	uint64_t lookup_me = 0;
17411.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
17421.1Skamil	struct ptrace_io_desc io = {
17431.1Skamil		.piod_op = PIOD_READ_D,
17441.1Skamil		.piod_offs = &lookup_me,
17451.1Skamil		.piod_addr = &lookup_me,
17461.1Skamil		.piod_len = sizeof(lookup_me)
17471.1Skamil	};
17481.1Skamil#if defined(TWAIT_HAVE_STATUS)
17491.1Skamil	int status;
17501.1Skamil#endif
17511.1Skamil
17521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17541.1Skamil	if (child == 0) {
17551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17571.1Skamil
17581.1Skamil		lookup_me = magic;
17591.1Skamil
17601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17621.1Skamil
17631.13Schristos		DPRINTF("Before exiting of the child process\n");
17641.1Skamil		_exit(exitval);
17651.1Skamil	}
17661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17671.1Skamil
17681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17701.1Skamil
17711.1Skamil	validate_status_stopped(status, sigval);
17721.1Skamil
17731.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
17741.1Skamil	    child, getpid());
17751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
17761.1Skamil
17771.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
17781.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
17791.1Skamil
17801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17811.1Skamil	    "without signal to be sent\n");
17821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17831.1Skamil
17841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17861.1Skamil
17871.1Skamil	validate_status_exited(status, exitval);
17881.1Skamil
17891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17911.1Skamil}
17921.1Skamil
17931.1SkamilATF_TC(io_write_d1);
17941.1SkamilATF_TC_HEAD(io_write_d1, tc)
17951.1Skamil{
17961.1Skamil	atf_tc_set_md_var(tc, "descr",
17971.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
17981.1Skamil}
17991.1Skamil
18001.1SkamilATF_TC_BODY(io_write_d1, tc)
18011.1Skamil{
18021.1Skamil	const int exitval = 5;
18031.1Skamil	const int sigval = SIGSTOP;
18041.1Skamil	pid_t child, wpid;
18051.1Skamil	uint8_t lookup_me = 0;
18061.1Skamil	const uint8_t magic = 0xab;
18071.1Skamil	struct ptrace_io_desc io = {
18081.1Skamil		.piod_op = PIOD_WRITE_D,
18091.1Skamil		.piod_offs = &lookup_me,
18101.1Skamil		.piod_addr = &lookup_me,
18111.1Skamil		.piod_len = sizeof(lookup_me)
18121.1Skamil	};
18131.1Skamil#if defined(TWAIT_HAVE_STATUS)
18141.1Skamil	int status;
18151.1Skamil#endif
18161.1Skamil
18171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18191.1Skamil	if (child == 0) {
18201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18221.1Skamil
18231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18251.1Skamil
18261.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
18271.1Skamil
18281.13Schristos		DPRINTF("Before exiting of the child process\n");
18291.1Skamil		_exit(exitval);
18301.1Skamil	}
18311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18321.1Skamil
18331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18351.1Skamil
18361.1Skamil	validate_status_stopped(status, sigval);
18371.1Skamil
18381.1Skamil	lookup_me = magic;
18391.1Skamil
18401.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
18411.1Skamil	    child, getpid());
18421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18431.1Skamil
18441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18451.1Skamil	    "without signal to be sent\n");
18461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18471.1Skamil
18481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18501.1Skamil
18511.1Skamil	validate_status_exited(status, exitval);
18521.1Skamil
18531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18551.1Skamil}
18561.1Skamil
18571.1SkamilATF_TC(io_write_d2);
18581.1SkamilATF_TC_HEAD(io_write_d2, tc)
18591.1Skamil{
18601.1Skamil	atf_tc_set_md_var(tc, "descr",
18611.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
18621.1Skamil}
18631.1Skamil
18641.1SkamilATF_TC_BODY(io_write_d2, tc)
18651.1Skamil{
18661.1Skamil	const int exitval = 5;
18671.1Skamil	const int sigval = SIGSTOP;
18681.1Skamil	pid_t child, wpid;
18691.1Skamil	uint16_t lookup_me = 0;
18701.1Skamil	const uint16_t magic = 0xab12;
18711.1Skamil	struct ptrace_io_desc io = {
18721.1Skamil		.piod_op = PIOD_WRITE_D,
18731.1Skamil		.piod_offs = &lookup_me,
18741.1Skamil		.piod_addr = &lookup_me,
18751.1Skamil		.piod_len = sizeof(lookup_me)
18761.1Skamil	};
18771.1Skamil#if defined(TWAIT_HAVE_STATUS)
18781.1Skamil	int status;
18791.1Skamil#endif
18801.1Skamil
18811.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18821.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18831.1Skamil	if (child == 0) {
18841.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18851.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18861.1Skamil
18871.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18881.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18891.1Skamil
18901.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
18911.1Skamil
18921.13Schristos		DPRINTF("Before exiting of the child process\n");
18931.1Skamil		_exit(exitval);
18941.1Skamil	}
18951.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18961.1Skamil
18971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18991.1Skamil
19001.1Skamil	validate_status_stopped(status, sigval);
19011.1Skamil
19021.1Skamil	lookup_me = magic;
19031.1Skamil
19041.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
19051.1Skamil	    child, getpid());
19061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19071.1Skamil
19081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19091.1Skamil	    "without signal to be sent\n");
19101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19111.1Skamil
19121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19141.1Skamil
19151.1Skamil	validate_status_exited(status, exitval);
19161.1Skamil
19171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19191.1Skamil}
19201.1Skamil
19211.1SkamilATF_TC(io_write_d3);
19221.1SkamilATF_TC_HEAD(io_write_d3, tc)
19231.1Skamil{
19241.1Skamil	atf_tc_set_md_var(tc, "descr",
19251.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
19261.1Skamil}
19271.1Skamil
19281.1SkamilATF_TC_BODY(io_write_d3, tc)
19291.1Skamil{
19301.1Skamil	const int exitval = 5;
19311.1Skamil	const int sigval = SIGSTOP;
19321.1Skamil	pid_t child, wpid;
19331.1Skamil	uint32_t lookup_me = 0;
19341.1Skamil	const uint32_t magic = 0xab127643;
19351.1Skamil	struct ptrace_io_desc io = {
19361.1Skamil		.piod_op = PIOD_WRITE_D,
19371.1Skamil		.piod_offs = &lookup_me,
19381.1Skamil		.piod_addr = &lookup_me,
19391.1Skamil		.piod_len = sizeof(lookup_me)
19401.1Skamil	};
19411.1Skamil#if defined(TWAIT_HAVE_STATUS)
19421.1Skamil	int status;
19431.1Skamil#endif
19441.1Skamil
19451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19471.1Skamil	if (child == 0) {
19481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19501.1Skamil
19511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19531.1Skamil
19541.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19551.1Skamil
19561.13Schristos		DPRINTF("Before exiting of the child process\n");
19571.1Skamil		_exit(exitval);
19581.1Skamil	}
19591.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19601.1Skamil
19611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19631.1Skamil
19641.1Skamil	validate_status_stopped(status, sigval);
19651.1Skamil
19661.1Skamil	lookup_me = magic;
19671.1Skamil
19681.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
19691.1Skamil	    child, getpid());
19701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19711.1Skamil
19721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19731.1Skamil	    "without signal to be sent\n");
19741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19751.1Skamil
19761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19781.1Skamil
19791.1Skamil	validate_status_exited(status, exitval);
19801.1Skamil
19811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19831.1Skamil}
19841.1Skamil
19851.1SkamilATF_TC(io_write_d4);
19861.1SkamilATF_TC_HEAD(io_write_d4, tc)
19871.1Skamil{
19881.1Skamil	atf_tc_set_md_var(tc, "descr",
19891.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
19901.1Skamil}
19911.1Skamil
19921.1SkamilATF_TC_BODY(io_write_d4, tc)
19931.1Skamil{
19941.1Skamil	const int exitval = 5;
19951.1Skamil	const int sigval = SIGSTOP;
19961.1Skamil	pid_t child, wpid;
19971.1Skamil	uint64_t lookup_me = 0;
19981.1Skamil	const uint64_t magic = 0xab12764376490123;
19991.1Skamil	struct ptrace_io_desc io = {
20001.1Skamil		.piod_op = PIOD_WRITE_D,
20011.1Skamil		.piod_offs = &lookup_me,
20021.1Skamil		.piod_addr = &lookup_me,
20031.1Skamil		.piod_len = sizeof(lookup_me)
20041.1Skamil	};
20051.1Skamil#if defined(TWAIT_HAVE_STATUS)
20061.1Skamil	int status;
20071.1Skamil#endif
20081.1Skamil
20091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20111.1Skamil	if (child == 0) {
20121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20141.1Skamil
20151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20171.1Skamil
20181.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
20191.1Skamil
20201.13Schristos		DPRINTF("Before exiting of the child process\n");
20211.1Skamil		_exit(exitval);
20221.1Skamil	}
20231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20241.1Skamil
20251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20271.1Skamil
20281.1Skamil	validate_status_stopped(status, sigval);
20291.1Skamil
20301.1Skamil	lookup_me = magic;
20311.1Skamil
20321.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20331.1Skamil	    child, getpid());
20341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20351.1Skamil
20361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20371.1Skamil	    "without signal to be sent\n");
20381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20391.1Skamil
20401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20421.1Skamil
20431.1Skamil	validate_status_exited(status, exitval);
20441.1Skamil
20451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20471.1Skamil}
20481.1Skamil
20491.1SkamilATF_TC(io_read_auxv1);
20501.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
20511.1Skamil{
20521.1Skamil	atf_tc_set_md_var(tc, "descr",
20531.1Skamil	    "Verify PT_READ_AUXV called for tracee");
20541.1Skamil}
20551.1Skamil
20561.1SkamilATF_TC_BODY(io_read_auxv1, tc)
20571.1Skamil{
20581.1Skamil	const int exitval = 5;
20591.1Skamil	const int sigval = SIGSTOP;
20601.1Skamil	pid_t child, wpid;
20611.1Skamil#if defined(TWAIT_HAVE_STATUS)
20621.1Skamil	int status;
20631.1Skamil#endif
20641.1Skamil	AuxInfo ai[100], *aip;
20651.1Skamil	struct ptrace_io_desc io = {
20661.1Skamil		.piod_op = PIOD_READ_AUXV,
20671.1Skamil		.piod_offs = 0,
20681.1Skamil		.piod_addr = ai,
20691.1Skamil		.piod_len = sizeof(ai)
20701.1Skamil	};
20711.1Skamil
20721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20741.1Skamil	if (child == 0) {
20751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20771.1Skamil
20781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20801.1Skamil
20811.13Schristos		DPRINTF("Before exiting of the child process\n");
20821.1Skamil		_exit(exitval);
20831.1Skamil	}
20841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20851.1Skamil
20861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20881.1Skamil
20891.1Skamil	validate_status_stopped(status, sigval);
20901.1Skamil
20911.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
20921.1Skamil	    child, getpid());
20931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20941.1Skamil
20951.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
20961.1Skamil	ATF_REQUIRE(io.piod_len > 0);
20971.1Skamil
20981.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
20991.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
21001.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
21011.1Skamil
21021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21031.1Skamil	    "without signal to be sent\n");
21041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21051.1Skamil
21061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21081.1Skamil
21091.1Skamil	validate_status_exited(status, exitval);
21101.1Skamil
21111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21131.1Skamil}
21141.1Skamil
21151.1SkamilATF_TC(read_d1);
21161.1SkamilATF_TC_HEAD(read_d1, tc)
21171.1Skamil{
21181.1Skamil	atf_tc_set_md_var(tc, "descr",
21191.1Skamil	    "Verify PT_READ_D called once");
21201.1Skamil}
21211.1Skamil
21221.1SkamilATF_TC_BODY(read_d1, tc)
21231.1Skamil{
21241.1Skamil	const int exitval = 5;
21251.1Skamil	const int sigval = SIGSTOP;
21261.1Skamil	pid_t child, wpid;
21271.1Skamil	int lookup_me = 0;
21281.1Skamil	const int magic = (int)random();
21291.1Skamil#if defined(TWAIT_HAVE_STATUS)
21301.1Skamil	int status;
21311.1Skamil#endif
21321.1Skamil
21331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21351.1Skamil	if (child == 0) {
21361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21381.1Skamil
21391.1Skamil		lookup_me = magic;
21401.1Skamil
21411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21431.1Skamil
21441.13Schristos		DPRINTF("Before exiting of the child process\n");
21451.1Skamil		_exit(exitval);
21461.1Skamil	}
21471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21481.1Skamil
21491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21511.1Skamil
21521.1Skamil	validate_status_stopped(status, sigval);
21531.1Skamil
21541.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21551.1Skamil	    child, getpid());
21561.1Skamil	errno = 0;
21571.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
21581.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
21591.1Skamil
21601.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21611.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
21621.1Skamil
21631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21641.1Skamil	    "without signal to be sent\n");
21651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21661.1Skamil
21671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21691.1Skamil
21701.1Skamil	validate_status_exited(status, exitval);
21711.1Skamil
21721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21741.1Skamil}
21751.1Skamil
21761.1SkamilATF_TC(read_d2);
21771.1SkamilATF_TC_HEAD(read_d2, tc)
21781.1Skamil{
21791.1Skamil	atf_tc_set_md_var(tc, "descr",
21801.1Skamil	    "Verify PT_READ_D called twice");
21811.1Skamil}
21821.1Skamil
21831.1SkamilATF_TC_BODY(read_d2, tc)
21841.1Skamil{
21851.1Skamil	const int exitval = 5;
21861.1Skamil	const int sigval = SIGSTOP;
21871.1Skamil	pid_t child, wpid;
21881.1Skamil	int lookup_me1 = 0;
21891.1Skamil	int lookup_me2 = 0;
21901.1Skamil	const int magic1 = (int)random();
21911.1Skamil	const int magic2 = (int)random();
21921.1Skamil#if defined(TWAIT_HAVE_STATUS)
21931.1Skamil	int status;
21941.1Skamil#endif
21951.1Skamil
21961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21981.1Skamil	if (child == 0) {
21991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22011.1Skamil
22021.1Skamil		lookup_me1 = magic1;
22031.1Skamil		lookup_me2 = magic2;
22041.1Skamil
22051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22071.1Skamil
22081.13Schristos		DPRINTF("Before exiting of the child process\n");
22091.1Skamil		_exit(exitval);
22101.1Skamil	}
22111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22121.1Skamil
22131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22151.1Skamil
22161.1Skamil	validate_status_stopped(status, sigval);
22171.1Skamil
22181.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
22191.1Skamil	    child, getpid());
22201.1Skamil	errno = 0;
22211.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
22221.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22231.1Skamil
22241.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
22251.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
22261.1Skamil
22271.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
22281.1Skamil	    child, getpid());
22291.1Skamil	errno = 0;
22301.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
22311.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22321.1Skamil
22331.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
22341.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
22351.1Skamil
22361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22371.1Skamil	    "without signal to be sent\n");
22381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22391.1Skamil
22401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22421.1Skamil
22431.1Skamil	validate_status_exited(status, exitval);
22441.1Skamil
22451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22471.1Skamil}
22481.1Skamil
22491.1SkamilATF_TC(read_d3);
22501.1SkamilATF_TC_HEAD(read_d3, tc)
22511.1Skamil{
22521.1Skamil	atf_tc_set_md_var(tc, "descr",
22531.1Skamil	    "Verify PT_READ_D called three times");
22541.1Skamil}
22551.1Skamil
22561.1SkamilATF_TC_BODY(read_d3, tc)
22571.1Skamil{
22581.1Skamil	const int exitval = 5;
22591.1Skamil	const int sigval = SIGSTOP;
22601.1Skamil	pid_t child, wpid;
22611.1Skamil	int lookup_me1 = 0;
22621.1Skamil	int lookup_me2 = 0;
22631.1Skamil	int lookup_me3 = 0;
22641.1Skamil	const int magic1 = (int)random();
22651.1Skamil	const int magic2 = (int)random();
22661.1Skamil	const int magic3 = (int)random();
22671.1Skamil#if defined(TWAIT_HAVE_STATUS)
22681.1Skamil	int status;
22691.1Skamil#endif
22701.1Skamil
22711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22731.1Skamil	if (child == 0) {
22741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22761.1Skamil
22771.1Skamil		lookup_me1 = magic1;
22781.1Skamil		lookup_me2 = magic2;
22791.1Skamil		lookup_me3 = magic3;
22801.1Skamil
22811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22831.1Skamil
22841.13Schristos		DPRINTF("Before exiting of the child process\n");
22851.1Skamil		_exit(exitval);
22861.1Skamil	}
22871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22881.1Skamil
22891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22911.1Skamil
22921.1Skamil	validate_status_stopped(status, sigval);
22931.1Skamil
22941.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
22951.1Skamil	    child, getpid());
22961.1Skamil	errno = 0;
22971.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
22981.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22991.1Skamil
23001.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
23011.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
23021.1Skamil
23031.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
23041.1Skamil	    child, getpid());
23051.1Skamil	errno = 0;
23061.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
23071.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23081.1Skamil
23091.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
23101.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
23111.1Skamil
23121.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
23131.1Skamil	    child, getpid());
23141.1Skamil	errno = 0;
23151.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
23161.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23171.1Skamil
23181.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
23191.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
23201.1Skamil
23211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23221.1Skamil	    "without signal to be sent\n");
23231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23241.1Skamil
23251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23271.1Skamil
23281.1Skamil	validate_status_exited(status, exitval);
23291.1Skamil
23301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23321.1Skamil}
23331.1Skamil
23341.1SkamilATF_TC(read_d4);
23351.1SkamilATF_TC_HEAD(read_d4, tc)
23361.1Skamil{
23371.1Skamil	atf_tc_set_md_var(tc, "descr",
23381.1Skamil	    "Verify PT_READ_D called four times");
23391.1Skamil}
23401.1Skamil
23411.1SkamilATF_TC_BODY(read_d4, tc)
23421.1Skamil{
23431.1Skamil	const int exitval = 5;
23441.1Skamil	const int sigval = SIGSTOP;
23451.1Skamil	pid_t child, wpid;
23461.1Skamil	int lookup_me1 = 0;
23471.1Skamil	int lookup_me2 = 0;
23481.1Skamil	int lookup_me3 = 0;
23491.1Skamil	int lookup_me4 = 0;
23501.1Skamil	const int magic1 = (int)random();
23511.1Skamil	const int magic2 = (int)random();
23521.1Skamil	const int magic3 = (int)random();
23531.1Skamil	const int magic4 = (int)random();
23541.1Skamil#if defined(TWAIT_HAVE_STATUS)
23551.1Skamil	int status;
23561.1Skamil#endif
23571.1Skamil
23581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23601.1Skamil	if (child == 0) {
23611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23631.1Skamil
23641.1Skamil		lookup_me1 = magic1;
23651.1Skamil		lookup_me2 = magic2;
23661.1Skamil		lookup_me3 = magic3;
23671.1Skamil		lookup_me4 = magic4;
23681.1Skamil
23691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23711.1Skamil
23721.13Schristos		DPRINTF("Before exiting of the child process\n");
23731.1Skamil		_exit(exitval);
23741.1Skamil	}
23751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23761.1Skamil
23771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23791.1Skamil
23801.1Skamil	validate_status_stopped(status, sigval);
23811.1Skamil
23821.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
23831.1Skamil	    child, getpid());
23841.1Skamil	errno = 0;
23851.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
23861.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23871.1Skamil
23881.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
23891.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
23901.1Skamil
23911.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
23921.1Skamil	    child, getpid());
23931.1Skamil	errno = 0;
23941.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
23951.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23961.1Skamil
23971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
23981.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
23991.1Skamil
24001.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
24011.1Skamil	    child, getpid());
24021.1Skamil	errno = 0;
24031.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
24041.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24051.1Skamil
24061.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
24071.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
24081.1Skamil
24091.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
24101.1Skamil	    child, getpid());
24111.1Skamil	errno = 0;
24121.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
24131.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24141.1Skamil
24151.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
24161.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
24171.1Skamil
24181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24191.1Skamil	    "without signal to be sent\n");
24201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24211.1Skamil
24221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24241.1Skamil
24251.1Skamil	validate_status_exited(status, exitval);
24261.1Skamil
24271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24281.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24291.1Skamil}
24301.1Skamil
24311.1SkamilATF_TC(write_d1);
24321.1SkamilATF_TC_HEAD(write_d1, tc)
24331.1Skamil{
24341.1Skamil	atf_tc_set_md_var(tc, "descr",
24351.1Skamil	    "Verify PT_WRITE_D called once");
24361.1Skamil}
24371.1Skamil
24381.1SkamilATF_TC_BODY(write_d1, tc)
24391.1Skamil{
24401.1Skamil	const int exitval = 5;
24411.1Skamil	const int sigval = SIGSTOP;
24421.1Skamil	pid_t child, wpid;
24431.1Skamil	int lookup_me = 0;
24441.1Skamil	const int magic = (int)random();
24451.1Skamil#if defined(TWAIT_HAVE_STATUS)
24461.1Skamil	int status;
24471.1Skamil#endif
24481.1Skamil
24491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24511.1Skamil	if (child == 0) {
24521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24541.1Skamil
24551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24571.1Skamil
24581.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
24591.1Skamil
24601.13Schristos		DPRINTF("Before exiting of the child process\n");
24611.1Skamil		_exit(exitval);
24621.1Skamil	}
24631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24641.1Skamil
24651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24671.1Skamil
24681.1Skamil	validate_status_stopped(status, sigval);
24691.1Skamil
24701.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24711.1Skamil	    child, getpid());
24721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
24731.1Skamil
24741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24751.1Skamil	    "without signal to be sent\n");
24761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24771.1Skamil
24781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24801.1Skamil
24811.1Skamil	validate_status_exited(status, exitval);
24821.1Skamil
24831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24841.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24851.1Skamil}
24861.1Skamil
24871.1SkamilATF_TC(write_d2);
24881.1SkamilATF_TC_HEAD(write_d2, tc)
24891.1Skamil{
24901.1Skamil	atf_tc_set_md_var(tc, "descr",
24911.1Skamil	    "Verify PT_WRITE_D called twice");
24921.1Skamil}
24931.1Skamil
24941.1SkamilATF_TC_BODY(write_d2, tc)
24951.1Skamil{
24961.1Skamil	const int exitval = 5;
24971.1Skamil	const int sigval = SIGSTOP;
24981.1Skamil	pid_t child, wpid;
24991.1Skamil	int lookup_me1 = 0;
25001.1Skamil	int lookup_me2 = 0;
25011.1Skamil	const int magic1 = (int)random();
25021.1Skamil	const int magic2 = (int)random();
25031.1Skamil#if defined(TWAIT_HAVE_STATUS)
25041.1Skamil	int status;
25051.1Skamil#endif
25061.1Skamil
25071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25091.1Skamil	if (child == 0) {
25101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25121.1Skamil
25131.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25141.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25151.1Skamil
25161.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
25171.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
25181.1Skamil
25191.13Schristos		DPRINTF("Before exiting of the child process\n");
25201.1Skamil		_exit(exitval);
25211.1Skamil	}
25221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25231.1Skamil
25241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25261.1Skamil
25271.1Skamil	validate_status_stopped(status, sigval);
25281.1Skamil
25291.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
25301.1Skamil	    child, getpid());
25311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
25321.1Skamil
25331.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
25341.1Skamil	    child, getpid());
25351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
25361.1Skamil
25371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25381.1Skamil	    "without signal to be sent\n");
25391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25401.1Skamil
25411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25431.1Skamil
25441.1Skamil	validate_status_exited(status, exitval);
25451.1Skamil
25461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25481.1Skamil}
25491.1Skamil
25501.1SkamilATF_TC(write_d3);
25511.1SkamilATF_TC_HEAD(write_d3, tc)
25521.1Skamil{
25531.1Skamil	atf_tc_set_md_var(tc, "descr",
25541.1Skamil	    "Verify PT_WRITE_D called three times");
25551.1Skamil}
25561.1Skamil
25571.1SkamilATF_TC_BODY(write_d3, tc)
25581.1Skamil{
25591.1Skamil	const int exitval = 5;
25601.1Skamil	const int sigval = SIGSTOP;
25611.1Skamil	pid_t child, wpid;
25621.1Skamil	int lookup_me1 = 0;
25631.1Skamil	int lookup_me2 = 0;
25641.1Skamil	int lookup_me3 = 0;
25651.1Skamil	const int magic1 = (int)random();
25661.1Skamil	const int magic2 = (int)random();
25671.1Skamil	const int magic3 = (int)random();
25681.1Skamil#if defined(TWAIT_HAVE_STATUS)
25691.1Skamil	int status;
25701.1Skamil#endif
25711.1Skamil
25721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25741.1Skamil	if (child == 0) {
25751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25771.1Skamil
25781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25801.1Skamil
25811.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
25821.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
25831.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
25841.1Skamil
25851.13Schristos		DPRINTF("Before exiting of the child process\n");
25861.1Skamil		_exit(exitval);
25871.1Skamil	}
25881.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25891.1Skamil
25901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25921.1Skamil
25931.1Skamil	validate_status_stopped(status, sigval);
25941.1Skamil
25951.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
25961.1Skamil	    child, getpid());
25971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
25981.1Skamil
25991.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
26001.1Skamil	    child, getpid());
26011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
26021.1Skamil
26031.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
26041.1Skamil	    child, getpid());
26051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
26061.1Skamil
26071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26081.1Skamil	    "without signal to be sent\n");
26091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26101.1Skamil
26111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26131.1Skamil
26141.1Skamil	validate_status_exited(status, exitval);
26151.1Skamil
26161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26181.1Skamil}
26191.1Skamil
26201.1SkamilATF_TC(write_d4);
26211.1SkamilATF_TC_HEAD(write_d4, tc)
26221.1Skamil{
26231.1Skamil	atf_tc_set_md_var(tc, "descr",
26241.1Skamil	    "Verify PT_WRITE_D called four times");
26251.1Skamil}
26261.1Skamil
26271.1SkamilATF_TC_BODY(write_d4, tc)
26281.1Skamil{
26291.1Skamil	const int exitval = 5;
26301.1Skamil	const int sigval = SIGSTOP;
26311.1Skamil	pid_t child, wpid;
26321.1Skamil	int lookup_me1 = 0;
26331.1Skamil	int lookup_me2 = 0;
26341.1Skamil	int lookup_me3 = 0;
26351.1Skamil	int lookup_me4 = 0;
26361.1Skamil	const int magic1 = (int)random();
26371.1Skamil	const int magic2 = (int)random();
26381.1Skamil	const int magic3 = (int)random();
26391.1Skamil	const int magic4 = (int)random();
26401.1Skamil#if defined(TWAIT_HAVE_STATUS)
26411.1Skamil	int status;
26421.1Skamil#endif
26431.1Skamil
26441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26461.1Skamil	if (child == 0) {
26471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26491.1Skamil
26501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26521.1Skamil
26531.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26541.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26551.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
26561.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
26571.1Skamil
26581.13Schristos		DPRINTF("Before exiting of the child process\n");
26591.1Skamil		_exit(exitval);
26601.1Skamil	}
26611.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26621.1Skamil
26631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26651.1Skamil
26661.1Skamil	validate_status_stopped(status, sigval);
26671.1Skamil
26681.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
26691.1Skamil	    child, getpid());
26701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
26711.1Skamil
26721.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
26731.1Skamil	    child, getpid());
26741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
26751.1Skamil
26761.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
26771.1Skamil	    child, getpid());
26781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
26791.1Skamil
26801.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
26811.1Skamil	    child, getpid());
26821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
26831.1Skamil
26841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26851.1Skamil	    "without signal to be sent\n");
26861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26871.1Skamil
26881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26901.1Skamil
26911.1Skamil	validate_status_exited(status, exitval);
26921.1Skamil
26931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26941.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26951.1Skamil}
26961.1Skamil
26971.1SkamilATF_TC(io_read_d_write_d_handshake1);
26981.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
26991.1Skamil{
27001.1Skamil	atf_tc_set_md_var(tc, "descr",
27011.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
27021.1Skamil}
27031.1Skamil
27041.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
27051.1Skamil{
27061.1Skamil	const int exitval = 5;
27071.1Skamil	const int sigval = SIGSTOP;
27081.1Skamil	pid_t child, wpid;
27091.1Skamil	uint8_t lookup_me_fromtracee = 0;
27101.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
27111.1Skamil	uint8_t lookup_me_totracee = 0;
27121.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
27131.1Skamil	struct ptrace_io_desc io_fromtracee = {
27141.1Skamil		.piod_op = PIOD_READ_D,
27151.1Skamil		.piod_offs = &lookup_me_fromtracee,
27161.1Skamil		.piod_addr = &lookup_me_fromtracee,
27171.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
27181.1Skamil	};
27191.1Skamil	struct ptrace_io_desc io_totracee = {
27201.1Skamil		.piod_op = PIOD_WRITE_D,
27211.1Skamil		.piod_offs = &lookup_me_totracee,
27221.1Skamil		.piod_addr = &lookup_me_totracee,
27231.1Skamil		.piod_len = sizeof(lookup_me_totracee)
27241.1Skamil	};
27251.1Skamil#if defined(TWAIT_HAVE_STATUS)
27261.1Skamil	int status;
27271.1Skamil#endif
27281.1Skamil
27291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27311.1Skamil	if (child == 0) {
27321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27341.1Skamil
27351.1Skamil		lookup_me_fromtracee = magic_fromtracee;
27361.1Skamil
27371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27391.1Skamil
27401.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
27411.1Skamil
27421.13Schristos		DPRINTF("Before exiting of the child process\n");
27431.1Skamil		_exit(exitval);
27441.1Skamil	}
27451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27461.1Skamil
27471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27491.1Skamil
27501.1Skamil	validate_status_stopped(status, sigval);
27511.1Skamil
27521.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
27531.1Skamil	    child, getpid());
27541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
27551.1Skamil
27561.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
27571.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
27581.1Skamil	    magic_fromtracee);
27591.1Skamil
27601.1Skamil	lookup_me_totracee = magic_totracee;
27611.1Skamil
27621.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
27631.1Skamil	    child, getpid());
27641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
27651.1Skamil
27661.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
27671.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
27681.1Skamil	    magic_totracee);
27691.1Skamil
27701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27711.1Skamil	    "without signal to be sent\n");
27721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27731.1Skamil
27741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27761.1Skamil
27771.1Skamil	validate_status_exited(status, exitval);
27781.1Skamil
27791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27811.1Skamil}
27821.1Skamil
27831.1SkamilATF_TC(io_read_d_write_d_handshake2);
27841.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
27851.1Skamil{
27861.1Skamil	atf_tc_set_md_var(tc, "descr",
27871.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
27881.1Skamil}
27891.1Skamil
27901.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
27911.1Skamil{
27921.1Skamil	const int exitval = 5;
27931.1Skamil	const int sigval = SIGSTOP;
27941.1Skamil	pid_t child, wpid;
27951.1Skamil	uint8_t lookup_me_fromtracee = 0;
27961.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
27971.1Skamil	uint8_t lookup_me_totracee = 0;
27981.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
27991.1Skamil	struct ptrace_io_desc io_fromtracee = {
28001.1Skamil		.piod_op = PIOD_READ_D,
28011.1Skamil		.piod_offs = &lookup_me_fromtracee,
28021.1Skamil		.piod_addr = &lookup_me_fromtracee,
28031.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
28041.1Skamil	};
28051.1Skamil	struct ptrace_io_desc io_totracee = {
28061.1Skamil		.piod_op = PIOD_WRITE_D,
28071.1Skamil		.piod_offs = &lookup_me_totracee,
28081.1Skamil		.piod_addr = &lookup_me_totracee,
28091.1Skamil		.piod_len = sizeof(lookup_me_totracee)
28101.1Skamil	};
28111.1Skamil#if defined(TWAIT_HAVE_STATUS)
28121.1Skamil	int status;
28131.1Skamil#endif
28141.1Skamil
28151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28171.1Skamil	if (child == 0) {
28181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28201.1Skamil
28211.1Skamil		lookup_me_fromtracee = magic_fromtracee;
28221.1Skamil
28231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28251.1Skamil
28261.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
28271.1Skamil
28281.13Schristos		DPRINTF("Before exiting of the child process\n");
28291.1Skamil		_exit(exitval);
28301.1Skamil	}
28311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28321.1Skamil
28331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28351.1Skamil
28361.1Skamil	validate_status_stopped(status, sigval);
28371.1Skamil
28381.1Skamil	lookup_me_totracee = magic_totracee;
28391.1Skamil
28401.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
28411.1Skamil	    child, getpid());
28421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
28431.1Skamil
28441.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
28451.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
28461.1Skamil	    magic_totracee);
28471.1Skamil
28481.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
28491.1Skamil	    child, getpid());
28501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
28511.1Skamil
28521.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
28531.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
28541.1Skamil	    magic_fromtracee);
28551.1Skamil
28561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28571.1Skamil	    "without signal to be sent\n");
28581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28591.1Skamil
28601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28621.1Skamil
28631.1Skamil	validate_status_exited(status, exitval);
28641.1Skamil
28651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28671.1Skamil}
28681.1Skamil
28691.1SkamilATF_TC(read_d_write_d_handshake1);
28701.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
28711.1Skamil{
28721.1Skamil	atf_tc_set_md_var(tc, "descr",
28731.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
28741.1Skamil}
28751.1Skamil
28761.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
28771.1Skamil{
28781.1Skamil	const int exitval = 5;
28791.1Skamil	const int sigval = SIGSTOP;
28801.1Skamil	pid_t child, wpid;
28811.1Skamil	int lookup_me_fromtracee = 0;
28821.1Skamil	const int magic_fromtracee = (int)random();
28831.1Skamil	int lookup_me_totracee = 0;
28841.1Skamil	const int magic_totracee = (int)random();
28851.1Skamil#if defined(TWAIT_HAVE_STATUS)
28861.1Skamil	int status;
28871.1Skamil#endif
28881.1Skamil
28891.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28901.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28911.1Skamil	if (child == 0) {
28921.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28931.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28941.1Skamil
28951.1Skamil		lookup_me_fromtracee = magic_fromtracee;
28961.1Skamil
28971.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28981.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28991.1Skamil
29001.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
29011.1Skamil
29021.13Schristos		DPRINTF("Before exiting of the child process\n");
29031.1Skamil		_exit(exitval);
29041.1Skamil	}
29051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29061.1Skamil
29071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29091.1Skamil
29101.1Skamil	validate_status_stopped(status, sigval);
29111.1Skamil
29121.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
29131.1Skamil	    child, getpid());
29141.1Skamil	errno = 0;
29151.1Skamil	lookup_me_fromtracee =
29161.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
29171.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
29181.1Skamil
29191.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29201.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
29211.1Skamil	    magic_fromtracee);
29221.1Skamil
29231.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
29241.1Skamil	    child, getpid());
29251.1Skamil	ATF_REQUIRE
29261.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
29271.1Skamil	    != -1);
29281.1Skamil
29291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29301.1Skamil	    "without signal to be sent\n");
29311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29321.1Skamil
29331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29351.1Skamil
29361.1Skamil	validate_status_exited(status, exitval);
29371.1Skamil
29381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29401.1Skamil}
29411.1Skamil
29421.1SkamilATF_TC(read_d_write_d_handshake2);
29431.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
29441.1Skamil{
29451.1Skamil	atf_tc_set_md_var(tc, "descr",
29461.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
29471.1Skamil}
29481.1Skamil
29491.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
29501.1Skamil{
29511.1Skamil	const int exitval = 5;
29521.1Skamil	const int sigval = SIGSTOP;
29531.1Skamil	pid_t child, wpid;
29541.1Skamil	int lookup_me_fromtracee = 0;
29551.1Skamil	const int magic_fromtracee = (int)random();
29561.1Skamil	int lookup_me_totracee = 0;
29571.1Skamil	const int magic_totracee = (int)random();
29581.1Skamil#if defined(TWAIT_HAVE_STATUS)
29591.1Skamil	int status;
29601.1Skamil#endif
29611.1Skamil
29621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29641.1Skamil	if (child == 0) {
29651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29671.1Skamil
29681.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29691.1Skamil
29701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29721.1Skamil
29731.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
29741.1Skamil
29751.13Schristos		DPRINTF("Before exiting of the child process\n");
29761.1Skamil		_exit(exitval);
29771.1Skamil	}
29781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29791.1Skamil
29801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29821.1Skamil
29831.1Skamil	validate_status_stopped(status, sigval);
29841.1Skamil
29851.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
29861.1Skamil	    child, getpid());
29871.1Skamil	ATF_REQUIRE
29881.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
29891.1Skamil	    != -1);
29901.1Skamil
29911.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
29921.1Skamil	    child, getpid());
29931.1Skamil	errno = 0;
29941.1Skamil	lookup_me_fromtracee =
29951.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
29961.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
29971.1Skamil
29981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29991.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
30001.1Skamil	    magic_fromtracee);
30011.1Skamil
30021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30031.1Skamil	    "without signal to be sent\n");
30041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30051.1Skamil
30061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30081.1Skamil
30091.1Skamil	validate_status_exited(status, exitval);
30101.1Skamil
30111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30131.1Skamil}
30141.1Skamil
30151.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
30161.1Skamilstatic int __used
30171.1Skamildummy_fn1(int a, int b, int c, int d)
30181.1Skamil{
30191.1Skamil
30201.1Skamil	a *= 1;
30211.1Skamil	b += 2;
30221.1Skamil	c -= 3;
30231.1Skamil	d /= 4;
30241.1Skamil
30251.1Skamil	return a + b * c - d;
30261.1Skamil}
30271.1Skamil
30281.1Skamilstatic int __used
30291.1Skamildummy_fn2(int a, int b, int c, int d)
30301.1Skamil{
30311.1Skamil
30321.1Skamil	a *= 4;
30331.1Skamil	b += 3;
30341.1Skamil	c -= 2;
30351.1Skamil	d /= 1;
30361.1Skamil
30371.1Skamil	return a + b * c - d;
30381.1Skamil}
30391.1Skamil
30401.1Skamilstatic int __used
30411.1Skamildummy_fn3(int a, int b, int c, int d)
30421.1Skamil{
30431.1Skamil
30441.1Skamil	a *= 10;
30451.1Skamil	b += 20;
30461.1Skamil	c -= 30;
30471.1Skamil	d /= 40;
30481.1Skamil
30491.1Skamil	return a + b * c - d;
30501.1Skamil}
30511.1Skamil
30521.1Skamilstatic int __used
30531.1Skamildummy_fn4(int a, int b, int c, int d)
30541.1Skamil{
30551.1Skamil
30561.1Skamil	a *= 40;
30571.1Skamil	b += 30;
30581.1Skamil	c -= 20;
30591.1Skamil	d /= 10;
30601.1Skamil
30611.1Skamil	return a + b * c - d;
30621.1Skamil}
30631.1Skamil
30641.1SkamilATF_TC(io_read_i1);
30651.1SkamilATF_TC_HEAD(io_read_i1, tc)
30661.1Skamil{
30671.1Skamil	atf_tc_set_md_var(tc, "descr",
30681.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
30691.1Skamil}
30701.1Skamil
30711.1SkamilATF_TC_BODY(io_read_i1, tc)
30721.1Skamil{
30731.1Skamil	const int exitval = 5;
30741.1Skamil	const int sigval = SIGSTOP;
30751.1Skamil	pid_t child, wpid;
30761.1Skamil	uint8_t lookup_me = 0;
30771.1Skamil	uint8_t magic;
30781.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
30791.1Skamil	struct ptrace_io_desc io = {
30801.1Skamil		.piod_op = PIOD_READ_I,
30811.1Skamil		.piod_offs = dummy_fn1,
30821.1Skamil		.piod_addr = &lookup_me,
30831.1Skamil		.piod_len = sizeof(lookup_me)
30841.1Skamil	};
30851.1Skamil#if defined(TWAIT_HAVE_STATUS)
30861.1Skamil	int status;
30871.1Skamil#endif
30881.1Skamil
30891.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30901.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30911.1Skamil	if (child == 0) {
30921.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30931.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30941.1Skamil
30951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30971.1Skamil
30981.13Schristos		DPRINTF("Before exiting of the child process\n");
30991.1Skamil		_exit(exitval);
31001.1Skamil	}
31011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31021.1Skamil
31031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31051.1Skamil
31061.1Skamil	validate_status_stopped(status, sigval);
31071.1Skamil
31081.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
31091.1Skamil	    child, getpid());
31101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
31111.1Skamil
31121.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
31131.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
31141.1Skamil
31151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31161.1Skamil	    "without signal to be sent\n");
31171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31181.1Skamil
31191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31211.1Skamil
31221.1Skamil	validate_status_exited(status, exitval);
31231.1Skamil
31241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31261.1Skamil}
31271.1Skamil
31281.1SkamilATF_TC(io_read_i2);
31291.1SkamilATF_TC_HEAD(io_read_i2, tc)
31301.1Skamil{
31311.1Skamil	atf_tc_set_md_var(tc, "descr",
31321.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
31331.1Skamil}
31341.1Skamil
31351.1SkamilATF_TC_BODY(io_read_i2, tc)
31361.1Skamil{
31371.1Skamil	const int exitval = 5;
31381.1Skamil	const int sigval = SIGSTOP;
31391.1Skamil	pid_t child, wpid;
31401.1Skamil	uint16_t lookup_me = 0;
31411.1Skamil	uint16_t magic;
31421.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31431.1Skamil	struct ptrace_io_desc io = {
31441.1Skamil		.piod_op = PIOD_READ_I,
31451.1Skamil		.piod_offs = dummy_fn1,
31461.1Skamil		.piod_addr = &lookup_me,
31471.1Skamil		.piod_len = sizeof(lookup_me)
31481.1Skamil	};
31491.1Skamil#if defined(TWAIT_HAVE_STATUS)
31501.1Skamil	int status;
31511.1Skamil#endif
31521.1Skamil
31531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31551.1Skamil	if (child == 0) {
31561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31581.1Skamil
31591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31611.1Skamil
31621.13Schristos		DPRINTF("Before exiting of the child process\n");
31631.1Skamil		_exit(exitval);
31641.1Skamil	}
31651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31661.1Skamil
31671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31691.1Skamil
31701.1Skamil	validate_status_stopped(status, sigval);
31711.1Skamil
31721.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
31731.1Skamil	    child, getpid());
31741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
31751.1Skamil
31761.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
31771.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
31781.1Skamil
31791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31801.1Skamil	    "without signal to be sent\n");
31811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31821.1Skamil
31831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31851.1Skamil
31861.1Skamil	validate_status_exited(status, exitval);
31871.1Skamil
31881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31891.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31901.1Skamil}
31911.1Skamil
31921.1SkamilATF_TC(io_read_i3);
31931.1SkamilATF_TC_HEAD(io_read_i3, tc)
31941.1Skamil{
31951.1Skamil	atf_tc_set_md_var(tc, "descr",
31961.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
31971.1Skamil}
31981.1Skamil
31991.1SkamilATF_TC_BODY(io_read_i3, tc)
32001.1Skamil{
32011.1Skamil	const int exitval = 5;
32021.1Skamil	const int sigval = SIGSTOP;
32031.1Skamil	pid_t child, wpid;
32041.1Skamil	uint32_t lookup_me = 0;
32051.1Skamil	uint32_t magic;
32061.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
32071.1Skamil	struct ptrace_io_desc io = {
32081.1Skamil		.piod_op = PIOD_READ_I,
32091.1Skamil		.piod_offs = dummy_fn1,
32101.1Skamil		.piod_addr = &lookup_me,
32111.1Skamil		.piod_len = sizeof(lookup_me)
32121.1Skamil	};
32131.1Skamil#if defined(TWAIT_HAVE_STATUS)
32141.1Skamil	int status;
32151.1Skamil#endif
32161.1Skamil
32171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32191.1Skamil	if (child == 0) {
32201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32221.1Skamil
32231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32251.1Skamil
32261.13Schristos		DPRINTF("Before exiting of the child process\n");
32271.1Skamil		_exit(exitval);
32281.1Skamil	}
32291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32301.1Skamil
32311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32331.1Skamil
32341.1Skamil	validate_status_stopped(status, sigval);
32351.1Skamil
32361.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32371.1Skamil	    child, getpid());
32381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32391.1Skamil
32401.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32411.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
32421.1Skamil
32431.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32441.1Skamil	    "without signal to be sent\n");
32451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32461.1Skamil
32471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32491.1Skamil
32501.1Skamil	validate_status_exited(status, exitval);
32511.1Skamil
32521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32531.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32541.1Skamil}
32551.1Skamil
32561.1SkamilATF_TC(io_read_i4);
32571.1SkamilATF_TC_HEAD(io_read_i4, tc)
32581.1Skamil{
32591.1Skamil	atf_tc_set_md_var(tc, "descr",
32601.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
32611.1Skamil}
32621.1Skamil
32631.1SkamilATF_TC_BODY(io_read_i4, tc)
32641.1Skamil{
32651.1Skamil	const int exitval = 5;
32661.1Skamil	const int sigval = SIGSTOP;
32671.1Skamil	pid_t child, wpid;
32681.1Skamil	uint64_t lookup_me = 0;
32691.1Skamil	uint64_t magic;
32701.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
32711.1Skamil	struct ptrace_io_desc io = {
32721.1Skamil		.piod_op = PIOD_READ_I,
32731.1Skamil		.piod_offs = dummy_fn1,
32741.1Skamil		.piod_addr = &lookup_me,
32751.1Skamil		.piod_len = sizeof(lookup_me)
32761.1Skamil	};
32771.1Skamil#if defined(TWAIT_HAVE_STATUS)
32781.1Skamil	int status;
32791.1Skamil#endif
32801.1Skamil
32811.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32821.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32831.1Skamil	if (child == 0) {
32841.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32851.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32861.1Skamil
32871.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32881.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32891.1Skamil
32901.13Schristos		DPRINTF("Before exiting of the child process\n");
32911.1Skamil		_exit(exitval);
32921.1Skamil	}
32931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32941.1Skamil
32951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32971.1Skamil
32981.1Skamil	validate_status_stopped(status, sigval);
32991.1Skamil
33001.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33011.1Skamil	    child, getpid());
33021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
33031.1Skamil
33041.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33051.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
33061.1Skamil
33071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33081.1Skamil	    "without signal to be sent\n");
33091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33101.1Skamil
33111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33131.1Skamil
33141.1Skamil	validate_status_exited(status, exitval);
33151.1Skamil
33161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33181.1Skamil}
33191.1Skamil
33201.1SkamilATF_TC(read_i1);
33211.1SkamilATF_TC_HEAD(read_i1, tc)
33221.1Skamil{
33231.1Skamil	atf_tc_set_md_var(tc, "descr",
33241.1Skamil	    "Verify PT_READ_I called once");
33251.1Skamil}
33261.1Skamil
33271.1SkamilATF_TC_BODY(read_i1, tc)
33281.1Skamil{
33291.1Skamil	const int exitval = 5;
33301.1Skamil	const int sigval = SIGSTOP;
33311.1Skamil	pid_t child, wpid;
33321.1Skamil	int lookup_me = 0;
33331.1Skamil	int magic;
33341.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33351.1Skamil#if defined(TWAIT_HAVE_STATUS)
33361.1Skamil	int status;
33371.1Skamil#endif
33381.1Skamil
33391.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33401.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33411.1Skamil	if (child == 0) {
33421.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33431.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33441.1Skamil
33451.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33461.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33471.1Skamil
33481.13Schristos		DPRINTF("Before exiting of the child process\n");
33491.1Skamil		_exit(exitval);
33501.1Skamil	}
33511.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
33571.1Skamil
33581.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33591.1Skamil	    child, getpid());
33601.1Skamil	errno = 0;
33611.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
33621.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33631.1Skamil
33641.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33651.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
33661.1Skamil
33671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33681.1Skamil	    "without signal to be sent\n");
33691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33701.1Skamil
33711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33731.1Skamil
33741.1Skamil	validate_status_exited(status, exitval);
33751.1Skamil
33761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33771.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33781.1Skamil}
33791.1Skamil
33801.1SkamilATF_TC(read_i2);
33811.1SkamilATF_TC_HEAD(read_i2, tc)
33821.1Skamil{
33831.1Skamil	atf_tc_set_md_var(tc, "descr",
33841.1Skamil	    "Verify PT_READ_I called twice");
33851.1Skamil}
33861.1Skamil
33871.1SkamilATF_TC_BODY(read_i2, tc)
33881.1Skamil{
33891.1Skamil	const int exitval = 5;
33901.1Skamil	const int sigval = SIGSTOP;
33911.1Skamil	pid_t child, wpid;
33921.1Skamil	int lookup_me1 = 0;
33931.1Skamil	int lookup_me2 = 0;
33941.1Skamil	int magic1;
33951.1Skamil	int magic2;
33961.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
33971.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
33981.1Skamil#if defined(TWAIT_HAVE_STATUS)
33991.1Skamil	int status;
34001.1Skamil#endif
34011.1Skamil
34021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34041.1Skamil	if (child == 0) {
34051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34071.1Skamil
34081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34101.1Skamil
34111.13Schristos		DPRINTF("Before exiting of the child process\n");
34121.1Skamil		_exit(exitval);
34131.1Skamil	}
34141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34151.1Skamil
34161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34181.1Skamil
34191.1Skamil	validate_status_stopped(status, sigval);
34201.1Skamil
34211.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
34221.1Skamil	    child, getpid());
34231.1Skamil	errno = 0;
34241.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
34251.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34261.1Skamil
34271.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
34281.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
34291.1Skamil
34301.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
34311.1Skamil	    child, getpid());
34321.1Skamil	errno = 0;
34331.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
34341.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34351.1Skamil
34361.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
34371.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
34381.1Skamil
34391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34401.1Skamil	    "without signal to be sent\n");
34411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34421.1Skamil
34431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34451.1Skamil
34461.1Skamil	validate_status_exited(status, exitval);
34471.1Skamil
34481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34501.1Skamil}
34511.1Skamil
34521.1SkamilATF_TC(read_i3);
34531.1SkamilATF_TC_HEAD(read_i3, tc)
34541.1Skamil{
34551.1Skamil	atf_tc_set_md_var(tc, "descr",
34561.1Skamil	    "Verify PT_READ_I called three times");
34571.1Skamil}
34581.1Skamil
34591.1SkamilATF_TC_BODY(read_i3, tc)
34601.1Skamil{
34611.1Skamil	const int exitval = 5;
34621.1Skamil	const int sigval = SIGSTOP;
34631.1Skamil	pid_t child, wpid;
34641.1Skamil	int lookup_me1 = 0;
34651.1Skamil	int lookup_me2 = 0;
34661.1Skamil	int lookup_me3 = 0;
34671.1Skamil	int magic1;
34681.1Skamil	int magic2;
34691.1Skamil	int magic3;
34701.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
34711.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
34721.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
34731.1Skamil#if defined(TWAIT_HAVE_STATUS)
34741.1Skamil	int status;
34751.1Skamil#endif
34761.1Skamil
34771.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34781.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34791.1Skamil	if (child == 0) {
34801.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34811.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34821.1Skamil
34831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34851.1Skamil
34861.13Schristos		DPRINTF("Before exiting of the child process\n");
34871.1Skamil		_exit(exitval);
34881.1Skamil	}
34891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34901.1Skamil
34911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34931.1Skamil
34941.1Skamil	validate_status_stopped(status, sigval);
34951.1Skamil
34961.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
34971.1Skamil	    child, getpid());
34981.1Skamil	errno = 0;
34991.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
35001.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35011.1Skamil
35021.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
35031.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
35041.1Skamil
35051.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
35061.1Skamil	    child, getpid());
35071.1Skamil	errno = 0;
35081.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
35091.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35101.1Skamil
35111.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
35121.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
35131.1Skamil
35141.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
35151.1Skamil	    child, getpid());
35161.1Skamil	errno = 0;
35171.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
35181.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35191.1Skamil
35201.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
35211.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
35221.1Skamil
35231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35241.1Skamil	    "without signal to be sent\n");
35251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35261.1Skamil
35271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35291.1Skamil
35301.1Skamil	validate_status_exited(status, exitval);
35311.1Skamil
35321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35341.1Skamil}
35351.1Skamil
35361.1SkamilATF_TC(read_i4);
35371.1SkamilATF_TC_HEAD(read_i4, tc)
35381.1Skamil{
35391.1Skamil	atf_tc_set_md_var(tc, "descr",
35401.1Skamil	    "Verify PT_READ_I called four times");
35411.1Skamil}
35421.1Skamil
35431.1SkamilATF_TC_BODY(read_i4, tc)
35441.1Skamil{
35451.1Skamil	const int exitval = 5;
35461.1Skamil	const int sigval = SIGSTOP;
35471.1Skamil	pid_t child, wpid;
35481.1Skamil	int lookup_me1 = 0;
35491.1Skamil	int lookup_me2 = 0;
35501.1Skamil	int lookup_me3 = 0;
35511.1Skamil	int lookup_me4 = 0;
35521.1Skamil	int magic1;
35531.1Skamil	int magic2;
35541.1Skamil	int magic3;
35551.1Skamil	int magic4;
35561.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35571.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
35581.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
35591.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
35601.1Skamil#if defined(TWAIT_HAVE_STATUS)
35611.1Skamil	int status;
35621.1Skamil#endif
35631.1Skamil
35641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35661.1Skamil	if (child == 0) {
35671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35691.1Skamil
35701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35721.1Skamil
35731.13Schristos		DPRINTF("Before exiting of the child process\n");
35741.1Skamil		_exit(exitval);
35751.1Skamil	}
35761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35771.1Skamil
35781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35801.1Skamil
35811.1Skamil	validate_status_stopped(status, sigval);
35821.1Skamil
35831.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
35841.1Skamil	    child, getpid());
35851.1Skamil	errno = 0;
35861.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
35871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35881.1Skamil
35891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
35901.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
35911.1Skamil
35921.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
35931.1Skamil	    child, getpid());
35941.1Skamil	errno = 0;
35951.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
35961.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35971.1Skamil
35981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
35991.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
36001.1Skamil
36011.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
36021.1Skamil	    child, getpid());
36031.1Skamil	errno = 0;
36041.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
36051.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36061.1Skamil
36071.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
36081.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
36091.1Skamil
36101.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
36111.1Skamil	    child, getpid());
36121.1Skamil	errno = 0;
36131.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
36141.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36151.1Skamil
36161.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
36171.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
36181.1Skamil
36191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36201.1Skamil	    "without signal to be sent\n");
36211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36221.1Skamil
36231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36251.1Skamil
36261.1Skamil	validate_status_exited(status, exitval);
36271.1Skamil
36281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36301.1Skamil}
36311.1Skamil
36321.1Skamil#if defined(HAVE_GPREGS)
36331.1SkamilATF_TC(regs1);
36341.1SkamilATF_TC_HEAD(regs1, tc)
36351.1Skamil{
36361.1Skamil	atf_tc_set_md_var(tc, "descr",
36371.1Skamil	    "Verify plain PT_GETREGS call without further steps");
36381.1Skamil}
36391.1Skamil
36401.1SkamilATF_TC_BODY(regs1, tc)
36411.1Skamil{
36421.1Skamil	const int exitval = 5;
36431.1Skamil	const int sigval = SIGSTOP;
36441.1Skamil	pid_t child, wpid;
36451.1Skamil#if defined(TWAIT_HAVE_STATUS)
36461.1Skamil	int status;
36471.1Skamil#endif
36481.1Skamil	struct reg r;
36491.1Skamil
36501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36521.1Skamil	if (child == 0) {
36531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36551.1Skamil
36561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36581.1Skamil
36591.13Schristos		DPRINTF("Before exiting of the child process\n");
36601.1Skamil		_exit(exitval);
36611.1Skamil	}
36621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36631.1Skamil
36641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36661.1Skamil
36671.1Skamil	validate_status_stopped(status, sigval);
36681.1Skamil
36691.13Schristos	DPRINTF("Call GETREGS for the child process\n");
36701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
36711.1Skamil
36721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36731.1Skamil	    "without signal to be sent\n");
36741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36751.1Skamil
36761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36781.1Skamil
36791.1Skamil	validate_status_exited(status, exitval);
36801.1Skamil
36811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36831.1Skamil}
36841.1Skamil#endif
36851.1Skamil
36861.1Skamil#if defined(HAVE_GPREGS)
36871.1SkamilATF_TC(regs2);
36881.1SkamilATF_TC_HEAD(regs2, tc)
36891.1Skamil{
36901.1Skamil	atf_tc_set_md_var(tc, "descr",
36911.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
36921.1Skamil}
36931.1Skamil
36941.1SkamilATF_TC_BODY(regs2, tc)
36951.1Skamil{
36961.1Skamil	const int exitval = 5;
36971.1Skamil	const int sigval = SIGSTOP;
36981.1Skamil	pid_t child, wpid;
36991.1Skamil#if defined(TWAIT_HAVE_STATUS)
37001.1Skamil	int status;
37011.1Skamil#endif
37021.1Skamil	struct reg r;
37031.1Skamil
37041.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37051.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37061.1Skamil	if (child == 0) {
37071.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37081.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37091.1Skamil
37101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37121.1Skamil
37131.13Schristos		DPRINTF("Before exiting of the child process\n");
37141.1Skamil		_exit(exitval);
37151.1Skamil	}
37161.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
37221.1Skamil
37231.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37251.1Skamil
37261.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
37271.1Skamil
37281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37291.1Skamil	    "without signal to be sent\n");
37301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37311.1Skamil
37321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37341.1Skamil
37351.1Skamil	validate_status_exited(status, exitval);
37361.1Skamil
37371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37391.1Skamil}
37401.1Skamil#endif
37411.1Skamil
37421.1Skamil#if defined(HAVE_GPREGS)
37431.1SkamilATF_TC(regs3);
37441.1SkamilATF_TC_HEAD(regs3, tc)
37451.1Skamil{
37461.1Skamil	atf_tc_set_md_var(tc, "descr",
37471.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
37481.1Skamil}
37491.1Skamil
37501.1SkamilATF_TC_BODY(regs3, tc)
37511.1Skamil{
37521.1Skamil	const int exitval = 5;
37531.1Skamil	const int sigval = SIGSTOP;
37541.1Skamil	pid_t child, wpid;
37551.1Skamil#if defined(TWAIT_HAVE_STATUS)
37561.1Skamil	int status;
37571.1Skamil#endif
37581.1Skamil	struct reg r;
37591.1Skamil
37601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37621.1Skamil	if (child == 0) {
37631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37651.1Skamil
37661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37681.1Skamil
37691.13Schristos		DPRINTF("Before exiting of the child process\n");
37701.1Skamil		_exit(exitval);
37711.1Skamil	}
37721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
37781.1Skamil
37791.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37811.1Skamil
37821.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
37831.1Skamil
37841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37851.1Skamil	    "without signal to be sent\n");
37861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37871.1Skamil
37881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37901.1Skamil
37911.1Skamil	validate_status_exited(status, exitval);
37921.1Skamil
37931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37941.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37951.1Skamil}
37961.1Skamil#endif
37971.1Skamil
37981.1Skamil#if defined(HAVE_GPREGS)
37991.1SkamilATF_TC(regs4);
38001.1SkamilATF_TC_HEAD(regs4, tc)
38011.1Skamil{
38021.1Skamil	atf_tc_set_md_var(tc, "descr",
38031.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
38041.1Skamil}
38051.1Skamil
38061.1SkamilATF_TC_BODY(regs4, tc)
38071.1Skamil{
38081.1Skamil	const int exitval = 5;
38091.1Skamil	const int sigval = SIGSTOP;
38101.1Skamil	pid_t child, wpid;
38111.1Skamil#if defined(TWAIT_HAVE_STATUS)
38121.1Skamil	int status;
38131.1Skamil#endif
38141.1Skamil	struct reg r;
38151.1Skamil
38161.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38171.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38181.1Skamil	if (child == 0) {
38191.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38201.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38211.1Skamil
38221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38241.1Skamil
38251.13Schristos		DPRINTF("Before exiting of the child process\n");
38261.1Skamil		_exit(exitval);
38271.1Skamil	}
38281.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
38341.1Skamil
38351.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38371.1Skamil
38381.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
38391.1Skamil
38401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38411.1Skamil	    "without signal to be sent\n");
38421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38431.1Skamil
38441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38461.1Skamil
38471.1Skamil	validate_status_exited(status, exitval);
38481.1Skamil
38491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38511.1Skamil}
38521.1Skamil#endif
38531.1Skamil
38541.1Skamil#if defined(HAVE_GPREGS)
38551.1SkamilATF_TC(regs5);
38561.1SkamilATF_TC_HEAD(regs5, tc)
38571.1Skamil{
38581.1Skamil	atf_tc_set_md_var(tc, "descr",
38591.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
38601.1Skamil}
38611.1Skamil
38621.1SkamilATF_TC_BODY(regs5, tc)
38631.1Skamil{
38641.1Skamil	const int exitval = 5;
38651.1Skamil	const int sigval = SIGSTOP;
38661.1Skamil	pid_t child, wpid;
38671.1Skamil#if defined(TWAIT_HAVE_STATUS)
38681.1Skamil	int status;
38691.1Skamil#endif
38701.1Skamil	struct reg r;
38711.1Skamil
38721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38741.1Skamil	if (child == 0) {
38751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38771.1Skamil
38781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38801.1Skamil
38811.13Schristos		DPRINTF("Before exiting of the child process\n");
38821.1Skamil		_exit(exitval);
38831.1Skamil	}
38841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
38901.1Skamil
38911.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38931.1Skamil
38941.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
38951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38961.1Skamil
38971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38981.1Skamil	    "without signal to be sent\n");
38991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39001.1Skamil
39011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39031.1Skamil
39041.1Skamil	validate_status_exited(status, exitval);
39051.1Skamil
39061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39081.1Skamil}
39091.1Skamil#endif
39101.1Skamil
39111.1Skamil#if defined(HAVE_FPREGS)
39121.1SkamilATF_TC(fpregs1);
39131.1SkamilATF_TC_HEAD(fpregs1, tc)
39141.1Skamil{
39151.1Skamil	atf_tc_set_md_var(tc, "descr",
39161.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
39171.1Skamil}
39181.1Skamil
39191.1SkamilATF_TC_BODY(fpregs1, tc)
39201.1Skamil{
39211.1Skamil	const int exitval = 5;
39221.1Skamil	const int sigval = SIGSTOP;
39231.1Skamil	pid_t child, wpid;
39241.1Skamil#if defined(TWAIT_HAVE_STATUS)
39251.1Skamil	int status;
39261.1Skamil#endif
39271.1Skamil	struct fpreg r;
39281.1Skamil
39291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39311.1Skamil	if (child == 0) {
39321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39341.1Skamil
39351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39371.1Skamil
39381.13Schristos		DPRINTF("Before exiting of the child process\n");
39391.1Skamil		_exit(exitval);
39401.1Skamil	}
39411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
39471.1Skamil
39481.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
39491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
39501.1Skamil
39511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39521.1Skamil	    "without signal to be sent\n");
39531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39541.1Skamil
39551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39571.1Skamil
39581.1Skamil	validate_status_exited(status, exitval);
39591.1Skamil
39601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39621.1Skamil}
39631.1Skamil#endif
39641.1Skamil
39651.1Skamil#if defined(HAVE_FPREGS)
39661.1SkamilATF_TC(fpregs2);
39671.1SkamilATF_TC_HEAD(fpregs2, tc)
39681.1Skamil{
39691.1Skamil	atf_tc_set_md_var(tc, "descr",
39701.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
39711.1Skamil	    "regs");
39721.1Skamil}
39731.1Skamil
39741.1SkamilATF_TC_BODY(fpregs2, tc)
39751.1Skamil{
39761.1Skamil	const int exitval = 5;
39771.1Skamil	const int sigval = SIGSTOP;
39781.1Skamil	pid_t child, wpid;
39791.1Skamil#if defined(TWAIT_HAVE_STATUS)
39801.1Skamil	int status;
39811.1Skamil#endif
39821.1Skamil	struct fpreg r;
39831.1Skamil
39841.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39851.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39861.1Skamil	if (child == 0) {
39871.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39881.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39891.1Skamil
39901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39921.1Skamil
39931.13Schristos		DPRINTF("Before exiting of the child process\n");
39941.1Skamil		_exit(exitval);
39951.1Skamil	}
39961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39971.1Skamil
39981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40001.1Skamil
40011.1Skamil	validate_status_stopped(status, sigval);
40021.1Skamil
40031.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
40041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
40051.1Skamil
40061.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
40071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
40081.1Skamil
40091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40101.1Skamil	    "without signal to be sent\n");
40111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40121.1Skamil
40131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40151.1Skamil
40161.1Skamil	validate_status_exited(status, exitval);
40171.1Skamil
40181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40201.1Skamil}
40211.1Skamil#endif
40221.1Skamil
40231.1Skamil#if defined(PT_STEP)
40241.1Skamilstatic void
40251.2Skamilptrace_step(int N, int setstep)
40261.1Skamil{
40271.1Skamil	const int exitval = 5;
40281.1Skamil	const int sigval = SIGSTOP;
40291.1Skamil	pid_t child, wpid;
40301.1Skamil#if defined(TWAIT_HAVE_STATUS)
40311.1Skamil	int status;
40321.1Skamil#endif
40331.1Skamil	int happy;
40341.1Skamil
40351.1Skamil#if defined(__arm__)
40361.1Skamil	/* PT_STEP not supported on arm 32-bit */
40371.1Skamil	atf_tc_expect_fail("PR kern/52119");
40381.1Skamil#endif
40391.1Skamil
40401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40421.1Skamil	if (child == 0) {
40431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40451.1Skamil
40461.1Skamil		happy = check_happy(999);
40471.1Skamil
40481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40501.1Skamil
40511.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
40521.1Skamil
40531.13Schristos		DPRINTF("Before exiting of the child process\n");
40541.1Skamil		_exit(exitval);
40551.1Skamil	}
40561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40571.1Skamil
40581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40601.1Skamil
40611.1Skamil	validate_status_stopped(status, sigval);
40621.1Skamil
40631.1Skamil	while (N --> 0) {
40641.2Skamil		if (setstep) {
40651.13Schristos			DPRINTF("Before resuming the child process where it "
40661.2Skamil			    "left off and without signal to be sent (use "
40671.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
40681.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
40691.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
40701.2Skamil			    != -1);
40711.2Skamil		} else {
40721.13Schristos			DPRINTF("Before resuming the child process where it "
40731.2Skamil			    "left off and without signal to be sent (use "
40741.2Skamil			    "PT_STEP)\n");
40751.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
40761.2Skamil			    != -1);
40771.2Skamil		}
40781.1Skamil
40791.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40801.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
40811.1Skamil		    child);
40821.1Skamil
40831.1Skamil		validate_status_stopped(status, SIGTRAP);
40841.2Skamil
40851.2Skamil		if (setstep) {
40861.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
40871.2Skamil		}
40881.1Skamil	}
40891.1Skamil
40901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40911.1Skamil	    "without signal to be sent\n");
40921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40931.1Skamil
40941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40961.1Skamil
40971.1Skamil	validate_status_exited(status, exitval);
40981.1Skamil
40991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41011.1Skamil}
41021.1Skamil#endif
41031.1Skamil
41041.1Skamil#if defined(PT_STEP)
41051.1SkamilATF_TC(step1);
41061.1SkamilATF_TC_HEAD(step1, tc)
41071.1Skamil{
41081.1Skamil	atf_tc_set_md_var(tc, "descr",
41091.1Skamil	    "Verify single PT_STEP call");
41101.1Skamil}
41111.1Skamil
41121.1SkamilATF_TC_BODY(step1, tc)
41131.1Skamil{
41141.2Skamil	ptrace_step(1, 0);
41151.1Skamil}
41161.1Skamil#endif
41171.1Skamil
41181.1Skamil#if defined(PT_STEP)
41191.1SkamilATF_TC(step2);
41201.1SkamilATF_TC_HEAD(step2, tc)
41211.1Skamil{
41221.1Skamil	atf_tc_set_md_var(tc, "descr",
41231.1Skamil	    "Verify PT_STEP called twice");
41241.1Skamil}
41251.1Skamil
41261.1SkamilATF_TC_BODY(step2, tc)
41271.1Skamil{
41281.2Skamil	ptrace_step(2, 0);
41291.1Skamil}
41301.1Skamil#endif
41311.1Skamil
41321.1Skamil#if defined(PT_STEP)
41331.1SkamilATF_TC(step3);
41341.1SkamilATF_TC_HEAD(step3, tc)
41351.1Skamil{
41361.1Skamil	atf_tc_set_md_var(tc, "descr",
41371.1Skamil	    "Verify PT_STEP called three times");
41381.1Skamil}
41391.1Skamil
41401.1SkamilATF_TC_BODY(step3, tc)
41411.1Skamil{
41421.2Skamil	ptrace_step(3, 0);
41431.1Skamil}
41441.1Skamil#endif
41451.1Skamil
41461.1Skamil#if defined(PT_STEP)
41471.1SkamilATF_TC(step4);
41481.1SkamilATF_TC_HEAD(step4, tc)
41491.1Skamil{
41501.1Skamil	atf_tc_set_md_var(tc, "descr",
41511.1Skamil	    "Verify PT_STEP called four times");
41521.1Skamil}
41531.1Skamil
41541.1SkamilATF_TC_BODY(step4, tc)
41551.1Skamil{
41561.2Skamil	ptrace_step(4, 0);
41571.2Skamil}
41581.2Skamil#endif
41591.2Skamil
41601.2Skamil#if defined(PT_STEP)
41611.2SkamilATF_TC(setstep1);
41621.2SkamilATF_TC_HEAD(setstep1, tc)
41631.2Skamil{
41641.2Skamil	atf_tc_set_md_var(tc, "descr",
41651.2Skamil	    "Verify single PT_SETSTEP call");
41661.2Skamil}
41671.2Skamil
41681.2SkamilATF_TC_BODY(setstep1, tc)
41691.2Skamil{
41701.2Skamil	ptrace_step(1, 1);
41711.2Skamil}
41721.2Skamil#endif
41731.2Skamil
41741.2Skamil#if defined(PT_STEP)
41751.2SkamilATF_TC(setstep2);
41761.2SkamilATF_TC_HEAD(setstep2, tc)
41771.2Skamil{
41781.2Skamil	atf_tc_set_md_var(tc, "descr",
41791.2Skamil	    "Verify PT_SETSTEP called twice");
41801.2Skamil}
41811.2Skamil
41821.2SkamilATF_TC_BODY(setstep2, tc)
41831.2Skamil{
41841.2Skamil	ptrace_step(2, 1);
41851.2Skamil}
41861.2Skamil#endif
41871.2Skamil
41881.2Skamil#if defined(PT_STEP)
41891.2SkamilATF_TC(setstep3);
41901.2SkamilATF_TC_HEAD(setstep3, tc)
41911.2Skamil{
41921.2Skamil	atf_tc_set_md_var(tc, "descr",
41931.2Skamil	    "Verify PT_SETSTEP called three times");
41941.2Skamil}
41951.2Skamil
41961.2SkamilATF_TC_BODY(setstep3, tc)
41971.2Skamil{
41981.2Skamil	ptrace_step(3, 1);
41991.2Skamil}
42001.2Skamil#endif
42011.2Skamil
42021.2Skamil#if defined(PT_STEP)
42031.2SkamilATF_TC(setstep4);
42041.2SkamilATF_TC_HEAD(setstep4, tc)
42051.2Skamil{
42061.2Skamil	atf_tc_set_md_var(tc, "descr",
42071.2Skamil	    "Verify PT_SETSTEP called four times");
42081.2Skamil}
42091.2Skamil
42101.2SkamilATF_TC_BODY(setstep4, tc)
42111.2Skamil{
42121.2Skamil	ptrace_step(4, 1);
42131.1Skamil}
42141.1Skamil#endif
42151.1Skamil
42161.1SkamilATF_TC(kill1);
42171.1SkamilATF_TC_HEAD(kill1, tc)
42181.1Skamil{
42191.1Skamil	atf_tc_set_md_var(tc, "descr",
42201.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
42211.1Skamil}
42221.1Skamil
42231.1SkamilATF_TC_BODY(kill1, tc)
42241.1Skamil{
42251.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
42261.1Skamil	pid_t child, wpid;
42271.1Skamil#if defined(TWAIT_HAVE_STATUS)
42281.1Skamil	int status;
42291.1Skamil#endif
42301.1Skamil
42311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42331.1Skamil	if (child == 0) {
42341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42361.1Skamil
42371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42391.1Skamil
42401.1Skamil		/* NOTREACHED */
42411.1Skamil		FORKEE_ASSERTX(0 &&
42421.1Skamil		    "Child should be terminated by a signal from its parent");
42431.1Skamil	}
42441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42451.1Skamil
42461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42481.1Skamil
42491.1Skamil	validate_status_stopped(status, sigval);
42501.1Skamil
42511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42521.1Skamil	    "without signal to be sent\n");
42531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
42541.1Skamil
42551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42571.1Skamil
42581.1Skamil	validate_status_signaled(status, sigsent, 0);
42591.1Skamil
42601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42621.1Skamil}
42631.1Skamil
42641.1SkamilATF_TC(kill2);
42651.1SkamilATF_TC_HEAD(kill2, tc)
42661.1Skamil{
42671.1Skamil	atf_tc_set_md_var(tc, "descr",
42681.1Skamil	    "Verify that PT_KILL terminates child");
42691.1Skamil}
42701.1Skamil
42711.1SkamilATF_TC_BODY(kill2, tc)
42721.1Skamil{
42731.1Skamil	const int sigval = SIGSTOP;
42741.1Skamil	pid_t child, wpid;
42751.1Skamil#if defined(TWAIT_HAVE_STATUS)
42761.1Skamil	int status;
42771.1Skamil#endif
42781.1Skamil
42791.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42801.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42811.1Skamil	if (child == 0) {
42821.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42831.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42841.1Skamil
42851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42871.1Skamil
42881.1Skamil		/* NOTREACHED */
42891.1Skamil		FORKEE_ASSERTX(0 &&
42901.1Skamil		    "Child should be terminated by a signal from its parent");
42911.1Skamil	}
42921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42931.1Skamil
42941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42961.1Skamil
42971.1Skamil	validate_status_stopped(status, sigval);
42981.1Skamil
42991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43001.1Skamil	    "without signal to be sent\n");
43011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
43021.1Skamil
43031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43051.1Skamil
43061.1Skamil	validate_status_signaled(status, SIGKILL, 0);
43071.1Skamil
43081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43101.1Skamil}
43111.1Skamil
43121.1SkamilATF_TC(lwpinfo1);
43131.1SkamilATF_TC_HEAD(lwpinfo1, tc)
43141.1Skamil{
43151.1Skamil	atf_tc_set_md_var(tc, "descr",
43161.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
43171.1Skamil}
43181.1Skamil
43191.1SkamilATF_TC_BODY(lwpinfo1, tc)
43201.1Skamil{
43211.1Skamil	const int exitval = 5;
43221.1Skamil	const int sigval = SIGSTOP;
43231.1Skamil	pid_t child, wpid;
43241.1Skamil#if defined(TWAIT_HAVE_STATUS)
43251.1Skamil	int status;
43261.1Skamil#endif
43271.1Skamil	struct ptrace_lwpinfo info = {0, 0};
43281.1Skamil
43291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43311.1Skamil	if (child == 0) {
43321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43341.1Skamil
43351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43371.1Skamil
43381.13Schristos		DPRINTF("Before exiting of the child process\n");
43391.1Skamil		_exit(exitval);
43401.1Skamil	}
43411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43421.1Skamil
43431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43451.1Skamil
43461.1Skamil	validate_status_stopped(status, sigval);
43471.1Skamil
43481.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
43491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
43501.1Skamil
43511.13Schristos	DPRINTF("Assert that there exists a thread\n");
43521.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
43531.1Skamil
43541.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
43551.1Skamil	    info.pl_lwpid);
43561.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
43571.1Skamil	    "Received event %d != expected event %d",
43581.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
43591.1Skamil
43601.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
43611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
43621.1Skamil
43631.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
43641.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
43651.1Skamil
43661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43671.1Skamil	    "without signal to be sent\n");
43681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43691.1Skamil
43701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43721.1Skamil
43731.1Skamil	validate_status_exited(status, exitval);
43741.1Skamil
43751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43771.1Skamil}
43781.1Skamil
43791.1Skamil#if defined(TWAIT_HAVE_PID)
43801.1SkamilATF_TC(lwpinfo2);
43811.1SkamilATF_TC_HEAD(lwpinfo2, tc)
43821.1Skamil{
43831.1Skamil	atf_tc_set_md_var(tc, "descr",
43841.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
43851.1Skamil	    "tracer)");
43861.1Skamil}
43871.1Skamil
43881.1SkamilATF_TC_BODY(lwpinfo2, tc)
43891.1Skamil{
43901.1Skamil	struct msg_fds parent_tracee, parent_tracer;
43911.1Skamil	const int exitval_tracee = 5;
43921.1Skamil	const int exitval_tracer = 10;
43931.1Skamil	pid_t tracee, tracer, wpid;
43941.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
43951.1Skamil#if defined(TWAIT_HAVE_STATUS)
43961.1Skamil	int status;
43971.1Skamil#endif
43981.1Skamil	struct ptrace_lwpinfo info = {0, 0};
43991.1Skamil
44001.13Schristos	DPRINTF("Spawn tracee\n");
44011.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
44021.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
44031.1Skamil	tracee = atf_utils_fork();
44041.1Skamil	if (tracee == 0) {
44051.1Skamil
44061.1Skamil		/* Wait for message from the parent */
44071.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
44081.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
44091.1Skamil
44101.1Skamil		_exit(exitval_tracee);
44111.1Skamil	}
44121.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
44131.1Skamil
44141.13Schristos	DPRINTF("Spawn debugger\n");
44151.1Skamil	tracer = atf_utils_fork();
44161.1Skamil	if (tracer == 0) {
44171.1Skamil		/* No IPC to communicate with the child */
44181.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
44191.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
44201.1Skamil
44211.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
44221.1Skamil		FORKEE_REQUIRE_SUCCESS(
44231.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44241.1Skamil
44251.1Skamil		forkee_status_stopped(status, SIGSTOP);
44261.1Skamil
44271.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44281.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44291.1Skamil		    != -1);
44301.1Skamil
44311.13Schristos		DPRINTF("Assert that there exists a thread\n");
44321.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
44331.1Skamil
44341.13Schristos		DPRINTF("Assert that lwp thread %d received event "
44351.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
44361.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
44371.1Skamil
44381.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44391.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44401.1Skamil		    != -1);
44411.1Skamil
44421.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
44431.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
44441.1Skamil
44451.1Skamil		/* Resume tracee with PT_CONTINUE */
44461.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
44471.1Skamil
44481.1Skamil		/* Inform parent that tracer has attached to tracee */
44491.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
44501.1Skamil		/* Wait for parent */
44511.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
44521.1Skamil
44531.1Skamil		/* Wait for tracee and assert that it exited */
44541.1Skamil		FORKEE_REQUIRE_SUCCESS(
44551.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44561.1Skamil
44571.1Skamil		forkee_status_exited(status, exitval_tracee);
44581.1Skamil
44591.13Schristos		DPRINTF("Before exiting of the tracer process\n");
44601.1Skamil		_exit(exitval_tracer);
44611.1Skamil	}
44621.1Skamil
44631.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
44641.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
44651.1Skamil
44661.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
44671.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
44681.1Skamil
44691.13Schristos	DPRINTF("Detect that tracee is zombie\n");
44701.1Skamil	await_zombie(tracee);
44711.1Skamil
44721.13Schristos	DPRINTF("Assert that there is no status about tracee - "
44731.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
44741.1Skamil	TWAIT_REQUIRE_SUCCESS(
44751.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
44761.1Skamil
44771.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
44781.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
44791.1Skamil
44801.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
44811.1Skamil	    TWAIT_FNAME);
44821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
44831.1Skamil	    tracer);
44841.1Skamil
44851.1Skamil	validate_status_exited(status, exitval_tracer);
44861.1Skamil
44871.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
44881.1Skamil	    TWAIT_FNAME);
44891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
44901.1Skamil	    tracee);
44911.1Skamil
44921.1Skamil	validate_status_exited(status, exitval_tracee);
44931.1Skamil
44941.1Skamil	msg_close(&parent_tracer);
44951.1Skamil	msg_close(&parent_tracee);
44961.1Skamil}
44971.1Skamil#endif
44981.1Skamil
44991.1SkamilATF_TC(siginfo1);
45001.1SkamilATF_TC_HEAD(siginfo1, tc)
45011.1Skamil{
45021.1Skamil	atf_tc_set_md_var(tc, "descr",
45031.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
45041.1Skamil}
45051.1Skamil
45061.1SkamilATF_TC_BODY(siginfo1, tc)
45071.1Skamil{
45081.1Skamil	const int exitval = 5;
45091.1Skamil	const int sigval = SIGTRAP;
45101.1Skamil	pid_t child, wpid;
45111.1Skamil#if defined(TWAIT_HAVE_STATUS)
45121.1Skamil	int status;
45131.1Skamil#endif
45141.1Skamil	struct ptrace_siginfo info;
45151.1Skamil	memset(&info, 0, sizeof(info));
45161.1Skamil
45171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
45181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
45191.1Skamil	if (child == 0) {
45201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
45211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
45221.1Skamil
45231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
45241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
45251.1Skamil
45261.13Schristos		DPRINTF("Before exiting of the child process\n");
45271.1Skamil		_exit(exitval);
45281.1Skamil	}
45291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
45301.1Skamil
45311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45331.1Skamil
45341.1Skamil	validate_status_stopped(status, sigval);
45351.1Skamil
45361.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
45371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
45381.1Skamil
45391.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
45401.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
45411.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
45421.1Skamil	    info.psi_siginfo.si_errno);
45431.1Skamil
45441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
45451.1Skamil	    "without signal to be sent\n");
45461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
45471.1Skamil
45481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45501.1Skamil
45511.1Skamil	validate_status_exited(status, exitval);
45521.1Skamil
45531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
45551.1Skamil}
45561.1Skamil
45571.1SkamilATF_TC(siginfo2);
45581.1SkamilATF_TC_HEAD(siginfo2, tc)
45591.1Skamil{
45601.1Skamil	atf_tc_set_md_var(tc, "descr",
45611.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
45621.1Skamil	    "modification of SIGINT from tracee");
45631.1Skamil}
45641.1Skamil
45651.1Skamilstatic int siginfo2_caught = 0;
45661.1Skamil
45671.1Skamilstatic void
45681.1Skamilsiginfo2_sighandler(int sig)
45691.1Skamil{
45701.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
45711.1Skamil
45721.1Skamil	++siginfo2_caught;
45731.1Skamil}
45741.1Skamil
45751.1SkamilATF_TC_BODY(siginfo2, tc)
45761.1Skamil{
45771.1Skamil	const int exitval = 5;
45781.1Skamil	const int sigval = SIGINT;
45791.1Skamil	pid_t child, wpid;
45801.1Skamil	struct sigaction sa;
45811.1Skamil#if defined(TWAIT_HAVE_STATUS)
45821.1Skamil	int status;
45831.1Skamil#endif
45841.1Skamil	struct ptrace_siginfo info;
45851.1Skamil	memset(&info, 0, sizeof(info));
45861.1Skamil
45871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
45881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
45891.1Skamil	if (child == 0) {
45901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
45911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
45921.1Skamil
45931.1Skamil		sa.sa_handler = siginfo2_sighandler;
45941.1Skamil		sa.sa_flags = SA_SIGINFO;
45951.1Skamil		sigemptyset(&sa.sa_mask);
45961.1Skamil
45971.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
45981.1Skamil
45991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46011.1Skamil
46021.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
46031.1Skamil
46041.13Schristos		DPRINTF("Before exiting of the child process\n");
46051.1Skamil		_exit(exitval);
46061.1Skamil	}
46071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46081.1Skamil
46091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46111.1Skamil
46121.1Skamil	validate_status_stopped(status, sigval);
46131.1Skamil
46141.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
46151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
46161.1Skamil
46171.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
46181.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
46191.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
46201.1Skamil	    info.psi_siginfo.si_errno);
46211.1Skamil
46221.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
46231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
46241.1Skamil
46251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46261.1Skamil	    "without signal to be sent\n");
46271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
46281.1Skamil
46291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46311.1Skamil
46321.1Skamil	validate_status_exited(status, exitval);
46331.1Skamil
46341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46361.1Skamil}
46371.1Skamil
46381.1SkamilATF_TC(siginfo3);
46391.1SkamilATF_TC_HEAD(siginfo3, tc)
46401.1Skamil{
46411.1Skamil	atf_tc_set_md_var(tc, "descr",
46421.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
46431.1Skamil	    "setting signal to new value");
46441.1Skamil}
46451.1Skamil
46461.1Skamilstatic int siginfo3_caught = 0;
46471.1Skamil
46481.1Skamilstatic void
46491.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
46501.1Skamil{
46511.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
46521.1Skamil
46531.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
46541.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
46551.1Skamil
46561.1Skamil	++siginfo3_caught;
46571.1Skamil}
46581.1Skamil
46591.1SkamilATF_TC_BODY(siginfo3, tc)
46601.1Skamil{
46611.1Skamil	const int exitval = 5;
46621.1Skamil	const int sigval = SIGINT;
46631.1Skamil	const int sigfaked = SIGTRAP;
46641.1Skamil	const int sicodefaked = TRAP_BRKPT;
46651.1Skamil	pid_t child, wpid;
46661.1Skamil	struct sigaction sa;
46671.1Skamil#if defined(TWAIT_HAVE_STATUS)
46681.1Skamil	int status;
46691.1Skamil#endif
46701.1Skamil	struct ptrace_siginfo info;
46711.1Skamil	memset(&info, 0, sizeof(info));
46721.1Skamil
46731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46751.1Skamil	if (child == 0) {
46761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46781.1Skamil
46791.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
46801.1Skamil		sa.sa_flags = SA_SIGINFO;
46811.1Skamil		sigemptyset(&sa.sa_mask);
46821.1Skamil
46831.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
46841.1Skamil
46851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46871.1Skamil
46881.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
46891.1Skamil
46901.13Schristos		DPRINTF("Before exiting of the child process\n");
46911.1Skamil		_exit(exitval);
46921.1Skamil	}
46931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46941.1Skamil
46951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46971.1Skamil
46981.1Skamil	validate_status_stopped(status, sigval);
46991.1Skamil
47001.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47021.1Skamil
47031.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47041.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47051.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47061.1Skamil	    info.psi_siginfo.si_errno);
47071.1Skamil
47081.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
47091.1Skamil	    sigfaked, sicodefaked);
47101.1Skamil	info.psi_siginfo.si_signo = sigfaked;
47111.1Skamil	info.psi_siginfo.si_code = sicodefaked;
47121.1Skamil
47131.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
47141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
47151.1Skamil
47161.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47181.1Skamil
47191.13Schristos	DPRINTF("Before checking siginfo_t\n");
47201.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
47211.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
47221.1Skamil
47231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47241.1Skamil	    "without signal to be sent\n");
47251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
47261.1Skamil
47271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47291.1Skamil
47301.1Skamil	validate_status_exited(status, exitval);
47311.1Skamil
47321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47341.1Skamil}
47351.1Skamil
47361.1SkamilATF_TC(siginfo4);
47371.1SkamilATF_TC_HEAD(siginfo4, tc)
47381.1Skamil{
47391.1Skamil	atf_tc_set_md_var(tc, "descr",
47401.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
47411.1Skamil}
47421.1Skamil
47431.1SkamilATF_TC_BODY(siginfo4, tc)
47441.1Skamil{
47451.1Skamil	const int sigval = SIGTRAP;
47461.1Skamil	pid_t child, wpid;
47471.1Skamil#if defined(TWAIT_HAVE_STATUS)
47481.1Skamil	int status;
47491.1Skamil#endif
47501.1Skamil
47511.1Skamil	struct ptrace_siginfo info;
47521.1Skamil	memset(&info, 0, sizeof(info));
47531.1Skamil
47541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47561.1Skamil	if (child == 0) {
47571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47591.1Skamil
47601.13Schristos		DPRINTF("Before calling execve(2) from child\n");
47611.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
47621.1Skamil
47631.1Skamil		FORKEE_ASSERT(0 && "Not reached");
47641.1Skamil	}
47651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47661.1Skamil
47671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47691.1Skamil
47701.1Skamil	validate_status_stopped(status, sigval);
47711.1Skamil
47721.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47741.1Skamil
47751.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47761.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47771.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47781.1Skamil	    info.psi_siginfo.si_errno);
47791.1Skamil
47801.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
47811.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
47821.1Skamil
47831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47841.1Skamil	    "without signal to be sent\n");
47851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47861.1Skamil
47871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47891.1Skamil
47901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47921.1Skamil}
47931.1Skamil
47941.1Skamil#if defined(TWAIT_HAVE_PID)
47951.1SkamilATF_TC(siginfo5);
47961.1SkamilATF_TC_HEAD(siginfo5, tc)
47971.1Skamil{
47981.1Skamil	atf_tc_set_md_var(tc, "descr",
47991.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
48001.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
48011.1Skamil}
48021.1Skamil
48031.1SkamilATF_TC_BODY(siginfo5, tc)
48041.1Skamil{
48051.1Skamil	const int exitval = 5;
48061.1Skamil	const int exitval2 = 15;
48071.1Skamil	const int sigval = SIGSTOP;
48081.1Skamil	pid_t child, child2, wpid;
48091.1Skamil#if defined(TWAIT_HAVE_STATUS)
48101.1Skamil	int status;
48111.1Skamil#endif
48121.1Skamil	ptrace_state_t state;
48131.1Skamil	const int slen = sizeof(state);
48141.1Skamil	ptrace_event_t event;
48151.1Skamil	const int elen = sizeof(event);
48161.1Skamil	struct ptrace_siginfo info;
48171.1Skamil
48181.1Skamil	memset(&info, 0, sizeof(info));
48191.1Skamil
48201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48221.1Skamil	if (child == 0) {
48231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48251.1Skamil
48261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
48271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
48281.1Skamil
48291.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
48301.1Skamil
48311.1Skamil		if (child2 == 0)
48321.1Skamil			_exit(exitval2);
48331.1Skamil
48341.1Skamil		FORKEE_REQUIRE_SUCCESS
48351.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
48361.1Skamil
48371.1Skamil		forkee_status_exited(status, exitval2);
48381.1Skamil
48391.13Schristos		DPRINTF("Before exiting of the child process\n");
48401.1Skamil		_exit(exitval);
48411.1Skamil	}
48421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
48431.1Skamil
48441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48461.1Skamil
48471.1Skamil	validate_status_stopped(status, sigval);
48481.1Skamil
48491.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48511.1Skamil
48521.13Schristos	DPRINTF("Before checking siginfo_t\n");
48531.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
48541.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
48551.1Skamil
48561.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
48571.1Skamil	event.pe_set_event = PTRACE_FORK;
48581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
48591.1Skamil
48601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48611.1Skamil	    "without signal to be sent\n");
48621.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
48631.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
48641.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
48651.1Skamil                "state.pe_other_pid=child)\n", child);
48661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
48671.1Skamil
48681.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
48691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48701.1Skamil
48711.1Skamil	validate_status_stopped(status, SIGTRAP);
48721.1Skamil
48731.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48751.1Skamil
48761.13Schristos	DPRINTF("Before checking siginfo_t\n");
48771.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
48781.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
48791.1Skamil
48801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
48811.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
48821.1Skamil
48831.1Skamil	child2 = state.pe_other_pid;
48841.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
48851.1Skamil
48861.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
48871.1Skamil	    TWAIT_FNAME, child2, child);
48881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
48891.1Skamil	    child2);
48901.1Skamil
48911.1Skamil	validate_status_stopped(status, SIGTRAP);
48921.1Skamil
48931.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48951.1Skamil
48961.13Schristos	DPRINTF("Before checking siginfo_t\n");
48971.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
48981.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
48991.1Skamil
49001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
49011.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
49021.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
49031.1Skamil
49041.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
49051.1Skamil	    "without signal to be sent\n");
49061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
49071.1Skamil
49081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49091.1Skamil	    "without signal to be sent\n");
49101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49111.1Skamil
49121.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
49131.1Skamil	    TWAIT_FNAME);
49141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
49151.1Skamil	    child2);
49161.1Skamil
49171.1Skamil	validate_status_exited(status, exitval2);
49181.1Skamil
49191.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
49201.1Skamil	    TWAIT_FNAME);
49211.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
49221.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
49231.1Skamil
49241.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
49251.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
49261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49271.1Skamil
49281.1Skamil	validate_status_stopped(status, SIGCHLD);
49291.1Skamil
49301.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49321.1Skamil
49331.13Schristos	DPRINTF("Before checking siginfo_t\n");
49341.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
49351.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
49361.1Skamil
49371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49381.1Skamil	    "without signal to be sent\n");
49391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49401.1Skamil
49411.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
49421.1Skamil	    TWAIT_FNAME);
49431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49441.1Skamil
49451.1Skamil	validate_status_exited(status, exitval);
49461.1Skamil
49471.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
49481.1Skamil	    TWAIT_FNAME);
49491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49501.1Skamil}
49511.1Skamil#endif
49521.1Skamil
49531.1Skamil#if defined(PT_STEP)
49541.1SkamilATF_TC(siginfo6);
49551.1SkamilATF_TC_HEAD(siginfo6, tc)
49561.1Skamil{
49571.1Skamil	atf_tc_set_md_var(tc, "descr",
49581.1Skamil	    "Verify single PT_STEP call with signal information check");
49591.1Skamil}
49601.1Skamil
49611.1SkamilATF_TC_BODY(siginfo6, tc)
49621.1Skamil{
49631.1Skamil	const int exitval = 5;
49641.1Skamil	const int sigval = SIGSTOP;
49651.1Skamil	pid_t child, wpid;
49661.1Skamil#if defined(TWAIT_HAVE_STATUS)
49671.1Skamil	int status;
49681.1Skamil#endif
49691.1Skamil	int happy;
49701.1Skamil	struct ptrace_siginfo info;
49711.1Skamil
49721.1Skamil#if defined(__arm__)
49731.1Skamil	/* PT_STEP not supported on arm 32-bit */
49741.1Skamil	atf_tc_expect_fail("PR kern/52119");
49751.1Skamil#endif
49761.1Skamil
49771.1Skamil	memset(&info, 0, sizeof(info));
49781.1Skamil
49791.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49801.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49811.1Skamil	if (child == 0) {
49821.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49831.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49841.1Skamil
49851.1Skamil		happy = check_happy(100);
49861.1Skamil
49871.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49881.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49891.1Skamil
49901.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
49911.1Skamil
49921.13Schristos		DPRINTF("Before exiting of the child process\n");
49931.1Skamil		_exit(exitval);
49941.1Skamil	}
49951.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49961.1Skamil
49971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49991.1Skamil
50001.1Skamil	validate_status_stopped(status, sigval);
50011.1Skamil
50021.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50041.1Skamil
50051.13Schristos	DPRINTF("Before checking siginfo_t\n");
50061.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
50071.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
50081.1Skamil
50091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50101.1Skamil	    "without signal to be sent (use PT_STEP)\n");
50111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
50121.1Skamil
50131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50151.1Skamil
50161.1Skamil	validate_status_stopped(status, SIGTRAP);
50171.1Skamil
50181.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50201.1Skamil
50211.13Schristos	DPRINTF("Before checking siginfo_t\n");
50221.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
50231.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
50241.1Skamil
50251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50261.1Skamil	    "without signal to be sent\n");
50271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50281.1Skamil
50291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50311.1Skamil
50321.1Skamil	validate_status_exited(status, exitval);
50331.1Skamil
50341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50361.1Skamil}
50371.1Skamil#endif
50381.1Skamil
50391.1Skamilvolatile lwpid_t the_lwp_id = 0;
50401.1Skamil
50411.1Skamilstatic void
50421.1Skamillwp_main_func(void *arg)
50431.1Skamil{
50441.1Skamil	the_lwp_id = _lwp_self();
50451.1Skamil	_lwp_exit();
50461.1Skamil}
50471.1Skamil
50481.1SkamilATF_TC(lwp_create1);
50491.1SkamilATF_TC_HEAD(lwp_create1, tc)
50501.1Skamil{
50511.1Skamil	atf_tc_set_md_var(tc, "descr",
50521.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
50531.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
50541.1Skamil}
50551.1Skamil
50561.1SkamilATF_TC_BODY(lwp_create1, tc)
50571.1Skamil{
50581.1Skamil	const int exitval = 5;
50591.1Skamil	const int sigval = SIGSTOP;
50601.1Skamil	pid_t child, wpid;
50611.1Skamil#if defined(TWAIT_HAVE_STATUS)
50621.1Skamil	int status;
50631.1Skamil#endif
50641.1Skamil	ptrace_state_t state;
50651.1Skamil	const int slen = sizeof(state);
50661.1Skamil	ptrace_event_t event;
50671.1Skamil	const int elen = sizeof(event);
50681.1Skamil	ucontext_t uc;
50691.1Skamil	lwpid_t lid;
50701.1Skamil	static const size_t ssize = 16*1024;
50711.1Skamil	void *stack;
50721.1Skamil
50731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50751.1Skamil	if (child == 0) {
50761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50781.1Skamil
50791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50811.1Skamil
50821.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
50831.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
50841.1Skamil
50851.13Schristos		DPRINTF("Before making context for new lwp in child\n");
50861.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
50871.1Skamil
50881.13Schristos		DPRINTF("Before creating new in child\n");
50891.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
50901.1Skamil
50911.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
50921.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
50931.1Skamil
50941.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
50951.1Skamil		    "are the same\n", lid, the_lwp_id);
50961.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
50971.1Skamil
50981.13Schristos		DPRINTF("Before exiting of the child process\n");
50991.1Skamil		_exit(exitval);
51001.1Skamil	}
51011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51021.1Skamil
51031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51051.1Skamil
51061.1Skamil	validate_status_stopped(status, sigval);
51071.1Skamil
51081.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
51091.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
51101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
51111.1Skamil
51121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51131.1Skamil	    "without signal to be sent\n");
51141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51151.1Skamil
51161.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
51171.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
51181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51191.1Skamil
51201.1Skamil	validate_status_stopped(status, SIGTRAP);
51211.1Skamil
51221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
51231.1Skamil
51241.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
51251.1Skamil
51261.1Skamil	lid = state.pe_lwp;
51271.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
51281.1Skamil
51291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51301.1Skamil	    "without signal to be sent\n");
51311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51321.1Skamil
51331.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
51341.1Skamil	    TWAIT_FNAME);
51351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51361.1Skamil
51371.1Skamil	validate_status_exited(status, exitval);
51381.1Skamil
51391.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
51401.1Skamil	    TWAIT_FNAME);
51411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51421.1Skamil}
51431.1Skamil
51441.1SkamilATF_TC(lwp_exit1);
51451.1SkamilATF_TC_HEAD(lwp_exit1, tc)
51461.1Skamil{
51471.1Skamil	atf_tc_set_md_var(tc, "descr",
51481.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
51491.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
51501.1Skamil}
51511.1Skamil
51521.1SkamilATF_TC_BODY(lwp_exit1, tc)
51531.1Skamil{
51541.1Skamil	const int exitval = 5;
51551.1Skamil	const int sigval = SIGSTOP;
51561.1Skamil	pid_t child, wpid;
51571.1Skamil#if defined(TWAIT_HAVE_STATUS)
51581.1Skamil	int status;
51591.1Skamil#endif
51601.1Skamil	ptrace_state_t state;
51611.1Skamil	const int slen = sizeof(state);
51621.1Skamil	ptrace_event_t event;
51631.1Skamil	const int elen = sizeof(event);
51641.1Skamil	ucontext_t uc;
51651.1Skamil	lwpid_t lid;
51661.1Skamil	static const size_t ssize = 16*1024;
51671.1Skamil	void *stack;
51681.1Skamil
51691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51711.1Skamil	if (child == 0) {
51721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51741.1Skamil
51751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
51761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
51771.1Skamil
51781.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
51791.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
51801.1Skamil
51811.13Schristos		DPRINTF("Before making context for new lwp in child\n");
51821.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
51831.1Skamil
51841.13Schristos		DPRINTF("Before creating new in child\n");
51851.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
51861.1Skamil
51871.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
51881.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
51891.1Skamil
51901.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
51911.1Skamil		    "are the same\n", lid, the_lwp_id);
51921.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
51931.1Skamil
51941.13Schristos		DPRINTF("Before exiting of the child process\n");
51951.1Skamil		_exit(exitval);
51961.1Skamil	}
51971.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51981.1Skamil
51991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52011.1Skamil
52021.1Skamil	validate_status_stopped(status, sigval);
52031.1Skamil
52041.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
52051.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
52061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52071.1Skamil
52081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52091.1Skamil	    "without signal to be sent\n");
52101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52111.1Skamil
52121.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
52131.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
52141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52151.1Skamil
52161.1Skamil	validate_status_stopped(status, SIGTRAP);
52171.1Skamil
52181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52191.1Skamil
52201.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
52211.1Skamil
52221.1Skamil	lid = state.pe_lwp;
52231.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
52241.1Skamil
52251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52261.1Skamil	    "without signal to be sent\n");
52271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52281.1Skamil
52291.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
52301.1Skamil	    TWAIT_FNAME);
52311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52321.1Skamil
52331.1Skamil	validate_status_exited(status, exitval);
52341.1Skamil
52351.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
52361.1Skamil	    TWAIT_FNAME);
52371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
52381.1Skamil}
52391.1Skamil
52401.1SkamilATF_TC(signal1);
52411.1SkamilATF_TC_HEAD(signal1, tc)
52421.1Skamil{
52431.1Skamil	atf_tc_set_md_var(tc, "descr",
52441.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
52451.1Skamil	    "from catching other signals");
52461.1Skamil}
52471.1Skamil
52481.1SkamilATF_TC_BODY(signal1, tc)
52491.1Skamil{
52501.1Skamil	const int exitval = 5;
52511.1Skamil	const int sigval = SIGSTOP;
52521.1Skamil	const int sigmasked = SIGTRAP;
52531.1Skamil	const int signotmasked = SIGINT;
52541.1Skamil	pid_t child, wpid;
52551.1Skamil#if defined(TWAIT_HAVE_STATUS)
52561.1Skamil	int status;
52571.1Skamil#endif
52581.1Skamil	sigset_t intmask;
52591.1Skamil
52601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52621.1Skamil	if (child == 0) {
52631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52651.1Skamil
52661.1Skamil		sigemptyset(&intmask);
52671.1Skamil		sigaddset(&intmask, sigmasked);
52681.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
52691.1Skamil
52701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52721.1Skamil
52731.13Schristos		DPRINTF("Before raising %s from child\n",
52741.1Skamil		    strsignal(signotmasked));
52751.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
52761.1Skamil
52771.13Schristos		DPRINTF("Before exiting of the child process\n");
52781.1Skamil		_exit(exitval);
52791.1Skamil	}
52801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52811.1Skamil
52821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52841.1Skamil
52851.1Skamil	validate_status_stopped(status, sigval);
52861.1Skamil
52871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52881.1Skamil	    "without signal to be sent\n");
52891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52901.1Skamil
52911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52931.1Skamil
52941.1Skamil	validate_status_stopped(status, signotmasked);
52951.1Skamil
52961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52971.1Skamil	    "without signal to be sent\n");
52981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52991.1Skamil
53001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53021.1Skamil
53031.1Skamil	validate_status_exited(status, exitval);
53041.1Skamil
53051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53071.1Skamil}
53081.1Skamil
53091.1SkamilATF_TC(signal2);
53101.1SkamilATF_TC_HEAD(signal2, tc)
53111.1Skamil{
53121.1Skamil	atf_tc_set_md_var(tc, "descr",
53131.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
53141.1Skamil	    "catching this raised signal");
53151.1Skamil}
53161.1Skamil
53171.1SkamilATF_TC_BODY(signal2, tc)
53181.1Skamil{
53191.1Skamil	const int exitval = 5;
53201.1Skamil	const int sigval = SIGSTOP;
53211.1Skamil	const int sigmasked = SIGTRAP;
53221.1Skamil	pid_t child, wpid;
53231.1Skamil#if defined(TWAIT_HAVE_STATUS)
53241.1Skamil	int status;
53251.1Skamil#endif
53261.1Skamil	sigset_t intmask;
53271.1Skamil
53281.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53291.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53301.1Skamil	if (child == 0) {
53311.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53321.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53331.1Skamil
53341.1Skamil		sigemptyset(&intmask);
53351.1Skamil		sigaddset(&intmask, sigmasked);
53361.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
53371.1Skamil
53381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53401.1Skamil
53411.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
53421.1Skamil		    strsignal(sigmasked));
53431.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
53441.1Skamil
53451.13Schristos		DPRINTF("Before exiting of the child process\n");
53461.1Skamil		_exit(exitval);
53471.1Skamil	}
53481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53491.1Skamil
53501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53521.1Skamil
53531.1Skamil	validate_status_stopped(status, sigval);
53541.1Skamil
53551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53561.1Skamil	    "without signal to be sent\n");
53571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53581.1Skamil
53591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53611.1Skamil
53621.1Skamil	validate_status_exited(status, exitval);
53631.1Skamil
53641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53661.1Skamil}
53671.1Skamil
53681.1SkamilATF_TC(signal3);
53691.1SkamilATF_TC_HEAD(signal3, tc)
53701.1Skamil{
53711.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
53721.1Skamil	atf_tc_set_md_var(tc, "descr",
53731.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
53741.1Skamil	    "catching software breakpoints");
53751.1Skamil}
53761.1Skamil
53771.1SkamilATF_TC_BODY(signal3, tc)
53781.1Skamil{
53791.1Skamil	const int exitval = 5;
53801.1Skamil	const int sigval = SIGSTOP;
53811.1Skamil	const int sigmasked = SIGTRAP;
53821.1Skamil	pid_t child, wpid;
53831.1Skamil#if defined(TWAIT_HAVE_STATUS)
53841.1Skamil	int status;
53851.1Skamil#endif
53861.1Skamil	sigset_t intmask;
53871.1Skamil
53881.20Skamil	atf_tc_expect_fail("PR kern/51918");
53891.20Skamil
53901.20Skamil	// This test breaks now on some ports, temporarily disable it
53911.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
53921.20Skamil
53931.10Smartin#if defined(__sparc__)
53941.7Skamil	atf_tc_expect_timeout("PR kern/52167");
53951.7Skamil
53961.7Skamil	// timeout wins, failure still valid
53971.7Skamil	// atf_tc_expect_fail("PR kern/51918");
53981.7Skamil#endif
53991.1Skamil
54001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54021.1Skamil	if (child == 0) {
54031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54051.1Skamil
54061.1Skamil		sigemptyset(&intmask);
54071.1Skamil		sigaddset(&intmask, sigmasked);
54081.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
54091.1Skamil
54101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54121.1Skamil
54131.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
54141.4Skamil
54151.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
54161.4Skamil		PTRACE_BREAKPOINT_ASM;
54171.1Skamil#else
54181.4Skamil		/* port me */
54191.1Skamil#endif
54201.1Skamil
54211.13Schristos		DPRINTF("Before exiting of the child process\n");
54221.1Skamil		_exit(exitval);
54231.1Skamil	}
54241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54251.1Skamil
54261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54281.1Skamil
54291.1Skamil	validate_status_stopped(status, sigval);
54301.1Skamil
54311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54321.1Skamil	    "without signal to be sent\n");
54331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54341.1Skamil
54351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54371.1Skamil
54381.1Skamil	validate_status_stopped(status, sigmasked);
54391.1Skamil
54401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54411.1Skamil	    "without signal to be sent\n");
54421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54431.1Skamil
54441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54461.1Skamil
54471.1Skamil	validate_status_exited(status, exitval);
54481.1Skamil
54491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54511.1Skamil}
54521.1Skamil
54531.1Skamil#if defined(PT_STEP)
54541.1SkamilATF_TC(signal4);
54551.1SkamilATF_TC_HEAD(signal4, tc)
54561.1Skamil{
54571.1Skamil	atf_tc_set_md_var(tc, "descr",
54581.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
54591.1Skamil	    "catching single step trap");
54601.1Skamil}
54611.1Skamil
54621.1SkamilATF_TC_BODY(signal4, tc)
54631.1Skamil{
54641.1Skamil	const int exitval = 5;
54651.1Skamil	const int sigval = SIGSTOP;
54661.1Skamil	const int sigmasked = SIGTRAP;
54671.1Skamil	pid_t child, wpid;
54681.1Skamil#if defined(TWAIT_HAVE_STATUS)
54691.1Skamil	int status;
54701.1Skamil#endif
54711.1Skamil	sigset_t intmask;
54721.1Skamil	int happy;
54731.1Skamil
54741.1Skamil#if defined(__arm__)
54751.5Skamil	/* PT_STEP not supported on arm 32-bit */
54761.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
54771.1Skamil#endif
54781.1Skamil
54791.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54801.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54811.1Skamil	if (child == 0) {
54821.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54831.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54841.1Skamil
54851.1Skamil		happy = check_happy(100);
54861.1Skamil
54871.1Skamil		sigemptyset(&intmask);
54881.1Skamil		sigaddset(&intmask, sigmasked);
54891.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
54901.1Skamil
54911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54931.1Skamil
54941.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
54951.1Skamil
54961.13Schristos		DPRINTF("Before exiting of the child process\n");
54971.1Skamil		_exit(exitval);
54981.1Skamil	}
54991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55001.1Skamil
55011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55031.1Skamil
55041.1Skamil	validate_status_stopped(status, sigval);
55051.1Skamil
55061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55071.1Skamil	    "without signal to be sent\n");
55081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
55091.1Skamil
55101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55121.1Skamil
55131.1Skamil	validate_status_stopped(status, sigmasked);
55141.1Skamil
55151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55161.1Skamil	    "without signal to be sent\n");
55171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55181.1Skamil
55191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55211.1Skamil
55221.1Skamil	validate_status_exited(status, exitval);
55231.1Skamil
55241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55261.1Skamil}
55271.1Skamil#endif
55281.1Skamil
55291.1SkamilATF_TC(signal5);
55301.1SkamilATF_TC_HEAD(signal5, tc)
55311.1Skamil{
55321.1Skamil	atf_tc_set_md_var(tc, "descr",
55331.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55341.1Skamil	    "catching exec() breakpoint");
55351.1Skamil}
55361.1Skamil
55371.1SkamilATF_TC_BODY(signal5, tc)
55381.1Skamil{
55391.1Skamil	const int exitval = 5;
55401.1Skamil	const int sigval = SIGSTOP;
55411.1Skamil	const int sigmasked = SIGTRAP;
55421.1Skamil	pid_t child, wpid;
55431.1Skamil#if defined(TWAIT_HAVE_STATUS)
55441.1Skamil	int status;
55451.1Skamil#endif
55461.1Skamil	sigset_t intmask;
55471.1Skamil
55481.14Schristos	atf_tc_expect_fail("wrong signal");
55491.14Schristos
55501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55521.1Skamil	if (child == 0) {
55531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55551.1Skamil
55561.1Skamil		sigemptyset(&intmask);
55571.1Skamil		sigaddset(&intmask, sigmasked);
55581.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55591.1Skamil
55601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55621.1Skamil
55631.13Schristos		DPRINTF("Before calling execve(2) from child\n");
55641.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
55651.1Skamil
55661.13Schristos		DPRINTF("Before exiting of the child process\n");
55671.1Skamil		_exit(exitval);
55681.1Skamil	}
55691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55701.1Skamil
55711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55731.1Skamil
55741.1Skamil	validate_status_stopped(status, sigval);
55751.1Skamil
55761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55771.1Skamil	    "without signal to be sent\n");
55781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55791.1Skamil
55801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55821.1Skamil
55831.1Skamil	validate_status_stopped(status, sigmasked);
55841.1Skamil
55851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55861.1Skamil	    "without signal to be sent\n");
55871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55881.1Skamil
55891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55911.1Skamil
55921.1Skamil	validate_status_exited(status, exitval);
55931.1Skamil
55941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55961.1Skamil}
55971.1Skamil
55981.1Skamil#if defined(TWAIT_HAVE_PID)
55991.1SkamilATF_TC(signal6);
56001.1SkamilATF_TC_HEAD(signal6, tc)
56011.1Skamil{
56021.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
56031.1Skamil	atf_tc_set_md_var(tc, "descr",
56041.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
56051.1Skamil	    "catching PTRACE_FORK breakpoint");
56061.1Skamil}
56071.1Skamil
56081.1SkamilATF_TC_BODY(signal6, tc)
56091.1Skamil{
56101.1Skamil	const int exitval = 5;
56111.1Skamil	const int exitval2 = 15;
56121.1Skamil	const int sigval = SIGSTOP;
56131.1Skamil	const int sigmasked = SIGTRAP;
56141.1Skamil	pid_t child, child2, wpid;
56151.1Skamil#if defined(TWAIT_HAVE_STATUS)
56161.1Skamil	int status;
56171.1Skamil#endif
56181.1Skamil	sigset_t intmask;
56191.1Skamil	ptrace_state_t state;
56201.1Skamil	const int slen = sizeof(state);
56211.1Skamil	ptrace_event_t event;
56221.1Skamil	const int elen = sizeof(event);
56231.1Skamil
56241.14Schristos	atf_tc_expect_timeout("PR kern/51918");
56251.14Schristos
56261.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56271.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56281.1Skamil	if (child == 0) {
56291.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56301.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56311.1Skamil
56321.1Skamil		sigemptyset(&intmask);
56331.1Skamil		sigaddset(&intmask, sigmasked);
56341.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56351.1Skamil
56361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56381.1Skamil
56391.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
56401.1Skamil
56411.1Skamil		if (child2 == 0)
56421.1Skamil			_exit(exitval2);
56431.1Skamil
56441.1Skamil		FORKEE_REQUIRE_SUCCESS
56451.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
56461.1Skamil
56471.1Skamil		forkee_status_exited(status, exitval2);
56481.1Skamil
56491.13Schristos		DPRINTF("Before exiting of the child process\n");
56501.1Skamil		_exit(exitval);
56511.1Skamil	}
56521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56531.1Skamil
56541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56561.1Skamil
56571.1Skamil	validate_status_stopped(status, sigval);
56581.1Skamil
56591.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
56601.1Skamil	event.pe_set_event = PTRACE_FORK;
56611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
56621.1Skamil
56631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56641.1Skamil	    "without signal to be sent\n");
56651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56661.1Skamil
56671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56691.1Skamil
56701.1Skamil	validate_status_stopped(status, sigmasked);
56711.1Skamil
56721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
56731.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
56741.1Skamil
56751.1Skamil	child2 = state.pe_other_pid;
56761.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
56771.1Skamil
56781.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
56791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
56801.1Skamil	    child2);
56811.1Skamil
56821.1Skamil	validate_status_stopped(status, SIGTRAP);
56831.1Skamil
56841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
56851.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
56861.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
56871.1Skamil
56881.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
56891.1Skamil	    "without signal to be sent\n");
56901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
56911.1Skamil
56921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56931.1Skamil	    "without signal to be sent\n");
56941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56951.1Skamil
56961.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
56971.1Skamil	    TWAIT_FNAME);
56981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
56991.1Skamil	    child2);
57001.1Skamil
57011.1Skamil	validate_status_exited(status, exitval2);
57021.1Skamil
57031.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
57041.1Skamil	    TWAIT_FNAME);
57051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
57061.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
57071.1Skamil
57081.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
57091.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
57101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57111.1Skamil
57121.1Skamil	validate_status_stopped(status, SIGCHLD);
57131.1Skamil
57141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57151.1Skamil	    "without signal to be sent\n");
57161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57171.1Skamil
57181.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
57191.1Skamil	    TWAIT_FNAME);
57201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57211.1Skamil
57221.1Skamil	validate_status_exited(status, exitval);
57231.1Skamil
57241.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
57251.1Skamil	    TWAIT_FNAME);
57261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57271.1Skamil}
57281.1Skamil#endif
57291.1Skamil
57301.1Skamil#if defined(TWAIT_HAVE_PID)
57311.1SkamilATF_TC(signal7);
57321.1SkamilATF_TC_HEAD(signal7, tc)
57331.1Skamil{
57341.1Skamil	atf_tc_set_md_var(tc, "descr",
57351.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57361.1Skamil	    "catching PTRACE_VFORK breakpoint");
57371.1Skamil}
57381.1Skamil
57391.1SkamilATF_TC_BODY(signal7, tc)
57401.1Skamil{
57411.1Skamil	const int exitval = 5;
57421.1Skamil	const int exitval2 = 15;
57431.1Skamil	const int sigval = SIGSTOP;
57441.1Skamil	const int sigmasked = SIGTRAP;
57451.1Skamil	pid_t child, child2, wpid;
57461.1Skamil#if defined(TWAIT_HAVE_STATUS)
57471.1Skamil	int status;
57481.1Skamil#endif
57491.1Skamil	sigset_t intmask;
57501.1Skamil	ptrace_state_t state;
57511.1Skamil	const int slen = sizeof(state);
57521.1Skamil	ptrace_event_t event;
57531.1Skamil	const int elen = sizeof(event);
57541.1Skamil
57551.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
57561.14Schristos
57571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57591.1Skamil	if (child == 0) {
57601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57621.1Skamil
57631.1Skamil		sigemptyset(&intmask);
57641.1Skamil		sigaddset(&intmask, sigmasked);
57651.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57661.1Skamil
57671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57691.1Skamil
57701.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
57711.1Skamil
57721.1Skamil		if (child2 == 0)
57731.1Skamil			_exit(exitval2);
57741.1Skamil
57751.1Skamil		FORKEE_REQUIRE_SUCCESS
57761.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
57771.1Skamil
57781.1Skamil		forkee_status_exited(status, exitval2);
57791.1Skamil
57801.13Schristos		DPRINTF("Before exiting of the child process\n");
57811.1Skamil		_exit(exitval);
57821.1Skamil	}
57831.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57841.1Skamil
57851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57871.1Skamil
57881.1Skamil	validate_status_stopped(status, sigval);
57891.1Skamil
57901.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
57911.1Skamil	event.pe_set_event = PTRACE_VFORK;
57921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
57931.1Skamil
57941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57951.1Skamil	    "without signal to be sent\n");
57961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57971.1Skamil
57981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58001.1Skamil
58011.1Skamil	validate_status_stopped(status, sigmasked);
58021.1Skamil
58031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
58041.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
58051.1Skamil
58061.1Skamil	child2 = state.pe_other_pid;
58071.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
58081.1Skamil
58091.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
58101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58111.1Skamil	    child2);
58121.1Skamil
58131.1Skamil	validate_status_stopped(status, SIGTRAP);
58141.1Skamil
58151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
58161.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
58171.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
58181.1Skamil
58191.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
58201.1Skamil	    "without signal to be sent\n");
58211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
58221.1Skamil
58231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58241.1Skamil	    "without signal to be sent\n");
58251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58261.1Skamil
58271.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
58281.1Skamil	    TWAIT_FNAME);
58291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58301.1Skamil	    child2);
58311.1Skamil
58321.1Skamil	validate_status_exited(status, exitval2);
58331.1Skamil
58341.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
58351.1Skamil	    TWAIT_FNAME);
58361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
58371.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
58381.1Skamil
58391.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
58401.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
58411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58421.1Skamil
58431.1Skamil	validate_status_stopped(status, SIGCHLD);
58441.1Skamil
58451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58461.1Skamil	    "without signal to be sent\n");
58471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58481.1Skamil
58491.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
58501.1Skamil	    TWAIT_FNAME);
58511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58521.1Skamil
58531.1Skamil	validate_status_exited(status, exitval);
58541.1Skamil
58551.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
58561.1Skamil	    TWAIT_FNAME);
58571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58581.1Skamil}
58591.1Skamil#endif
58601.1Skamil
58611.1SkamilATF_TC(signal8);
58621.1SkamilATF_TC_HEAD(signal8, tc)
58631.1Skamil{
58641.1Skamil	atf_tc_set_md_var(tc, "descr",
58651.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58661.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
58671.1Skamil}
58681.1Skamil
58691.1SkamilATF_TC_BODY(signal8, tc)
58701.1Skamil{
58711.1Skamil	const int exitval = 5;
58721.1Skamil	const int exitval2 = 15;
58731.1Skamil	const int sigval = SIGSTOP;
58741.1Skamil	const int sigmasked = SIGTRAP;
58751.1Skamil	pid_t child, child2, wpid;
58761.1Skamil#if defined(TWAIT_HAVE_STATUS)
58771.1Skamil	int status;
58781.1Skamil#endif
58791.1Skamil	sigset_t intmask;
58801.1Skamil	ptrace_state_t state;
58811.1Skamil	const int slen = sizeof(state);
58821.1Skamil	ptrace_event_t event;
58831.1Skamil	const int elen = sizeof(event);
58841.1Skamil
58851.14Schristos	atf_tc_expect_fail("PR kern/51918");
58861.14Schristos
58871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58891.1Skamil	if (child == 0) {
58901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58921.1Skamil
58931.1Skamil		sigemptyset(&intmask);
58941.1Skamil		sigaddset(&intmask, sigmasked);
58951.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58961.1Skamil
58971.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58981.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58991.1Skamil
59001.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
59011.1Skamil
59021.1Skamil		if (child2 == 0)
59031.1Skamil			_exit(exitval2);
59041.1Skamil
59051.1Skamil		FORKEE_REQUIRE_SUCCESS
59061.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
59071.1Skamil
59081.1Skamil		forkee_status_exited(status, exitval2);
59091.1Skamil
59101.13Schristos		DPRINTF("Before exiting of the child process\n");
59111.1Skamil		_exit(exitval);
59121.1Skamil	}
59131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59141.1Skamil
59151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59171.1Skamil
59181.1Skamil	validate_status_stopped(status, sigval);
59191.1Skamil
59201.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
59211.1Skamil	    child);
59221.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
59231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
59241.1Skamil
59251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59261.1Skamil	    "without signal to be sent\n");
59271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59281.1Skamil
59291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59311.1Skamil
59321.1Skamil	validate_status_stopped(status, sigmasked);
59331.1Skamil
59341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
59351.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
59361.1Skamil
59371.1Skamil	child2 = state.pe_other_pid;
59381.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
59391.1Skamil
59401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59411.1Skamil	    "without signal to be sent\n");
59421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59431.1Skamil
59441.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
59451.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
59461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59471.1Skamil
59481.1Skamil	validate_status_stopped(status, SIGCHLD);
59491.1Skamil
59501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59511.1Skamil	    "without signal to be sent\n");
59521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59531.1Skamil
59541.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
59551.1Skamil	    TWAIT_FNAME);
59561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59571.1Skamil
59581.1Skamil	validate_status_exited(status, exitval);
59591.1Skamil
59601.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
59611.1Skamil	    TWAIT_FNAME);
59621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59631.1Skamil}
59641.1Skamil
59651.1SkamilATF_TC(signal9);
59661.1SkamilATF_TC_HEAD(signal9, tc)
59671.1Skamil{
59681.1Skamil	atf_tc_set_md_var(tc, "descr",
59691.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59701.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
59711.1Skamil}
59721.1Skamil
59731.1SkamilATF_TC_BODY(signal9, tc)
59741.1Skamil{
59751.1Skamil	const int exitval = 5;
59761.1Skamil	const int sigval = SIGSTOP;
59771.1Skamil	const int sigmasked = SIGTRAP;
59781.1Skamil	pid_t child, wpid;
59791.1Skamil#if defined(TWAIT_HAVE_STATUS)
59801.1Skamil	int status;
59811.1Skamil#endif
59821.1Skamil	sigset_t intmask;
59831.1Skamil	ptrace_state_t state;
59841.1Skamil	const int slen = sizeof(state);
59851.1Skamil	ptrace_event_t event;
59861.1Skamil	const int elen = sizeof(event);
59871.1Skamil	ucontext_t uc;
59881.1Skamil	lwpid_t lid;
59891.1Skamil	static const size_t ssize = 16*1024;
59901.1Skamil	void *stack;
59911.1Skamil
59921.14Schristos	atf_tc_expect_fail("PR kern/51918");
59931.14Schristos
59941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59961.1Skamil	if (child == 0) {
59971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59991.1Skamil
60001.1Skamil		sigemptyset(&intmask);
60011.1Skamil		sigaddset(&intmask, sigmasked);
60021.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60031.1Skamil
60041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60061.1Skamil
60071.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
60081.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
60091.1Skamil
60101.13Schristos		DPRINTF("Before making context for new lwp in child\n");
60111.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
60121.1Skamil
60131.13Schristos		DPRINTF("Before creating new in child\n");
60141.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
60151.1Skamil
60161.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
60171.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
60181.1Skamil
60191.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
60201.1Skamil		    "are the same\n", lid, the_lwp_id);
60211.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
60221.1Skamil
60231.13Schristos		DPRINTF("Before exiting of the child process\n");
60241.1Skamil		_exit(exitval);
60251.1Skamil	}
60261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60271.1Skamil
60281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60301.1Skamil
60311.1Skamil	validate_status_stopped(status, sigval);
60321.1Skamil
60331.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
60341.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
60351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60361.1Skamil
60371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60381.1Skamil	    "without signal to be sent\n");
60391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60401.1Skamil
60411.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60421.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
60431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60441.1Skamil
60451.1Skamil	validate_status_stopped(status, sigmasked);
60461.1Skamil
60471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60481.1Skamil
60491.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
60501.1Skamil
60511.1Skamil	lid = state.pe_lwp;
60521.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
60531.1Skamil
60541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60551.1Skamil	    "without signal to be sent\n");
60561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60571.1Skamil
60581.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60591.1Skamil	    TWAIT_FNAME);
60601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60611.1Skamil
60621.1Skamil	validate_status_exited(status, exitval);
60631.1Skamil
60641.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60651.1Skamil	    TWAIT_FNAME);
60661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60671.1Skamil}
60681.1Skamil
60691.1SkamilATF_TC(signal10);
60701.1SkamilATF_TC_HEAD(signal10, tc)
60711.1Skamil{
60721.1Skamil	atf_tc_set_md_var(tc, "descr",
60731.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
60741.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
60751.1Skamil}
60761.1Skamil
60771.1SkamilATF_TC_BODY(signal10, tc)
60781.1Skamil{
60791.1Skamil	const int exitval = 5;
60801.1Skamil	const int sigval = SIGSTOP;
60811.1Skamil	const int sigmasked = SIGTRAP;
60821.1Skamil	pid_t child, wpid;
60831.1Skamil#if defined(TWAIT_HAVE_STATUS)
60841.1Skamil	int status;
60851.1Skamil#endif
60861.1Skamil	sigset_t intmask;
60871.1Skamil	ptrace_state_t state;
60881.1Skamil	const int slen = sizeof(state);
60891.1Skamil	ptrace_event_t event;
60901.1Skamil	const int elen = sizeof(event);
60911.1Skamil	ucontext_t uc;
60921.1Skamil	lwpid_t lid;
60931.1Skamil	static const size_t ssize = 16*1024;
60941.1Skamil	void *stack;
60951.1Skamil
60961.14Schristos	atf_tc_expect_fail("PR kern/51918");
60971.14Schristos
60981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61001.1Skamil	if (child == 0) {
61011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61031.1Skamil
61041.1Skamil		sigemptyset(&intmask);
61051.1Skamil		sigaddset(&intmask, sigmasked);
61061.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61071.1Skamil
61081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61101.1Skamil
61111.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
61121.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
61131.1Skamil
61141.13Schristos		DPRINTF("Before making context for new lwp in child\n");
61151.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
61161.1Skamil
61171.13Schristos		DPRINTF("Before creating new in child\n");
61181.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
61191.1Skamil
61201.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
61211.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
61221.1Skamil
61231.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
61241.1Skamil		    "are the same\n", lid, the_lwp_id);
61251.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
61261.1Skamil
61271.13Schristos		DPRINTF("Before exiting of the child process\n");
61281.1Skamil		_exit(exitval);
61291.1Skamil	}
61301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61311.1Skamil
61321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61341.1Skamil
61351.1Skamil	validate_status_stopped(status, sigval);
61361.1Skamil
61371.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
61381.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
61391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
61401.1Skamil
61411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61421.1Skamil	    "without signal to be sent\n");
61431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61441.1Skamil
61451.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61461.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
61471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61481.1Skamil
61491.1Skamil	validate_status_stopped(status, sigmasked);
61501.1Skamil
61511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61521.1Skamil
61531.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
61541.1Skamil
61551.1Skamil	lid = state.pe_lwp;
61561.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
61571.1Skamil
61581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61591.1Skamil	    "without signal to be sent\n");
61601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61611.1Skamil
61621.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61631.1Skamil	    TWAIT_FNAME);
61641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61651.1Skamil
61661.1Skamil	validate_status_exited(status, exitval);
61671.1Skamil
61681.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61691.1Skamil	    TWAIT_FNAME);
61701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61711.1Skamil}
61721.1Skamil
61731.1Skamilstatic void
61741.1Skamillwp_main_stop(void *arg)
61751.1Skamil{
61761.1Skamil	the_lwp_id = _lwp_self();
61771.1Skamil
61781.1Skamil	raise(SIGTRAP);
61791.1Skamil
61801.1Skamil	_lwp_exit();
61811.1Skamil}
61821.1Skamil
61831.1SkamilATF_TC(suspend1);
61841.1SkamilATF_TC_HEAD(suspend1, tc)
61851.1Skamil{
61861.1Skamil	atf_tc_set_md_var(tc, "descr",
61871.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
61881.1Skamil	    "resumed by a tracee");
61891.1Skamil}
61901.1Skamil
61911.1SkamilATF_TC_BODY(suspend1, tc)
61921.1Skamil{
61931.1Skamil	const int exitval = 5;
61941.1Skamil	const int sigval = SIGSTOP;
61951.1Skamil	pid_t child, wpid;
61961.1Skamil#if defined(TWAIT_HAVE_STATUS)
61971.1Skamil	int status;
61981.1Skamil#endif
61991.1Skamil	ucontext_t uc;
62001.1Skamil	lwpid_t lid;
62011.1Skamil	static const size_t ssize = 16*1024;
62021.1Skamil	void *stack;
62031.1Skamil	struct ptrace_lwpinfo pl;
62041.1Skamil	struct ptrace_siginfo psi;
62051.1Skamil	volatile int go = 0;
62061.1Skamil
62071.17Skamil	// Feature pending for refactoring
62081.17Skamil	atf_tc_expect_fail("PR kern/51995");
62091.17Skamil
62101.16Skamil	// Hangs with qemu
62111.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
62121.16Skamil
62131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62151.1Skamil	if (child == 0) {
62161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62181.1Skamil
62191.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62201.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62211.1Skamil
62221.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
62231.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
62241.1Skamil
62251.13Schristos		DPRINTF("Before making context for new lwp in child\n");
62261.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
62271.1Skamil
62281.13Schristos		DPRINTF("Before creating new in child\n");
62291.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
62301.1Skamil
62311.1Skamil		while (go == 0)
62321.1Skamil			continue;
62331.1Skamil
62341.1Skamil		raise(SIGINT);
62351.1Skamil
62361.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
62371.1Skamil
62381.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
62391.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
62401.1Skamil
62411.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
62421.1Skamil		    "are the same\n", lid, the_lwp_id);
62431.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
62441.1Skamil
62451.13Schristos		DPRINTF("Before exiting of the child process\n");
62461.1Skamil		_exit(exitval);
62471.1Skamil	}
62481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62491.1Skamil
62501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62521.1Skamil
62531.1Skamil	validate_status_stopped(status, sigval);
62541.1Skamil
62551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62561.1Skamil	    "without signal to be sent\n");
62571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62581.1Skamil
62591.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62601.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
62611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62621.1Skamil
62631.1Skamil	validate_status_stopped(status, SIGTRAP);
62641.1Skamil
62651.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
62661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
62671.1Skamil
62681.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
62691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
62701.1Skamil
62711.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
62721.1Skamil	    child, getpid());
62731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
62741.1Skamil
62751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62761.1Skamil	    "without signal to be sent\n");
62771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62781.1Skamil
62791.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62801.1Skamil	    "SIGINT\n", TWAIT_FNAME);
62811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62821.1Skamil
62831.1Skamil	validate_status_stopped(status, SIGINT);
62841.1Skamil
62851.1Skamil	pl.pl_lwpid = 0;
62861.1Skamil
62871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
62881.1Skamil	while (pl.pl_lwpid != 0) {
62891.1Skamil
62901.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
62911.1Skamil		switch (pl.pl_lwpid) {
62921.1Skamil		case 1:
62931.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
62941.1Skamil			break;
62951.1Skamil		case 2:
62961.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
62971.1Skamil			break;
62981.1Skamil		}
62991.1Skamil	}
63001.1Skamil
63011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63021.1Skamil	    "without signal to be sent\n");
63031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63041.1Skamil
63051.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63061.1Skamil	    TWAIT_FNAME);
63071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63081.1Skamil
63091.1Skamil	validate_status_exited(status, exitval);
63101.1Skamil
63111.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63121.1Skamil	    TWAIT_FNAME);
63131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63141.1Skamil}
63151.1Skamil
63161.1SkamilATF_TC(suspend2);
63171.1SkamilATF_TC_HEAD(suspend2, tc)
63181.1Skamil{
63191.1Skamil	atf_tc_set_md_var(tc, "descr",
63201.1Skamil	    "Verify that the while the only thread within a process is "
63211.1Skamil	    "suspended, the whole process cannot be unstopped");
63221.1Skamil}
63231.1Skamil
63241.1SkamilATF_TC_BODY(suspend2, tc)
63251.1Skamil{
63261.1Skamil	const int exitval = 5;
63271.1Skamil	const int sigval = SIGSTOP;
63281.1Skamil	pid_t child, wpid;
63291.1Skamil#if defined(TWAIT_HAVE_STATUS)
63301.1Skamil	int status;
63311.1Skamil#endif
63321.1Skamil	struct ptrace_siginfo psi;
63331.1Skamil
63341.17Skamil	// Feature pending for refactoring
63351.17Skamil	atf_tc_expect_fail("PR kern/51995");
63361.17Skamil
63371.16Skamil	// Hangs with qemu
63381.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
63391.16Skamil
63401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63421.1Skamil	if (child == 0) {
63431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63451.1Skamil
63461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63481.1Skamil
63491.13Schristos		DPRINTF("Before exiting of the child process\n");
63501.1Skamil		_exit(exitval);
63511.1Skamil	}
63521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63531.1Skamil
63541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63561.1Skamil
63571.1Skamil	validate_status_stopped(status, sigval);
63581.1Skamil
63591.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
63601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
63611.1Skamil
63621.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
63631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
63641.1Skamil
63651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63661.1Skamil	    "without signal to be sent\n");
63671.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
63681.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
63691.1Skamil
63701.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
63711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
63721.1Skamil
63731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63741.1Skamil	    "without signal to be sent\n");
63751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63761.1Skamil
63771.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63781.1Skamil	    TWAIT_FNAME);
63791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63801.1Skamil
63811.1Skamil	validate_status_exited(status, exitval);
63821.1Skamil
63831.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63841.1Skamil	    TWAIT_FNAME);
63851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63861.1Skamil}
63871.1Skamil
63881.1SkamilATF_TC(resume1);
63891.1SkamilATF_TC_HEAD(resume1, tc)
63901.1Skamil{
63911.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
63921.1Skamil	atf_tc_set_md_var(tc, "descr",
63931.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
63941.1Skamil	    "resumed by the debugger");
63951.1Skamil}
63961.1Skamil
63971.1SkamilATF_TC_BODY(resume1, tc)
63981.1Skamil{
63991.1Skamil	struct msg_fds fds;
64001.1Skamil	const int exitval = 5;
64011.1Skamil	const int sigval = SIGSTOP;
64021.1Skamil	pid_t child, wpid;
64031.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
64041.1Skamil#if defined(TWAIT_HAVE_STATUS)
64051.1Skamil	int status;
64061.1Skamil#endif
64071.1Skamil	ucontext_t uc;
64081.1Skamil	lwpid_t lid;
64091.1Skamil	static const size_t ssize = 16*1024;
64101.1Skamil	void *stack;
64111.1Skamil	struct ptrace_lwpinfo pl;
64121.1Skamil	struct ptrace_siginfo psi;
64131.1Skamil
64141.17Skamil	// Feature pending for refactoring
64151.17Skamil	atf_tc_expect_fail("PR kern/51995");
64161.17Skamil
64171.15Schristos	// Hangs with qemu
64181.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
64191.1Skamil
64201.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
64211.1Skamil
64221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64241.1Skamil	if (child == 0) {
64251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64271.1Skamil
64281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64301.1Skamil
64311.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64321.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64331.1Skamil
64341.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64351.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
64361.1Skamil
64371.13Schristos		DPRINTF("Before creating new in child\n");
64381.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64391.1Skamil
64401.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
64411.1Skamil
64421.1Skamil		raise(SIGINT);
64431.1Skamil
64441.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64451.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64461.1Skamil
64471.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64481.1Skamil		    "are the same\n", lid, the_lwp_id);
64491.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64501.1Skamil
64511.13Schristos		DPRINTF("Before exiting of the child process\n");
64521.1Skamil		_exit(exitval);
64531.1Skamil	}
64541.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64551.1Skamil
64561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64581.1Skamil
64591.1Skamil	validate_status_stopped(status, sigval);
64601.1Skamil
64611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64621.1Skamil	    "without signal to be sent\n");
64631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64641.1Skamil
64651.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64661.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64681.1Skamil
64691.1Skamil	validate_status_stopped(status, SIGTRAP);
64701.1Skamil
64711.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
64721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
64731.1Skamil
64741.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
64751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
64761.1Skamil
64771.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
64781.1Skamil
64791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64801.1Skamil	    "without signal to be sent\n");
64811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64821.1Skamil
64831.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64841.1Skamil	    "SIGINT\n", TWAIT_FNAME);
64851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64861.1Skamil
64871.1Skamil	validate_status_stopped(status, SIGINT);
64881.1Skamil
64891.1Skamil	pl.pl_lwpid = 0;
64901.1Skamil
64911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
64921.1Skamil	while (pl.pl_lwpid != 0) {
64931.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
64941.1Skamil		switch (pl.pl_lwpid) {
64951.1Skamil		case 1:
64961.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
64971.1Skamil			break;
64981.1Skamil		case 2:
64991.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
65001.1Skamil			break;
65011.1Skamil		}
65021.1Skamil	}
65031.1Skamil
65041.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
65051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
65061.1Skamil
65071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65081.1Skamil	    "without signal to be sent\n");
65091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65101.1Skamil
65111.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65121.1Skamil	    TWAIT_FNAME);
65131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65141.1Skamil
65151.1Skamil	validate_status_exited(status, exitval);
65161.1Skamil
65171.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65181.1Skamil	    TWAIT_FNAME);
65191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65201.1Skamil
65211.1Skamil	msg_close(&fds);
65221.1Skamil
65231.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
65241.1Skamil	sleep(10);
65251.1Skamil}
65261.1Skamil
65271.1SkamilATF_TC(syscall1);
65281.1SkamilATF_TC_HEAD(syscall1, tc)
65291.1Skamil{
65301.1Skamil	atf_tc_set_md_var(tc, "descr",
65311.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
65321.1Skamil}
65331.1Skamil
65341.1SkamilATF_TC_BODY(syscall1, tc)
65351.1Skamil{
65361.1Skamil	const int exitval = 5;
65371.1Skamil	const int sigval = SIGSTOP;
65381.1Skamil	pid_t child, wpid;
65391.1Skamil#if defined(TWAIT_HAVE_STATUS)
65401.1Skamil	int status;
65411.1Skamil#endif
65421.1Skamil	struct ptrace_siginfo info;
65431.1Skamil	memset(&info, 0, sizeof(info));
65441.1Skamil
65451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65471.1Skamil	if (child == 0) {
65481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65501.1Skamil
65511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65531.1Skamil
65541.1Skamil		syscall(SYS_getpid);
65551.1Skamil
65561.13Schristos		DPRINTF("Before exiting of the child process\n");
65571.1Skamil		_exit(exitval);
65581.1Skamil	}
65591.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65601.1Skamil
65611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65631.1Skamil
65641.1Skamil	validate_status_stopped(status, sigval);
65651.1Skamil
65661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65671.1Skamil	    "without signal to be sent\n");
65681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
65691.1Skamil
65701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65721.1Skamil
65731.1Skamil	validate_status_stopped(status, SIGTRAP);
65741.1Skamil
65751.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
65761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
65771.1Skamil
65781.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
65791.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
65801.1Skamil
65811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65821.1Skamil	    "without signal to be sent\n");
65831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
65841.1Skamil
65851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65871.1Skamil
65881.1Skamil	validate_status_stopped(status, SIGTRAP);
65891.1Skamil
65901.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
65911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
65921.1Skamil
65931.13Schristos	DPRINTF("Before checking siginfo_t\n");
65941.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
65951.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
65961.1Skamil
65971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65981.1Skamil	    "without signal to be sent\n");
65991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66001.1Skamil
66011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66031.1Skamil
66041.1Skamil	validate_status_exited(status, exitval);
66051.1Skamil
66061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66081.1Skamil}
66091.1Skamil
66101.1SkamilATF_TC(syscallemu1);
66111.1SkamilATF_TC_HEAD(syscallemu1, tc)
66121.1Skamil{
66131.1Skamil	atf_tc_set_md_var(tc, "descr",
66141.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
66151.1Skamil}
66161.1Skamil
66171.1SkamilATF_TC_BODY(syscallemu1, tc)
66181.1Skamil{
66191.1Skamil	const int exitval = 5;
66201.1Skamil	const int sigval = SIGSTOP;
66211.1Skamil	pid_t child, wpid;
66221.1Skamil#if defined(TWAIT_HAVE_STATUS)
66231.1Skamil	int status;
66241.1Skamil#endif
66251.1Skamil
66261.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
66271.6Skamil	/* syscallemu does not work on sparc (32-bit) */
66281.6Skamil	atf_tc_expect_fail("PR kern/52166");
66291.6Skamil#endif
66301.6Skamil
66311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66331.1Skamil	if (child == 0) {
66341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66361.1Skamil
66371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66391.1Skamil
66401.1Skamil		syscall(SYS_exit, 100);
66411.1Skamil
66421.13Schristos		DPRINTF("Before exiting of the child process\n");
66431.1Skamil		_exit(exitval);
66441.1Skamil	}
66451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66461.1Skamil
66471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66491.1Skamil
66501.1Skamil	validate_status_stopped(status, sigval);
66511.1Skamil
66521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66531.1Skamil	    "without signal to be sent\n");
66541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66551.1Skamil
66561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66581.1Skamil
66591.1Skamil	validate_status_stopped(status, SIGTRAP);
66601.1Skamil
66611.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
66621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
66631.1Skamil
66641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66651.1Skamil	    "without signal to be sent\n");
66661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66671.1Skamil
66681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66701.1Skamil
66711.1Skamil	validate_status_stopped(status, SIGTRAP);
66721.1Skamil
66731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66741.1Skamil	    "without signal to be sent\n");
66751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66761.1Skamil
66771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66791.1Skamil
66801.1Skamil	validate_status_exited(status, exitval);
66811.1Skamil
66821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66841.1Skamil}
66851.1Skamil
66861.26Skamil#if defined(TWAIT_HAVE_PID)
66871.26SkamilATF_TC(race1);
66881.26SkamilATF_TC_HEAD(race1, tc)
66891.26Skamil{
66901.26Skamil	atf_tc_set_md_var(tc, "descr",
66911.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
66921.26Skamil	    "process and no other error is reported");
66931.26Skamil}
66941.26Skamil
66951.26SkamilATF_TC_BODY(race1, tc)
66961.26Skamil{
66971.26Skamil	time_t start, end;
66981.26Skamil	double diff;
66991.26Skamil	unsigned long N = 0;
67001.26Skamil
67011.26Skamil	/* Reuse this test with attach1 */
67021.26Skamil
67031.26Skamil	start = time(NULL);
67041.26Skamil	while (true) {
67051.26Skamil		DPRINTF("Step: %lu\n", N);
67061.26Skamil		attach1_raw(true);
67071.26Skamil		end = time(NULL);
67081.26Skamil		diff = difftime(end, start);
67091.26Skamil		if (diff >= 5.0)
67101.26Skamil			break;
67111.26Skamil		++N;
67121.26Skamil	}
67131.26Skamil	DPRINTF("Iterations: %lu\n", N);
67141.26Skamil}
67151.26Skamil#endif
67161.26Skamil
67171.1Skamil#include "t_ptrace_amd64_wait.h"
67181.1Skamil#include "t_ptrace_i386_wait.h"
67191.1Skamil#include "t_ptrace_x86_wait.h"
67201.1Skamil
67211.1SkamilATF_TP_ADD_TCS(tp)
67221.1Skamil{
67231.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
67241.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
67251.33Skamil
67261.33Skamil//	ATF_TP_ADD_TC(tp, traceme_raise1); // not yet
67271.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
67281.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
67291.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
67301.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
67311.33Skamil
67321.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
67331.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
67341.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
67351.34Skamil
67361.1Skamil	ATF_TP_ADD_TC(tp, traceme3);
67371.1Skamil
67381.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
67391.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
67401.1Skamil	ATF_TP_ADD_TC(tp, attach3);
67411.1Skamil	ATF_TP_ADD_TC(tp, attach4);
67421.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
67431.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
67441.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
67451.1Skamil
67461.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
67471.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
67481.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
67491.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
67501.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
67511.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
67521.1Skamil
67531.31Skamil	ATF_TP_ADD_TC(tp, fork1);
67541.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
67551.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
67561.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
67571.31Skamil	ATF_TP_ADD_TC(tp, fork5);
67581.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
67591.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
67601.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
67611.31Skamil
67621.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
67631.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
67641.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
67651.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
67661.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
67671.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
67681.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
67691.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
67701.1Skamil
67711.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
67721.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
67731.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
67741.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
67751.1Skamil
67761.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
67771.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
67781.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
67791.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
67801.1Skamil
67811.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
67821.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
67831.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
67841.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
67851.1Skamil
67861.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
67871.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
67881.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
67891.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
67901.1Skamil
67911.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
67921.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
67931.1Skamil
67941.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
67951.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
67961.1Skamil
67971.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
67981.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
67991.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
68001.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
68011.1Skamil
68021.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
68031.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
68041.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
68051.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
68061.1Skamil
68071.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
68081.1Skamil
68091.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
68101.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
68111.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
68121.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
68131.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
68141.1Skamil
68151.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
68161.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
68171.1Skamil
68181.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
68191.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
68201.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
68211.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
68221.1Skamil
68231.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
68241.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
68251.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
68261.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
68271.2Skamil
68281.1Skamil	ATF_TP_ADD_TC(tp, kill1);
68291.1Skamil	ATF_TP_ADD_TC(tp, kill2);
68301.1Skamil
68311.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
68321.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
68331.1Skamil
68341.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
68351.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
68361.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
68371.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
68381.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
68391.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
68401.1Skamil
68411.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
68421.1Skamil
68431.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
68441.1Skamil
68451.1Skamil	ATF_TP_ADD_TC(tp, signal1);
68461.1Skamil	ATF_TP_ADD_TC(tp, signal2);
68471.1Skamil	ATF_TP_ADD_TC(tp, signal3);
68481.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
68491.1Skamil	ATF_TP_ADD_TC(tp, signal5);
68501.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
68511.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
68521.1Skamil	ATF_TP_ADD_TC(tp, signal8);
68531.1Skamil	ATF_TP_ADD_TC(tp, signal9);
68541.1Skamil	ATF_TP_ADD_TC(tp, signal10);
68551.1Skamil
68561.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
68571.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
68581.1Skamil
68591.1Skamil	ATF_TP_ADD_TC(tp, resume1);
68601.1Skamil
68611.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
68621.1Skamil
68631.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
68641.1Skamil
68651.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
68661.26Skamil
68671.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
68681.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
68691.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
68701.1Skamil
68711.1Skamil	return atf_no_error();
68721.1Skamil}
6873