t_ptrace_wait.c revision 1.33
11.33Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.33 2018/04/27 21:36:45 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.33Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.33 2018/04/27 21:36:45 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.33Skamilstatic void
851.33Skamiltraceme_raise(int sigval)
861.1Skamil{
871.1Skamil	const int exitval = 5;
881.1Skamil	pid_t child, wpid;
891.1Skamil#if defined(TWAIT_HAVE_STATUS)
901.1Skamil	int status;
911.1Skamil#endif
921.1Skamil
931.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
941.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
951.1Skamil	if (child == 0) {
961.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
971.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
981.1Skamil
991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1011.1Skamil
1021.13Schristos		DPRINTF("Before exiting of the child process\n");
1031.1Skamil		_exit(exitval);
1041.1Skamil	}
1051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1061.1Skamil
1071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1091.1Skamil
1101.1Skamil	validate_status_stopped(status, sigval);
1111.1Skamil
1121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
1131.1Skamil	    "without signal to be sent\n");
1141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1151.1Skamil
1161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1181.1Skamil
1191.1Skamil	validate_status_exited(status, exitval);
1201.1Skamil
1211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1231.1Skamil}
1241.1Skamil
1251.33Skamil#define TRACEME_RAISE(test, sig)						\
1261.33SkamilATF_TC(test);									\
1271.33SkamilATF_TC_HEAD(test, tc)								\
1281.33Skamil{										\
1291.33Skamil	atf_tc_set_md_var(tc, "descr",						\
1301.33Skamil	    "Verify " #sig " followed by _exit(2) in a child");			\
1311.33Skamil}										\
1321.33Skamil										\
1331.33SkamilATF_TC_BODY(test, tc)								\
1341.33Skamil{										\
1351.33Skamil										\
1361.33Skamil	traceme_raise(sig);							\
1371.33Skamil}
1381.33Skamil
1391.33Skamil//TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ // not yet
1401.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
1411.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
1421.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
1431.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
1441.33Skamil
1451.1SkamilATF_TC(traceme2);
1461.1SkamilATF_TC_HEAD(traceme2, tc)
1471.1Skamil{
1481.1Skamil	atf_tc_set_md_var(tc, "descr",
1491.27Skamil	    "Verify that a signal emitted by a tracer to a child is caught by "
1501.27Skamil	    "a signal handler");
1511.1Skamil}
1521.1Skamil
1531.1Skamilstatic int traceme2_caught = 0;
1541.1Skamil
1551.1Skamilstatic void
1561.1Skamiltraceme2_sighandler(int sig)
1571.1Skamil{
1581.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
1591.1Skamil
1601.1Skamil	++traceme2_caught;
1611.1Skamil}
1621.1Skamil
1631.1SkamilATF_TC_BODY(traceme2, tc)
1641.1Skamil{
1651.1Skamil	const int exitval = 5;
1661.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT;
1671.1Skamil	pid_t child, wpid;
1681.1Skamil	struct sigaction sa;
1691.1Skamil#if defined(TWAIT_HAVE_STATUS)
1701.1Skamil	int status;
1711.1Skamil#endif
1721.1Skamil
1731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1751.1Skamil	if (child == 0) {
1761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1781.1Skamil
1791.1Skamil		sa.sa_handler = traceme2_sighandler;
1801.1Skamil		sa.sa_flags = SA_SIGINFO;
1811.1Skamil		sigemptyset(&sa.sa_mask);
1821.1Skamil
1831.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1841.1Skamil
1851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1871.1Skamil
1881.1Skamil		FORKEE_ASSERT_EQ(traceme2_caught, 1);
1891.1Skamil
1901.13Schristos		DPRINTF("Before exiting of the child process\n");
1911.1Skamil		_exit(exitval);
1921.1Skamil	}
1931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1941.1Skamil
1951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1971.1Skamil
1981.1Skamil	validate_status_stopped(status, sigval);
1991.1Skamil
2001.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2011.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2031.1Skamil
2041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2061.1Skamil
2071.1Skamil	validate_status_exited(status, exitval);
2081.1Skamil
2091.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2111.1Skamil}
2121.1Skamil
2131.1SkamilATF_TC(traceme3);
2141.1SkamilATF_TC_HEAD(traceme3, tc)
2151.1Skamil{
2161.1Skamil	atf_tc_set_md_var(tc, "descr",
2171.1Skamil	    "Verify SIGSTOP followed by termination by a signal in a child");
2181.1Skamil}
2191.1Skamil
2201.1SkamilATF_TC_BODY(traceme3, tc)
2211.1Skamil{
2221.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
2231.1Skamil	pid_t child, wpid;
2241.1Skamil#if defined(TWAIT_HAVE_STATUS)
2251.1Skamil	int status;
2261.1Skamil#endif
2271.1Skamil
2281.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2291.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2301.1Skamil	if (child == 0) {
2311.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2321.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2331.1Skamil
2341.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2351.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2361.1Skamil
2371.1Skamil		/* NOTREACHED */
2381.1Skamil		FORKEE_ASSERTX(0 &&
2391.1Skamil		    "Child should be terminated by a signal from its parent");
2401.1Skamil	}
2411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2421.1Skamil
2431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2451.1Skamil
2461.1Skamil	validate_status_stopped(status, sigval);
2471.1Skamil
2481.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2491.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2511.1Skamil
2521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2541.1Skamil
2551.1Skamil	validate_status_signaled(status, sigsent, 0);
2561.1Skamil
2571.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2591.1Skamil}
2601.1Skamil
2611.1Skamil#if defined(TWAIT_HAVE_PID)
2621.1SkamilATF_TC(attach1);
2631.1SkamilATF_TC_HEAD(attach1, tc)
2641.1Skamil{
2651.1Skamil	atf_tc_set_md_var(tc, "descr",
2661.1Skamil	    "Assert that tracer sees process termination before the parent");
2671.1Skamil}
2681.1Skamil
2691.26Skamilstatic void
2701.26Skamilattach1_raw(bool raw)
2711.1Skamil{
2721.1Skamil	struct msg_fds parent_tracee, parent_tracer;
2731.1Skamil	const int exitval_tracee = 5;
2741.1Skamil	const int exitval_tracer = 10;
2751.1Skamil	pid_t tracee, tracer, wpid;
2761.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2771.1Skamil#if defined(TWAIT_HAVE_STATUS)
2781.1Skamil	int status;
2791.1Skamil#endif
2801.1Skamil
2811.13Schristos	DPRINTF("Spawn tracee\n");
2821.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2831.1Skamil	tracee = atf_utils_fork();
2841.1Skamil	if (tracee == 0) {
2851.1Skamil		// Wait for parent to let us exit
2861.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2871.1Skamil		_exit(exitval_tracee);
2881.1Skamil	}
2891.1Skamil
2901.13Schristos	DPRINTF("Spawn debugger\n");
2911.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2921.1Skamil	tracer = atf_utils_fork();
2931.1Skamil	if (tracer == 0) {
2941.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2951.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2961.1Skamil
2971.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2981.1Skamil		FORKEE_REQUIRE_SUCCESS(
2991.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3001.1Skamil
3011.1Skamil		forkee_status_stopped(status, SIGSTOP);
3021.1Skamil
3031.1Skamil		/* Resume tracee with PT_CONTINUE */
3041.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3051.1Skamil
3061.1Skamil		/* Inform parent that tracer has attached to tracee */
3071.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3081.1Skamil
3091.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3101.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3111.1Skamil
3121.1Skamil		/* Wait for tracee and assert that it exited */
3131.1Skamil		FORKEE_REQUIRE_SUCCESS(
3141.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3151.1Skamil
3161.1Skamil		forkee_status_exited(status, exitval_tracee);
3171.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3181.1Skamil
3191.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3201.1Skamil		_exit(exitval_tracer);
3211.1Skamil	}
3221.1Skamil
3231.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3241.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3251.1Skamil
3261.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3271.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3281.1Skamil
3291.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3301.26Skamil	if (raw)
3311.26Skamil		await_zombie_raw(tracee, 0);
3321.26Skamil	else
3331.26Skamil		await_zombie(tracee);
3341.1Skamil
3351.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3361.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3371.1Skamil	    TWAIT_FNAME);
3381.1Skamil	TWAIT_REQUIRE_SUCCESS(
3391.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
3401.1Skamil
3411.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
3421.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
3431.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3441.1Skamil	    TWAIT_FNAME);
3451.1Skamil
3461.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
3471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3481.1Skamil	    tracer);
3491.1Skamil
3501.1Skamil	validate_status_exited(status, exitval_tracer);
3511.1Skamil
3521.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
3531.1Skamil	    TWAIT_FNAME);
3541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
3551.1Skamil	    tracee);
3561.1Skamil
3571.1Skamil	validate_status_exited(status, exitval_tracee);
3581.1Skamil
3591.1Skamil	msg_close(&parent_tracer);
3601.1Skamil	msg_close(&parent_tracee);
3611.1Skamil}
3621.26Skamil
3631.26SkamilATF_TC_BODY(attach1, tc)
3641.26Skamil{
3651.26Skamil
3661.26Skamil	/* Reuse this test with race1 */
3671.26Skamil	attach1_raw(false);
3681.26Skamil}
3691.26Skamil
3701.1Skamil#endif
3711.1Skamil
3721.1Skamil#if defined(TWAIT_HAVE_PID)
3731.1SkamilATF_TC(attach2);
3741.1SkamilATF_TC_HEAD(attach2, tc)
3751.1Skamil{
3761.1Skamil	atf_tc_set_md_var(tc, "descr",
3771.1Skamil	    "Assert that any tracer sees process termination before its "
3781.1Skamil	    "parent");
3791.1Skamil}
3801.1Skamil
3811.1SkamilATF_TC_BODY(attach2, tc)
3821.1Skamil{
3831.1Skamil	struct msg_fds parent_tracer, parent_tracee;
3841.1Skamil	const int exitval_tracee = 5;
3851.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
3861.1Skamil	pid_t tracee, tracer, wpid;
3871.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3881.1Skamil#if defined(TWAIT_HAVE_STATUS)
3891.1Skamil	int status;
3901.1Skamil#endif
3911.1Skamil
3921.13Schristos	DPRINTF("Spawn tracee\n");
3931.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3941.1Skamil	tracee = atf_utils_fork();
3951.1Skamil	if (tracee == 0) {
3961.1Skamil		/* Wait for message from the parent */
3971.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
3981.1Skamil		_exit(exitval_tracee);
3991.1Skamil	}
4001.1Skamil
4011.13Schristos	DPRINTF("Spawn debugger\n");
4021.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4031.1Skamil	tracer = atf_utils_fork();
4041.1Skamil	if (tracer == 0) {
4051.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4061.1Skamil		tracer = atf_utils_fork();
4071.1Skamil		if (tracer != 0)
4081.1Skamil			_exit(exitval_tracer1);
4091.1Skamil
4101.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4111.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4121.1Skamil
4131.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4141.1Skamil		FORKEE_REQUIRE_SUCCESS(
4151.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4161.1Skamil
4171.1Skamil		forkee_status_stopped(status, SIGSTOP);
4181.1Skamil
4191.1Skamil		/* Resume tracee with PT_CONTINUE */
4201.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4211.1Skamil
4221.1Skamil		/* Inform parent that tracer has attached to tracee */
4231.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4241.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4251.1Skamil
4261.1Skamil		/* Wait for tracee and assert that it exited */
4271.1Skamil		FORKEE_REQUIRE_SUCCESS(
4281.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4291.1Skamil
4301.1Skamil		forkee_status_exited(status, exitval_tracee);
4311.1Skamil
4321.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4331.1Skamil		_exit(exitval_tracer2);
4341.1Skamil	}
4351.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4361.1Skamil	    "%s()\n", TWAIT_FNAME);
4371.1Skamil	TWAIT_REQUIRE_SUCCESS(
4381.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4391.1Skamil
4401.1Skamil	validate_status_exited(status, exitval_tracer1);
4411.1Skamil
4421.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4431.1Skamil	    TWAIT_FNAME);
4441.1Skamil	TWAIT_REQUIRE_SUCCESS(
4451.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4461.1Skamil
4471.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4481.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
4491.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4501.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
4511.1Skamil
4521.13Schristos	DPRINTF("Detect that tracee is zombie\n");
4531.1Skamil	await_zombie(tracee);
4541.1Skamil
4551.13Schristos	DPRINTF("Assert that there is no status about tracee - "
4561.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4571.1Skamil	TWAIT_REQUIRE_SUCCESS(
4581.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4591.1Skamil
4601.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
4611.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
4621.1Skamil
4631.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4641.1Skamil	    TWAIT_FNAME);
4651.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
4661.1Skamil	    tracee);
4671.1Skamil
4681.1Skamil	validate_status_exited(status, exitval_tracee);
4691.1Skamil
4701.1Skamil	msg_close(&parent_tracer);
4711.1Skamil	msg_close(&parent_tracee);
4721.1Skamil}
4731.1Skamil#endif
4741.1Skamil
4751.1SkamilATF_TC(attach3);
4761.1SkamilATF_TC_HEAD(attach3, tc)
4771.1Skamil{
4781.1Skamil	atf_tc_set_md_var(tc, "descr",
4791.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
4801.1Skamil}
4811.1Skamil
4821.1SkamilATF_TC_BODY(attach3, tc)
4831.1Skamil{
4841.1Skamil	struct msg_fds parent_tracee;
4851.1Skamil	const int exitval_tracee = 5;
4861.1Skamil	pid_t tracee, wpid;
4871.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4881.1Skamil#if defined(TWAIT_HAVE_STATUS)
4891.1Skamil	int status;
4901.1Skamil#endif
4911.1Skamil
4921.13Schristos	DPRINTF("Spawn tracee\n");
4931.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4941.1Skamil	tracee = atf_utils_fork();
4951.1Skamil	if (tracee == 0) {
4961.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4971.13Schristos		DPRINTF("Parent should now attach to tracee\n");
4981.1Skamil
4991.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5001.1Skamil		/* Wait for message from the parent */
5011.1Skamil		_exit(exitval_tracee);
5021.1Skamil	}
5031.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5041.1Skamil
5051.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5071.1Skamil
5081.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5091.1Skamil	    TWAIT_FNAME);
5101.1Skamil	TWAIT_REQUIRE_SUCCESS(
5111.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5121.1Skamil
5131.1Skamil	validate_status_stopped(status, SIGSTOP);
5141.1Skamil
5151.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5171.1Skamil
5181.13Schristos	DPRINTF("Let the tracee exit now\n");
5191.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5201.1Skamil
5211.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5221.1Skamil	TWAIT_REQUIRE_SUCCESS(
5231.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5241.1Skamil
5251.1Skamil	validate_status_exited(status, exitval_tracee);
5261.1Skamil
5271.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5281.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5291.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5301.1Skamil
5311.1Skamil	msg_close(&parent_tracee);
5321.1Skamil}
5331.1Skamil
5341.1SkamilATF_TC(attach4);
5351.1SkamilATF_TC_HEAD(attach4, tc)
5361.1Skamil{
5371.1Skamil	atf_tc_set_md_var(tc, "descr",
5381.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
5391.1Skamil}
5401.1Skamil
5411.1SkamilATF_TC_BODY(attach4, tc)
5421.1Skamil{
5431.1Skamil	struct msg_fds parent_tracee;
5441.1Skamil	const int exitval_tracer = 5;
5451.1Skamil	pid_t tracer, wpid;
5461.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5471.1Skamil#if defined(TWAIT_HAVE_STATUS)
5481.1Skamil	int status;
5491.1Skamil#endif
5501.1Skamil
5511.13Schristos	DPRINTF("Spawn tracer\n");
5521.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5531.1Skamil	tracer = atf_utils_fork();
5541.1Skamil	if (tracer == 0) {
5551.1Skamil
5561.1Skamil		/* Wait for message from the parent */
5571.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5581.1Skamil
5591.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
5601.1Skamil		    getppid());
5611.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
5621.1Skamil
5631.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
5641.1Skamil		    TWAIT_FNAME);
5651.1Skamil		FORKEE_REQUIRE_SUCCESS(
5661.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
5671.1Skamil
5681.1Skamil		forkee_status_stopped(status, SIGSTOP);
5691.1Skamil
5701.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
5711.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
5721.1Skamil		    != -1);
5731.1Skamil
5741.1Skamil		/* Tell parent we are ready */
5751.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
5761.1Skamil
5771.1Skamil		_exit(exitval_tracer);
5781.1Skamil	}
5791.1Skamil
5801.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
5811.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5821.13Schristos	DPRINTF("Allow the tracer to exit now\n");
5831.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
5841.1Skamil
5851.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
5861.1Skamil	TWAIT_REQUIRE_SUCCESS(
5871.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
5881.1Skamil
5891.1Skamil	validate_status_exited(status, exitval_tracer);
5901.1Skamil
5911.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
5921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5931.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
5941.1Skamil
5951.1Skamil	msg_close(&parent_tracee);
5961.1Skamil}
5971.1Skamil
5981.1Skamil#if defined(TWAIT_HAVE_PID)
5991.1SkamilATF_TC(attach5);
6001.1SkamilATF_TC_HEAD(attach5, tc)
6011.1Skamil{
6021.1Skamil	atf_tc_set_md_var(tc, "descr",
6031.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6041.1Skamil	    "(check getppid(2))");
6051.1Skamil}
6061.1Skamil
6071.1SkamilATF_TC_BODY(attach5, tc)
6081.1Skamil{
6091.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6101.1Skamil	const int exitval_tracee = 5;
6111.1Skamil	const int exitval_tracer = 10;
6121.1Skamil	pid_t parent, tracee, tracer, wpid;
6131.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6141.1Skamil#if defined(TWAIT_HAVE_STATUS)
6151.1Skamil	int status;
6161.1Skamil#endif
6171.1Skamil
6181.13Schristos	DPRINTF("Spawn tracee\n");
6191.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6201.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6211.1Skamil	tracee = atf_utils_fork();
6221.1Skamil	if (tracee == 0) {
6231.1Skamil		parent = getppid();
6241.1Skamil
6251.1Skamil		/* Emit message to the parent */
6261.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6271.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6281.1Skamil
6291.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6301.1Skamil
6311.1Skamil		_exit(exitval_tracee);
6321.1Skamil	}
6331.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6341.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6351.1Skamil
6361.13Schristos	DPRINTF("Spawn debugger\n");
6371.1Skamil	tracer = atf_utils_fork();
6381.1Skamil	if (tracer == 0) {
6391.1Skamil		/* No IPC to communicate with the child */
6401.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6411.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6421.1Skamil
6431.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6441.1Skamil		FORKEE_REQUIRE_SUCCESS(
6451.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6461.1Skamil
6471.1Skamil		forkee_status_stopped(status, SIGSTOP);
6481.1Skamil
6491.1Skamil		/* Resume tracee with PT_CONTINUE */
6501.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6511.1Skamil
6521.1Skamil		/* Inform parent that tracer has attached to tracee */
6531.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
6541.1Skamil
6551.1Skamil		/* Wait for parent to tell use that tracee should have exited */
6561.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
6571.1Skamil
6581.1Skamil		/* Wait for tracee and assert that it exited */
6591.1Skamil		FORKEE_REQUIRE_SUCCESS(
6601.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6611.1Skamil
6621.1Skamil		forkee_status_exited(status, exitval_tracee);
6631.1Skamil
6641.13Schristos		DPRINTF("Before exiting of the tracer process\n");
6651.1Skamil		_exit(exitval_tracer);
6661.1Skamil	}
6671.1Skamil
6681.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
6691.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
6701.1Skamil
6711.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
6721.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
6731.1Skamil
6741.13Schristos	DPRINTF("Detect that tracee is zombie\n");
6751.1Skamil	await_zombie(tracee);
6761.1Skamil
6771.13Schristos	DPRINTF("Assert that there is no status about tracee - "
6781.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
6791.1Skamil	TWAIT_REQUIRE_SUCCESS(
6801.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
6811.1Skamil
6821.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
6831.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
6841.1Skamil
6851.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
6861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
6871.1Skamil	    tracer);
6881.1Skamil
6891.1Skamil	validate_status_exited(status, exitval_tracer);
6901.1Skamil
6911.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
6921.1Skamil	    TWAIT_FNAME);
6931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
6941.1Skamil	    tracee);
6951.1Skamil
6961.1Skamil	validate_status_exited(status, exitval_tracee);
6971.1Skamil
6981.1Skamil	msg_close(&parent_tracer);
6991.1Skamil	msg_close(&parent_tracee);
7001.1Skamil}
7011.1Skamil#endif
7021.1Skamil
7031.1Skamil#if defined(TWAIT_HAVE_PID)
7041.1SkamilATF_TC(attach6);
7051.1SkamilATF_TC_HEAD(attach6, tc)
7061.1Skamil{
7071.1Skamil	atf_tc_set_md_var(tc, "descr",
7081.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7091.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7101.1Skamil}
7111.1Skamil
7121.1SkamilATF_TC_BODY(attach6, tc)
7131.1Skamil{
7141.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7151.1Skamil	const int exitval_tracee = 5;
7161.1Skamil	const int exitval_tracer = 10;
7171.1Skamil	pid_t parent, tracee, tracer, wpid;
7181.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7191.1Skamil#if defined(TWAIT_HAVE_STATUS)
7201.1Skamil	int status;
7211.1Skamil#endif
7221.1Skamil	int name[CTL_MAXNAME];
7231.1Skamil	struct kinfo_proc2 kp;
7241.1Skamil	size_t len = sizeof(kp);
7251.1Skamil	unsigned int namelen;
7261.1Skamil
7271.13Schristos	DPRINTF("Spawn tracee\n");
7281.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7291.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7301.1Skamil	tracee = atf_utils_fork();
7311.1Skamil	if (tracee == 0) {
7321.1Skamil		parent = getppid();
7331.1Skamil
7341.1Skamil		/* Emit message to the parent */
7351.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7361.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7371.1Skamil
7381.1Skamil		namelen = 0;
7391.1Skamil		name[namelen++] = CTL_KERN;
7401.1Skamil		name[namelen++] = KERN_PROC2;
7411.1Skamil		name[namelen++] = KERN_PROC_PID;
7421.1Skamil		name[namelen++] = getpid();
7431.1Skamil		name[namelen++] = len;
7441.1Skamil		name[namelen++] = 1;
7451.1Skamil
7461.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
7471.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
7481.1Skamil
7491.1Skamil		_exit(exitval_tracee);
7501.1Skamil	}
7511.1Skamil
7521.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
7531.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
7541.1Skamil
7551.13Schristos	DPRINTF("Spawn debugger\n");
7561.1Skamil	tracer = atf_utils_fork();
7571.1Skamil	if (tracer == 0) {
7581.1Skamil		/* No IPC to communicate with the child */
7591.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
7601.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7611.1Skamil
7621.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
7631.1Skamil		FORKEE_REQUIRE_SUCCESS(
7641.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7651.1Skamil
7661.1Skamil		forkee_status_stopped(status, SIGSTOP);
7671.1Skamil
7681.1Skamil		/* Resume tracee with PT_CONTINUE */
7691.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7701.1Skamil
7711.1Skamil		/* Inform parent that tracer has attached to tracee */
7721.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
7731.1Skamil
7741.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
7751.1Skamil
7761.1Skamil		/* Wait for tracee and assert that it exited */
7771.1Skamil		FORKEE_REQUIRE_SUCCESS(
7781.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7791.1Skamil
7801.1Skamil		forkee_status_exited(status, exitval_tracee);
7811.1Skamil
7821.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7831.1Skamil		_exit(exitval_tracer);
7841.1Skamil	}
7851.1Skamil
7861.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7871.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
7881.1Skamil
7891.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7901.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
7911.1Skamil
7921.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7931.1Skamil	await_zombie(tracee);
7941.1Skamil
7951.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7961.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7971.1Skamil	TWAIT_REQUIRE_SUCCESS(
7981.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7991.1Skamil
8001.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8011.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8021.1Skamil
8031.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8041.1Skamil	    TWAIT_FNAME);
8051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8061.1Skamil	    tracer);
8071.1Skamil
8081.1Skamil	validate_status_exited(status, exitval_tracer);
8091.1Skamil
8101.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8111.1Skamil	    TWAIT_FNAME);
8121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8131.1Skamil	    tracee);
8141.1Skamil
8151.1Skamil	validate_status_exited(status, exitval_tracee);
8161.1Skamil
8171.1Skamil	msg_close(&parent_tracee);
8181.1Skamil	msg_close(&parent_tracer);
8191.1Skamil}
8201.1Skamil#endif
8211.1Skamil
8221.1Skamil#if defined(TWAIT_HAVE_PID)
8231.1SkamilATF_TC(attach7);
8241.1SkamilATF_TC_HEAD(attach7, tc)
8251.1Skamil{
8261.1Skamil	atf_tc_set_md_var(tc, "descr",
8271.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8281.1Skamil	    "(check /proc/curproc/status 3rd column)");
8291.1Skamil}
8301.1Skamil
8311.1SkamilATF_TC_BODY(attach7, tc)
8321.1Skamil{
8331.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8341.1Skamil	int rv;
8351.1Skamil	const int exitval_tracee = 5;
8361.1Skamil	const int exitval_tracer = 10;
8371.1Skamil	pid_t parent, tracee, tracer, wpid;
8381.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8391.1Skamil#if defined(TWAIT_HAVE_STATUS)
8401.1Skamil	int status;
8411.1Skamil#endif
8421.1Skamil	FILE *fp;
8431.1Skamil	struct stat st;
8441.1Skamil	const char *fname = "/proc/curproc/status";
8451.1Skamil	char s_executable[MAXPATHLEN];
8461.1Skamil	int s_pid, s_ppid;
8471.1Skamil	/*
8481.1Skamil	 * Format:
8491.1Skamil	 *  EXECUTABLE PID PPID ...
8501.1Skamil	 */
8511.1Skamil
8521.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
8531.1Skamil	if (rv != 0) {
8541.1Skamil		atf_tc_skip("/proc/curproc/status not found");
8551.1Skamil	}
8561.1Skamil
8571.13Schristos	DPRINTF("Spawn tracee\n");
8581.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8591.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8601.1Skamil	tracee = atf_utils_fork();
8611.1Skamil	if (tracee == 0) {
8621.1Skamil		parent = getppid();
8631.1Skamil
8641.1Skamil		// Wait for parent to let us exit
8651.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
8661.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
8671.1Skamil
8681.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
8691.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
8701.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
8711.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
8721.1Skamil
8731.1Skamil		_exit(exitval_tracee);
8741.1Skamil	}
8751.1Skamil
8761.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
8771.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
8781.1Skamil
8791.13Schristos	DPRINTF("Spawn debugger\n");
8801.1Skamil	tracer = atf_utils_fork();
8811.1Skamil	if (tracer == 0) {
8821.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8831.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8841.1Skamil
8851.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8861.1Skamil		FORKEE_REQUIRE_SUCCESS(
8871.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8881.1Skamil
8891.1Skamil		forkee_status_stopped(status, SIGSTOP);
8901.1Skamil
8911.1Skamil		/* Resume tracee with PT_CONTINUE */
8921.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8931.1Skamil
8941.1Skamil		/* Inform parent that tracer has attached to tracee */
8951.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
8961.1Skamil
8971.1Skamil		/* Wait for parent to tell use that tracee should have exited */
8981.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
8991.1Skamil
9001.1Skamil		/* Wait for tracee and assert that it exited */
9011.1Skamil		FORKEE_REQUIRE_SUCCESS(
9021.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9031.1Skamil
9041.1Skamil		forkee_status_exited(status, exitval_tracee);
9051.1Skamil
9061.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9071.1Skamil		_exit(exitval_tracer);
9081.1Skamil	}
9091.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9101.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9111.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9121.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9131.1Skamil
9141.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9151.1Skamil	await_zombie(tracee);
9161.1Skamil
9171.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9181.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9191.1Skamil	TWAIT_REQUIRE_SUCCESS(
9201.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9211.1Skamil
9221.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9231.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9241.1Skamil
9251.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9261.1Skamil	    TWAIT_FNAME);
9271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9281.1Skamil	    tracer);
9291.1Skamil
9301.1Skamil	validate_status_exited(status, exitval_tracer);
9311.1Skamil
9321.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9331.1Skamil	    TWAIT_FNAME);
9341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9351.1Skamil	    tracee);
9361.1Skamil
9371.1Skamil	validate_status_exited(status, exitval_tracee);
9381.1Skamil
9391.1Skamil	msg_close(&parent_tracee);
9401.1Skamil	msg_close(&parent_tracer);
9411.1Skamil}
9421.1Skamil#endif
9431.1Skamil
9441.1SkamilATF_TC(eventmask1);
9451.1SkamilATF_TC_HEAD(eventmask1, tc)
9461.1Skamil{
9471.1Skamil	atf_tc_set_md_var(tc, "descr",
9481.1Skamil	    "Verify that empty EVENT_MASK is preserved");
9491.1Skamil}
9501.1Skamil
9511.1SkamilATF_TC_BODY(eventmask1, tc)
9521.1Skamil{
9531.1Skamil	const int exitval = 5;
9541.1Skamil	const int sigval = SIGSTOP;
9551.1Skamil	pid_t child, wpid;
9561.1Skamil#if defined(TWAIT_HAVE_STATUS)
9571.1Skamil	int status;
9581.1Skamil#endif
9591.1Skamil	ptrace_event_t set_event, get_event;
9601.1Skamil	const int len = sizeof(ptrace_event_t);
9611.1Skamil
9621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
9631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
9641.1Skamil	if (child == 0) {
9651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
9661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
9671.1Skamil
9681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
9691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
9701.1Skamil
9711.13Schristos		DPRINTF("Before exiting of the child process\n");
9721.1Skamil		_exit(exitval);
9731.1Skamil	}
9741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
9751.1Skamil
9761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
9771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
9781.1Skamil
9791.1Skamil	validate_status_stopped(status, sigval);
9801.1Skamil
9811.1Skamil	set_event.pe_set_event = 0;
9821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
9831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
9841.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
9851.1Skamil
9861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
9871.1Skamil	    "without signal to be sent\n");
9881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
9891.1Skamil
9901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
9911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
9921.1Skamil
9931.1Skamil	validate_status_exited(status, exitval);
9941.1Skamil
9951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
9961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
9971.1Skamil}
9981.1Skamil
9991.1SkamilATF_TC(eventmask2);
10001.1SkamilATF_TC_HEAD(eventmask2, tc)
10011.1Skamil{
10021.1Skamil	atf_tc_set_md_var(tc, "descr",
10031.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10041.1Skamil}
10051.1Skamil
10061.1SkamilATF_TC_BODY(eventmask2, tc)
10071.1Skamil{
10081.1Skamil	const int exitval = 5;
10091.1Skamil	const int sigval = SIGSTOP;
10101.1Skamil	pid_t child, wpid;
10111.1Skamil#if defined(TWAIT_HAVE_STATUS)
10121.1Skamil	int status;
10131.1Skamil#endif
10141.1Skamil	ptrace_event_t set_event, get_event;
10151.1Skamil	const int len = sizeof(ptrace_event_t);
10161.1Skamil
10171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10191.1Skamil	if (child == 0) {
10201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10221.1Skamil
10231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10251.1Skamil
10261.13Schristos		DPRINTF("Before exiting of the child process\n");
10271.1Skamil		_exit(exitval);
10281.1Skamil	}
10291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10301.1Skamil
10311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10331.1Skamil
10341.1Skamil	validate_status_stopped(status, sigval);
10351.1Skamil
10361.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10391.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10401.1Skamil
10411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10421.1Skamil	    "without signal to be sent\n");
10431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10441.1Skamil
10451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10471.1Skamil
10481.1Skamil	validate_status_exited(status, exitval);
10491.1Skamil
10501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10521.1Skamil}
10531.1Skamil
10541.1SkamilATF_TC(eventmask3);
10551.1SkamilATF_TC_HEAD(eventmask3, tc)
10561.1Skamil{
10571.1Skamil	atf_tc_set_md_var(tc, "descr",
10581.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
10591.1Skamil}
10601.1Skamil
10611.1SkamilATF_TC_BODY(eventmask3, tc)
10621.1Skamil{
10631.1Skamil	const int exitval = 5;
10641.1Skamil	const int sigval = SIGSTOP;
10651.1Skamil	pid_t child, wpid;
10661.1Skamil#if defined(TWAIT_HAVE_STATUS)
10671.1Skamil	int status;
10681.1Skamil#endif
10691.1Skamil	ptrace_event_t set_event, get_event;
10701.1Skamil	const int len = sizeof(ptrace_event_t);
10711.1Skamil
10721.14Schristos	atf_tc_expect_fail("PR kern/51630");
10731.14Schristos
10741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10761.1Skamil	if (child == 0) {
10771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10791.1Skamil
10801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10821.1Skamil
10831.13Schristos		DPRINTF("Before exiting of the child process\n");
10841.1Skamil		_exit(exitval);
10851.1Skamil	}
10861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10871.1Skamil
10881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10901.1Skamil
10911.1Skamil	validate_status_stopped(status, sigval);
10921.1Skamil
10931.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
10941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
10951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10961.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10971.1Skamil
10981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10991.1Skamil	    "without signal to be sent\n");
11001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11011.1Skamil
11021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11041.1Skamil
11051.1Skamil	validate_status_exited(status, exitval);
11061.1Skamil
11071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11091.1Skamil}
11101.1Skamil
11111.1SkamilATF_TC(eventmask4);
11121.1SkamilATF_TC_HEAD(eventmask4, tc)
11131.1Skamil{
11141.1Skamil	atf_tc_set_md_var(tc, "descr",
11151.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11161.1Skamil}
11171.1Skamil
11181.1SkamilATF_TC_BODY(eventmask4, tc)
11191.1Skamil{
11201.1Skamil	const int exitval = 5;
11211.1Skamil	const int sigval = SIGSTOP;
11221.1Skamil	pid_t child, wpid;
11231.1Skamil#if defined(TWAIT_HAVE_STATUS)
11241.1Skamil	int status;
11251.1Skamil#endif
11261.1Skamil	ptrace_event_t set_event, get_event;
11271.1Skamil	const int len = sizeof(ptrace_event_t);
11281.1Skamil
11291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11311.1Skamil	if (child == 0) {
11321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11341.1Skamil
11351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11371.1Skamil
11381.13Schristos		DPRINTF("Before exiting of the child process\n");
11391.1Skamil		_exit(exitval);
11401.1Skamil	}
11411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11421.1Skamil
11431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11451.1Skamil
11461.1Skamil	validate_status_stopped(status, sigval);
11471.1Skamil
11481.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
11491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11511.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11521.1Skamil
11531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11541.1Skamil	    "without signal to be sent\n");
11551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11561.1Skamil
11571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11591.1Skamil
11601.1Skamil	validate_status_exited(status, exitval);
11611.1Skamil
11621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11641.1Skamil}
11651.1Skamil
11661.1SkamilATF_TC(eventmask5);
11671.1SkamilATF_TC_HEAD(eventmask5, tc)
11681.1Skamil{
11691.1Skamil	atf_tc_set_md_var(tc, "descr",
11701.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
11711.1Skamil}
11721.1Skamil
11731.1SkamilATF_TC_BODY(eventmask5, tc)
11741.1Skamil{
11751.1Skamil	const int exitval = 5;
11761.1Skamil	const int sigval = SIGSTOP;
11771.1Skamil	pid_t child, wpid;
11781.1Skamil#if defined(TWAIT_HAVE_STATUS)
11791.1Skamil	int status;
11801.1Skamil#endif
11811.1Skamil	ptrace_event_t set_event, get_event;
11821.1Skamil	const int len = sizeof(ptrace_event_t);
11831.1Skamil
11841.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11851.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11861.1Skamil	if (child == 0) {
11871.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11881.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11891.1Skamil
11901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11921.1Skamil
11931.13Schristos		DPRINTF("Before exiting of the child process\n");
11941.1Skamil		_exit(exitval);
11951.1Skamil	}
11961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11971.1Skamil
11981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12001.1Skamil
12011.1Skamil	validate_status_stopped(status, sigval);
12021.1Skamil
12031.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12061.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12071.1Skamil
12081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12091.1Skamil	    "without signal to be sent\n");
12101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12111.1Skamil
12121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12141.1Skamil
12151.1Skamil	validate_status_exited(status, exitval);
12161.1Skamil
12171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12191.1Skamil}
12201.1Skamil
12211.1SkamilATF_TC(eventmask6);
12221.1SkamilATF_TC_HEAD(eventmask6, tc)
12231.1Skamil{
12241.1Skamil	atf_tc_set_md_var(tc, "descr",
12251.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12261.1Skamil}
12271.1Skamil
12281.1SkamilATF_TC_BODY(eventmask6, tc)
12291.1Skamil{
12301.1Skamil	const int exitval = 5;
12311.1Skamil	const int sigval = SIGSTOP;
12321.1Skamil	pid_t child, wpid;
12331.1Skamil#if defined(TWAIT_HAVE_STATUS)
12341.1Skamil	int status;
12351.1Skamil#endif
12361.1Skamil	ptrace_event_t set_event, get_event;
12371.1Skamil	const int len = sizeof(ptrace_event_t);
12381.1Skamil
12391.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12401.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12411.1Skamil	if (child == 0) {
12421.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12431.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12441.1Skamil
12451.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12461.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12471.1Skamil
12481.13Schristos		DPRINTF("Before exiting of the child process\n");
12491.1Skamil		_exit(exitval);
12501.1Skamil	}
12511.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12521.1Skamil
12531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12551.1Skamil
12561.1Skamil	validate_status_stopped(status, sigval);
12571.1Skamil
12581.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
12591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12611.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12621.1Skamil
12631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12641.1Skamil	    "without signal to be sent\n");
12651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12661.1Skamil
12671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12691.1Skamil
12701.1Skamil	validate_status_exited(status, exitval);
12711.1Skamil
12721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12741.1Skamil}
12751.1Skamil
12761.28Skamilstatic void
12771.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
12781.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
12791.1Skamil{
12801.1Skamil	const int exitval = 5;
12811.1Skamil	const int exitval2 = 15;
12821.1Skamil	const int sigval = SIGSTOP;
12831.31Skamil	pid_t child, child2 = 0, wpid;
12841.1Skamil#if defined(TWAIT_HAVE_STATUS)
12851.1Skamil	int status;
12861.1Skamil#endif
12871.1Skamil	ptrace_state_t state;
12881.1Skamil	const int slen = sizeof(state);
12891.1Skamil	ptrace_event_t event;
12901.1Skamil	const int elen = sizeof(event);
12911.1Skamil
12921.30Skamil	if (trackvfork) {
12931.28Skamil		atf_tc_expect_fail("PR kern/51630");
12941.28Skamil	}
12951.28Skamil
12961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12981.1Skamil	if (child == 0) {
12991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13011.1Skamil
13021.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13031.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13041.1Skamil
13051.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
13061.1Skamil
13071.1Skamil		if (child2 == 0)
13081.1Skamil			_exit(exitval2);
13091.1Skamil
13101.1Skamil		FORKEE_REQUIRE_SUCCESS
13111.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13121.1Skamil
13131.1Skamil		forkee_status_exited(status, exitval2);
13141.1Skamil
13151.13Schristos		DPRINTF("Before exiting of the child process\n");
13161.1Skamil		_exit(exitval);
13171.1Skamil	}
13181.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13191.1Skamil
13201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13221.1Skamil
13231.1Skamil	validate_status_stopped(status, sigval);
13241.1Skamil
13251.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
13261.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
13271.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
13281.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
13291.30Skamil	event.pe_set_event = 0;
13301.30Skamil	if (trackfork)
13311.30Skamil		event.pe_set_event |= PTRACE_FORK;
13321.30Skamil	if (trackvfork)
13331.30Skamil		event.pe_set_event |= PTRACE_VFORK;
13341.30Skamil	if (trackvforkdone)
13351.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
13361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13371.1Skamil
13381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13391.1Skamil	    "without signal to be sent\n");
13401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13411.1Skamil
13421.29Skamil#if defined(TWAIT_HAVE_PID)
13431.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
13441.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
13451.29Skamil		        child);
13461.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
13471.29Skamil		                      child);
13481.1Skamil
13491.29Skamil		validate_status_stopped(status, SIGTRAP);
13501.1Skamil
13511.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
13521.29Skamil		                       slen) != -1);
13531.31Skamil		if (trackfork && fn == fork) {
13541.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
13551.30Skamil			       PTRACE_FORK);
13561.30Skamil		}
13571.31Skamil		if (trackvfork && fn == vfork) {
13581.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
13591.30Skamil			       PTRACE_VFORK);
13601.30Skamil		}
13611.29Skamil
13621.29Skamil		child2 = state.pe_other_pid;
13631.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
13641.29Skamil
13651.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
13661.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
13671.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
13681.29Skamil		    child2);
13691.1Skamil
13701.29Skamil		validate_status_stopped(status, SIGTRAP);
13711.1Skamil
13721.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
13731.29Skamil		                       slen) != -1);
13741.31Skamil		if (trackfork && fn == fork) {
13751.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
13761.30Skamil			       PTRACE_FORK);
13771.30Skamil		}
13781.31Skamil		if (trackvfork && fn == vfork) {
13791.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
13801.30Skamil			       PTRACE_VFORK);
13811.30Skamil		}
13821.30Skamil
13831.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
13841.29Skamil
13851.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
13861.29Skamil		    "and without signal to be sent\n");
13871.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
13881.29Skamil		                != -1);
13891.29Skamil
13901.29Skamil		DPRINTF("Before resuming the child process where it left off "
13911.29Skamil		        "and without signal to be sent\n");
13921.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13931.30Skamil	}
13941.30Skamil#endif
13951.30Skamil
13961.31Skamil	if (trackvforkdone && fn == vfork) {
13971.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
13981.30Skamil		        child);
13991.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
14001.30Skamil		                      child);
14011.30Skamil
14021.30Skamil		validate_status_stopped(status, SIGTRAP);
14031.30Skamil
14041.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
14051.30Skamil		                       slen) != -1);
14061.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
14071.30Skamil
14081.30Skamil		child2 = state.pe_other_pid;
14091.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
14101.30Skamil		        child2);
14111.30Skamil
14121.30Skamil		DPRINTF("Before resuming the child process where it left off "
14131.30Skamil		        "and without signal to be sent\n");
14141.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14151.30Skamil	}
14161.29Skamil
14171.30Skamil#if defined(TWAIT_HAVE_PID)
14181.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
14191.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
14201.29Skamil		        "\n", TWAIT_FNAME);
14211.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14221.29Skamil		    child2);
14231.29Skamil
14241.29Skamil		validate_status_exited(status, exitval2);
14251.29Skamil
14261.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
14271.29Skamil		        "process\n", TWAIT_FNAME);
14281.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
14291.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
14301.29Skamil	}
14311.29Skamil#endif
14321.1Skamil
14331.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14341.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14361.1Skamil
14371.1Skamil	validate_status_stopped(status, SIGCHLD);
14381.1Skamil
14391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14401.1Skamil	    "without signal to be sent\n");
14411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14421.1Skamil
14431.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
14441.1Skamil	    TWAIT_FNAME);
14451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14461.1Skamil
14471.1Skamil	validate_status_exited(status, exitval);
14481.1Skamil
14491.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
14501.1Skamil	    TWAIT_FNAME);
14511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14521.1Skamil}
14531.28Skamil
14541.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
14551.32SkamilATF_TC(name);									\
14561.32SkamilATF_TC_HEAD(name, tc)								\
14571.32Skamil{										\
14581.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
14591.32Skamil}										\
14601.32Skamil										\
14611.32SkamilATF_TC_BODY(name, tc)								\
14621.32Skamil{										\
14631.32Skamil										\
14641.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
14651.32Skamil}
14661.32Skamil
14671.32Skamil#define F false
14681.32Skamil#define T true
14691.32Skamil
14701.32Skamil#define F_IF__0(x)
14711.32Skamil#define F_IF__1(x) x
14721.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
14731.32Skamil#define F_IF_(x,y) F_IF__(x,y)
14741.32Skamil#define F_IF(x,y) F_IF_(x,y)
14751.32Skamil
14761.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
14771.32Skamil        "Verify " #function "(2) called with 0"					\
14781.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
14791.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
14801.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
14811.32Skamil        " in EVENT_MASK."							\
14821.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
14831.32Skamil        F_IF(dparentbit," Detach parent in this test.")
14841.1Skamil
14851.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
14861.31Skamil#if defined(TWAIT_HAVE_PID)
14871.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
14881.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
14891.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
14901.31Skamil#endif
14911.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
14921.31Skamil#if defined(TWAIT_HAVE_PID)
14931.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
14941.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
14951.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
14961.31Skamil#endif
14971.1Skamil
14981.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
14991.31Skamil#if defined(TWAIT_HAVE_PID)
15001.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
15011.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
15021.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
15031.31Skamil#endif
15041.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
15051.31Skamil#if defined(TWAIT_HAVE_PID)
15061.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
15071.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
15081.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
15091.31Skamil#endif
15101.31Skamil
15111.31Skamil
15121.31Skamil
15131.1Skamil
15141.1SkamilATF_TC(io_read_d1);
15151.1SkamilATF_TC_HEAD(io_read_d1, tc)
15161.1Skamil{
15171.1Skamil	atf_tc_set_md_var(tc, "descr",
15181.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
15191.1Skamil}
15201.1Skamil
15211.1SkamilATF_TC_BODY(io_read_d1, tc)
15221.1Skamil{
15231.1Skamil	const int exitval = 5;
15241.1Skamil	const int sigval = SIGSTOP;
15251.1Skamil	pid_t child, wpid;
15261.1Skamil	uint8_t lookup_me = 0;
15271.1Skamil	const uint8_t magic = 0xab;
15281.1Skamil	struct ptrace_io_desc io = {
15291.1Skamil		.piod_op = PIOD_READ_D,
15301.1Skamil		.piod_offs = &lookup_me,
15311.1Skamil		.piod_addr = &lookup_me,
15321.1Skamil		.piod_len = sizeof(lookup_me)
15331.1Skamil	};
15341.1Skamil#if defined(TWAIT_HAVE_STATUS)
15351.1Skamil	int status;
15361.1Skamil#endif
15371.1Skamil
15381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15401.1Skamil	if (child == 0) {
15411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15431.1Skamil
15441.1Skamil		lookup_me = magic;
15451.1Skamil
15461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15481.1Skamil
15491.13Schristos		DPRINTF("Before exiting of the child process\n");
15501.1Skamil		_exit(exitval);
15511.1Skamil	}
15521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15531.1Skamil
15541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15561.1Skamil
15571.1Skamil	validate_status_stopped(status, sigval);
15581.1Skamil
15591.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
15601.1Skamil	    child, getpid());
15611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
15621.1Skamil
15631.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
15641.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
15651.1Skamil
15661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15671.1Skamil	    "without signal to be sent\n");
15681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15691.1Skamil
15701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15721.1Skamil
15731.1Skamil	validate_status_exited(status, exitval);
15741.1Skamil
15751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15771.1Skamil}
15781.1Skamil
15791.1SkamilATF_TC(io_read_d2);
15801.1SkamilATF_TC_HEAD(io_read_d2, tc)
15811.1Skamil{
15821.1Skamil	atf_tc_set_md_var(tc, "descr",
15831.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
15841.1Skamil}
15851.1Skamil
15861.1SkamilATF_TC_BODY(io_read_d2, tc)
15871.1Skamil{
15881.1Skamil	const int exitval = 5;
15891.1Skamil	const int sigval = SIGSTOP;
15901.1Skamil	pid_t child, wpid;
15911.1Skamil	uint16_t lookup_me = 0;
15921.1Skamil	const uint16_t magic = 0x1234;
15931.1Skamil	struct ptrace_io_desc io = {
15941.1Skamil		.piod_op = PIOD_READ_D,
15951.1Skamil		.piod_offs = &lookup_me,
15961.1Skamil		.piod_addr = &lookup_me,
15971.1Skamil		.piod_len = sizeof(lookup_me)
15981.1Skamil	};
15991.1Skamil#if defined(TWAIT_HAVE_STATUS)
16001.1Skamil	int status;
16011.1Skamil#endif
16021.1Skamil
16031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16051.1Skamil	if (child == 0) {
16061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16081.1Skamil
16091.1Skamil		lookup_me = magic;
16101.1Skamil
16111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16131.1Skamil
16141.13Schristos		DPRINTF("Before exiting of the child process\n");
16151.1Skamil		_exit(exitval);
16161.1Skamil	}
16171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16181.1Skamil
16191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16211.1Skamil
16221.1Skamil	validate_status_stopped(status, sigval);
16231.1Skamil
16241.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16251.1Skamil	    child, getpid());
16261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16271.1Skamil
16281.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16291.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
16301.1Skamil
16311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16321.1Skamil	    "without signal to be sent\n");
16331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16341.1Skamil
16351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16371.1Skamil
16381.1Skamil	validate_status_exited(status, exitval);
16391.1Skamil
16401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16421.1Skamil}
16431.1Skamil
16441.1SkamilATF_TC(io_read_d3);
16451.1SkamilATF_TC_HEAD(io_read_d3, tc)
16461.1Skamil{
16471.1Skamil	atf_tc_set_md_var(tc, "descr",
16481.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
16491.1Skamil}
16501.1Skamil
16511.1SkamilATF_TC_BODY(io_read_d3, tc)
16521.1Skamil{
16531.1Skamil	const int exitval = 5;
16541.1Skamil	const int sigval = SIGSTOP;
16551.1Skamil	pid_t child, wpid;
16561.1Skamil	uint32_t lookup_me = 0;
16571.1Skamil	const uint32_t magic = 0x1234abcd;
16581.1Skamil	struct ptrace_io_desc io = {
16591.1Skamil		.piod_op = PIOD_READ_D,
16601.1Skamil		.piod_offs = &lookup_me,
16611.1Skamil		.piod_addr = &lookup_me,
16621.1Skamil		.piod_len = sizeof(lookup_me)
16631.1Skamil	};
16641.1Skamil#if defined(TWAIT_HAVE_STATUS)
16651.1Skamil	int status;
16661.1Skamil#endif
16671.1Skamil
16681.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16691.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16701.1Skamil	if (child == 0) {
16711.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16721.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16731.1Skamil
16741.1Skamil		lookup_me = magic;
16751.1Skamil
16761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16781.1Skamil
16791.13Schristos		DPRINTF("Before exiting of the child process\n");
16801.1Skamil		_exit(exitval);
16811.1Skamil	}
16821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16831.1Skamil
16841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16861.1Skamil
16871.1Skamil	validate_status_stopped(status, sigval);
16881.1Skamil
16891.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
16901.1Skamil	    child, getpid());
16911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
16921.1Skamil
16931.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
16941.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
16951.1Skamil
16961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16971.1Skamil	    "without signal to be sent\n");
16981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16991.1Skamil
17001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17021.1Skamil
17031.1Skamil	validate_status_exited(status, exitval);
17041.1Skamil
17051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17071.1Skamil}
17081.1Skamil
17091.1SkamilATF_TC(io_read_d4);
17101.1SkamilATF_TC_HEAD(io_read_d4, tc)
17111.1Skamil{
17121.1Skamil	atf_tc_set_md_var(tc, "descr",
17131.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
17141.1Skamil}
17151.1Skamil
17161.1SkamilATF_TC_BODY(io_read_d4, tc)
17171.1Skamil{
17181.1Skamil	const int exitval = 5;
17191.1Skamil	const int sigval = SIGSTOP;
17201.1Skamil	pid_t child, wpid;
17211.1Skamil	uint64_t lookup_me = 0;
17221.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
17231.1Skamil	struct ptrace_io_desc io = {
17241.1Skamil		.piod_op = PIOD_READ_D,
17251.1Skamil		.piod_offs = &lookup_me,
17261.1Skamil		.piod_addr = &lookup_me,
17271.1Skamil		.piod_len = sizeof(lookup_me)
17281.1Skamil	};
17291.1Skamil#if defined(TWAIT_HAVE_STATUS)
17301.1Skamil	int status;
17311.1Skamil#endif
17321.1Skamil
17331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17351.1Skamil	if (child == 0) {
17361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17381.1Skamil
17391.1Skamil		lookup_me = magic;
17401.1Skamil
17411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17431.1Skamil
17441.13Schristos		DPRINTF("Before exiting of the child process\n");
17451.1Skamil		_exit(exitval);
17461.1Skamil	}
17471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17481.1Skamil
17491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17511.1Skamil
17521.1Skamil	validate_status_stopped(status, sigval);
17531.1Skamil
17541.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
17551.1Skamil	    child, getpid());
17561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
17571.1Skamil
17581.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
17591.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
17601.1Skamil
17611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17621.1Skamil	    "without signal to be sent\n");
17631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17641.1Skamil
17651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17671.1Skamil
17681.1Skamil	validate_status_exited(status, exitval);
17691.1Skamil
17701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17721.1Skamil}
17731.1Skamil
17741.1SkamilATF_TC(io_write_d1);
17751.1SkamilATF_TC_HEAD(io_write_d1, tc)
17761.1Skamil{
17771.1Skamil	atf_tc_set_md_var(tc, "descr",
17781.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
17791.1Skamil}
17801.1Skamil
17811.1SkamilATF_TC_BODY(io_write_d1, tc)
17821.1Skamil{
17831.1Skamil	const int exitval = 5;
17841.1Skamil	const int sigval = SIGSTOP;
17851.1Skamil	pid_t child, wpid;
17861.1Skamil	uint8_t lookup_me = 0;
17871.1Skamil	const uint8_t magic = 0xab;
17881.1Skamil	struct ptrace_io_desc io = {
17891.1Skamil		.piod_op = PIOD_WRITE_D,
17901.1Skamil		.piod_offs = &lookup_me,
17911.1Skamil		.piod_addr = &lookup_me,
17921.1Skamil		.piod_len = sizeof(lookup_me)
17931.1Skamil	};
17941.1Skamil#if defined(TWAIT_HAVE_STATUS)
17951.1Skamil	int status;
17961.1Skamil#endif
17971.1Skamil
17981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18001.1Skamil	if (child == 0) {
18011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18031.1Skamil
18041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18061.1Skamil
18071.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
18081.1Skamil
18091.13Schristos		DPRINTF("Before exiting of the child process\n");
18101.1Skamil		_exit(exitval);
18111.1Skamil	}
18121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18131.1Skamil
18141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18161.1Skamil
18171.1Skamil	validate_status_stopped(status, sigval);
18181.1Skamil
18191.1Skamil	lookup_me = magic;
18201.1Skamil
18211.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
18221.1Skamil	    child, getpid());
18231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18241.1Skamil
18251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18261.1Skamil	    "without signal to be sent\n");
18271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18281.1Skamil
18291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18311.1Skamil
18321.1Skamil	validate_status_exited(status, exitval);
18331.1Skamil
18341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18361.1Skamil}
18371.1Skamil
18381.1SkamilATF_TC(io_write_d2);
18391.1SkamilATF_TC_HEAD(io_write_d2, tc)
18401.1Skamil{
18411.1Skamil	atf_tc_set_md_var(tc, "descr",
18421.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
18431.1Skamil}
18441.1Skamil
18451.1SkamilATF_TC_BODY(io_write_d2, tc)
18461.1Skamil{
18471.1Skamil	const int exitval = 5;
18481.1Skamil	const int sigval = SIGSTOP;
18491.1Skamil	pid_t child, wpid;
18501.1Skamil	uint16_t lookup_me = 0;
18511.1Skamil	const uint16_t magic = 0xab12;
18521.1Skamil	struct ptrace_io_desc io = {
18531.1Skamil		.piod_op = PIOD_WRITE_D,
18541.1Skamil		.piod_offs = &lookup_me,
18551.1Skamil		.piod_addr = &lookup_me,
18561.1Skamil		.piod_len = sizeof(lookup_me)
18571.1Skamil	};
18581.1Skamil#if defined(TWAIT_HAVE_STATUS)
18591.1Skamil	int status;
18601.1Skamil#endif
18611.1Skamil
18621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18641.1Skamil	if (child == 0) {
18651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18671.1Skamil
18681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18701.1Skamil
18711.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
18721.1Skamil
18731.13Schristos		DPRINTF("Before exiting of the child process\n");
18741.1Skamil		_exit(exitval);
18751.1Skamil	}
18761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18771.1Skamil
18781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18801.1Skamil
18811.1Skamil	validate_status_stopped(status, sigval);
18821.1Skamil
18831.1Skamil	lookup_me = magic;
18841.1Skamil
18851.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
18861.1Skamil	    child, getpid());
18871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18881.1Skamil
18891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18901.1Skamil	    "without signal to be sent\n");
18911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18921.1Skamil
18931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18951.1Skamil
18961.1Skamil	validate_status_exited(status, exitval);
18971.1Skamil
18981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19001.1Skamil}
19011.1Skamil
19021.1SkamilATF_TC(io_write_d3);
19031.1SkamilATF_TC_HEAD(io_write_d3, tc)
19041.1Skamil{
19051.1Skamil	atf_tc_set_md_var(tc, "descr",
19061.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
19071.1Skamil}
19081.1Skamil
19091.1SkamilATF_TC_BODY(io_write_d3, tc)
19101.1Skamil{
19111.1Skamil	const int exitval = 5;
19121.1Skamil	const int sigval = SIGSTOP;
19131.1Skamil	pid_t child, wpid;
19141.1Skamil	uint32_t lookup_me = 0;
19151.1Skamil	const uint32_t magic = 0xab127643;
19161.1Skamil	struct ptrace_io_desc io = {
19171.1Skamil		.piod_op = PIOD_WRITE_D,
19181.1Skamil		.piod_offs = &lookup_me,
19191.1Skamil		.piod_addr = &lookup_me,
19201.1Skamil		.piod_len = sizeof(lookup_me)
19211.1Skamil	};
19221.1Skamil#if defined(TWAIT_HAVE_STATUS)
19231.1Skamil	int status;
19241.1Skamil#endif
19251.1Skamil
19261.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19271.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19281.1Skamil	if (child == 0) {
19291.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19301.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19311.1Skamil
19321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19341.1Skamil
19351.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
19361.1Skamil
19371.13Schristos		DPRINTF("Before exiting of the child process\n");
19381.1Skamil		_exit(exitval);
19391.1Skamil	}
19401.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19411.1Skamil
19421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19441.1Skamil
19451.1Skamil	validate_status_stopped(status, sigval);
19461.1Skamil
19471.1Skamil	lookup_me = magic;
19481.1Skamil
19491.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
19501.1Skamil	    child, getpid());
19511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19521.1Skamil
19531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19541.1Skamil	    "without signal to be sent\n");
19551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19561.1Skamil
19571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19591.1Skamil
19601.1Skamil	validate_status_exited(status, exitval);
19611.1Skamil
19621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19641.1Skamil}
19651.1Skamil
19661.1SkamilATF_TC(io_write_d4);
19671.1SkamilATF_TC_HEAD(io_write_d4, tc)
19681.1Skamil{
19691.1Skamil	atf_tc_set_md_var(tc, "descr",
19701.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
19711.1Skamil}
19721.1Skamil
19731.1SkamilATF_TC_BODY(io_write_d4, tc)
19741.1Skamil{
19751.1Skamil	const int exitval = 5;
19761.1Skamil	const int sigval = SIGSTOP;
19771.1Skamil	pid_t child, wpid;
19781.1Skamil	uint64_t lookup_me = 0;
19791.1Skamil	const uint64_t magic = 0xab12764376490123;
19801.1Skamil	struct ptrace_io_desc io = {
19811.1Skamil		.piod_op = PIOD_WRITE_D,
19821.1Skamil		.piod_offs = &lookup_me,
19831.1Skamil		.piod_addr = &lookup_me,
19841.1Skamil		.piod_len = sizeof(lookup_me)
19851.1Skamil	};
19861.1Skamil#if defined(TWAIT_HAVE_STATUS)
19871.1Skamil	int status;
19881.1Skamil#endif
19891.1Skamil
19901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19921.1Skamil	if (child == 0) {
19931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19951.1Skamil
19961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19981.1Skamil
19991.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
20001.1Skamil
20011.13Schristos		DPRINTF("Before exiting of the child process\n");
20021.1Skamil		_exit(exitval);
20031.1Skamil	}
20041.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20051.1Skamil
20061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20081.1Skamil
20091.1Skamil	validate_status_stopped(status, sigval);
20101.1Skamil
20111.1Skamil	lookup_me = magic;
20121.1Skamil
20131.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20141.1Skamil	    child, getpid());
20151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20161.1Skamil
20171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20181.1Skamil	    "without signal to be sent\n");
20191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20201.1Skamil
20211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20231.1Skamil
20241.1Skamil	validate_status_exited(status, exitval);
20251.1Skamil
20261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20281.1Skamil}
20291.1Skamil
20301.1SkamilATF_TC(io_read_auxv1);
20311.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
20321.1Skamil{
20331.1Skamil	atf_tc_set_md_var(tc, "descr",
20341.1Skamil	    "Verify PT_READ_AUXV called for tracee");
20351.1Skamil}
20361.1Skamil
20371.1SkamilATF_TC_BODY(io_read_auxv1, tc)
20381.1Skamil{
20391.1Skamil	const int exitval = 5;
20401.1Skamil	const int sigval = SIGSTOP;
20411.1Skamil	pid_t child, wpid;
20421.1Skamil#if defined(TWAIT_HAVE_STATUS)
20431.1Skamil	int status;
20441.1Skamil#endif
20451.1Skamil	AuxInfo ai[100], *aip;
20461.1Skamil	struct ptrace_io_desc io = {
20471.1Skamil		.piod_op = PIOD_READ_AUXV,
20481.1Skamil		.piod_offs = 0,
20491.1Skamil		.piod_addr = ai,
20501.1Skamil		.piod_len = sizeof(ai)
20511.1Skamil	};
20521.1Skamil
20531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20551.1Skamil	if (child == 0) {
20561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20581.1Skamil
20591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20611.1Skamil
20621.13Schristos		DPRINTF("Before exiting of the child process\n");
20631.1Skamil		_exit(exitval);
20641.1Skamil	}
20651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20661.1Skamil
20671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20691.1Skamil
20701.1Skamil	validate_status_stopped(status, sigval);
20711.1Skamil
20721.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
20731.1Skamil	    child, getpid());
20741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20751.1Skamil
20761.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
20771.1Skamil	ATF_REQUIRE(io.piod_len > 0);
20781.1Skamil
20791.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
20801.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
20811.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
20821.1Skamil
20831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20841.1Skamil	    "without signal to be sent\n");
20851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20861.1Skamil
20871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20891.1Skamil
20901.1Skamil	validate_status_exited(status, exitval);
20911.1Skamil
20921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20931.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20941.1Skamil}
20951.1Skamil
20961.1SkamilATF_TC(read_d1);
20971.1SkamilATF_TC_HEAD(read_d1, tc)
20981.1Skamil{
20991.1Skamil	atf_tc_set_md_var(tc, "descr",
21001.1Skamil	    "Verify PT_READ_D called once");
21011.1Skamil}
21021.1Skamil
21031.1SkamilATF_TC_BODY(read_d1, tc)
21041.1Skamil{
21051.1Skamil	const int exitval = 5;
21061.1Skamil	const int sigval = SIGSTOP;
21071.1Skamil	pid_t child, wpid;
21081.1Skamil	int lookup_me = 0;
21091.1Skamil	const int magic = (int)random();
21101.1Skamil#if defined(TWAIT_HAVE_STATUS)
21111.1Skamil	int status;
21121.1Skamil#endif
21131.1Skamil
21141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21161.1Skamil	if (child == 0) {
21171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21191.1Skamil
21201.1Skamil		lookup_me = magic;
21211.1Skamil
21221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21241.1Skamil
21251.13Schristos		DPRINTF("Before exiting of the child process\n");
21261.1Skamil		_exit(exitval);
21271.1Skamil	}
21281.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21291.1Skamil
21301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21321.1Skamil
21331.1Skamil	validate_status_stopped(status, sigval);
21341.1Skamil
21351.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21361.1Skamil	    child, getpid());
21371.1Skamil	errno = 0;
21381.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
21391.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
21401.1Skamil
21411.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21421.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
21431.1Skamil
21441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21451.1Skamil	    "without signal to be sent\n");
21461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21471.1Skamil
21481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21501.1Skamil
21511.1Skamil	validate_status_exited(status, exitval);
21521.1Skamil
21531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21551.1Skamil}
21561.1Skamil
21571.1SkamilATF_TC(read_d2);
21581.1SkamilATF_TC_HEAD(read_d2, tc)
21591.1Skamil{
21601.1Skamil	atf_tc_set_md_var(tc, "descr",
21611.1Skamil	    "Verify PT_READ_D called twice");
21621.1Skamil}
21631.1Skamil
21641.1SkamilATF_TC_BODY(read_d2, tc)
21651.1Skamil{
21661.1Skamil	const int exitval = 5;
21671.1Skamil	const int sigval = SIGSTOP;
21681.1Skamil	pid_t child, wpid;
21691.1Skamil	int lookup_me1 = 0;
21701.1Skamil	int lookup_me2 = 0;
21711.1Skamil	const int magic1 = (int)random();
21721.1Skamil	const int magic2 = (int)random();
21731.1Skamil#if defined(TWAIT_HAVE_STATUS)
21741.1Skamil	int status;
21751.1Skamil#endif
21761.1Skamil
21771.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21781.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21791.1Skamil	if (child == 0) {
21801.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21811.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21821.1Skamil
21831.1Skamil		lookup_me1 = magic1;
21841.1Skamil		lookup_me2 = magic2;
21851.1Skamil
21861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21881.1Skamil
21891.13Schristos		DPRINTF("Before exiting of the child process\n");
21901.1Skamil		_exit(exitval);
21911.1Skamil	}
21921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21931.1Skamil
21941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21961.1Skamil
21971.1Skamil	validate_status_stopped(status, sigval);
21981.1Skamil
21991.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
22001.1Skamil	    child, getpid());
22011.1Skamil	errno = 0;
22021.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
22031.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22041.1Skamil
22051.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
22061.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
22071.1Skamil
22081.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
22091.1Skamil	    child, getpid());
22101.1Skamil	errno = 0;
22111.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
22121.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22131.1Skamil
22141.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
22151.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
22161.1Skamil
22171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22181.1Skamil	    "without signal to be sent\n");
22191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22201.1Skamil
22211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22231.1Skamil
22241.1Skamil	validate_status_exited(status, exitval);
22251.1Skamil
22261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22281.1Skamil}
22291.1Skamil
22301.1SkamilATF_TC(read_d3);
22311.1SkamilATF_TC_HEAD(read_d3, tc)
22321.1Skamil{
22331.1Skamil	atf_tc_set_md_var(tc, "descr",
22341.1Skamil	    "Verify PT_READ_D called three times");
22351.1Skamil}
22361.1Skamil
22371.1SkamilATF_TC_BODY(read_d3, tc)
22381.1Skamil{
22391.1Skamil	const int exitval = 5;
22401.1Skamil	const int sigval = SIGSTOP;
22411.1Skamil	pid_t child, wpid;
22421.1Skamil	int lookup_me1 = 0;
22431.1Skamil	int lookup_me2 = 0;
22441.1Skamil	int lookup_me3 = 0;
22451.1Skamil	const int magic1 = (int)random();
22461.1Skamil	const int magic2 = (int)random();
22471.1Skamil	const int magic3 = (int)random();
22481.1Skamil#if defined(TWAIT_HAVE_STATUS)
22491.1Skamil	int status;
22501.1Skamil#endif
22511.1Skamil
22521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22541.1Skamil	if (child == 0) {
22551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22571.1Skamil
22581.1Skamil		lookup_me1 = magic1;
22591.1Skamil		lookup_me2 = magic2;
22601.1Skamil		lookup_me3 = magic3;
22611.1Skamil
22621.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22631.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22641.1Skamil
22651.13Schristos		DPRINTF("Before exiting of the child process\n");
22661.1Skamil		_exit(exitval);
22671.1Skamil	}
22681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22691.1Skamil
22701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22721.1Skamil
22731.1Skamil	validate_status_stopped(status, sigval);
22741.1Skamil
22751.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
22761.1Skamil	    child, getpid());
22771.1Skamil	errno = 0;
22781.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
22791.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22801.1Skamil
22811.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
22821.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
22831.1Skamil
22841.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
22851.1Skamil	    child, getpid());
22861.1Skamil	errno = 0;
22871.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
22881.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22891.1Skamil
22901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
22911.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
22921.1Skamil
22931.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
22941.1Skamil	    child, getpid());
22951.1Skamil	errno = 0;
22961.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
22971.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
22981.1Skamil
22991.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
23001.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
23011.1Skamil
23021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23031.1Skamil	    "without signal to be sent\n");
23041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23051.1Skamil
23061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23081.1Skamil
23091.1Skamil	validate_status_exited(status, exitval);
23101.1Skamil
23111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23131.1Skamil}
23141.1Skamil
23151.1SkamilATF_TC(read_d4);
23161.1SkamilATF_TC_HEAD(read_d4, tc)
23171.1Skamil{
23181.1Skamil	atf_tc_set_md_var(tc, "descr",
23191.1Skamil	    "Verify PT_READ_D called four times");
23201.1Skamil}
23211.1Skamil
23221.1SkamilATF_TC_BODY(read_d4, tc)
23231.1Skamil{
23241.1Skamil	const int exitval = 5;
23251.1Skamil	const int sigval = SIGSTOP;
23261.1Skamil	pid_t child, wpid;
23271.1Skamil	int lookup_me1 = 0;
23281.1Skamil	int lookup_me2 = 0;
23291.1Skamil	int lookup_me3 = 0;
23301.1Skamil	int lookup_me4 = 0;
23311.1Skamil	const int magic1 = (int)random();
23321.1Skamil	const int magic2 = (int)random();
23331.1Skamil	const int magic3 = (int)random();
23341.1Skamil	const int magic4 = (int)random();
23351.1Skamil#if defined(TWAIT_HAVE_STATUS)
23361.1Skamil	int status;
23371.1Skamil#endif
23381.1Skamil
23391.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23401.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23411.1Skamil	if (child == 0) {
23421.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23431.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23441.1Skamil
23451.1Skamil		lookup_me1 = magic1;
23461.1Skamil		lookup_me2 = magic2;
23471.1Skamil		lookup_me3 = magic3;
23481.1Skamil		lookup_me4 = magic4;
23491.1Skamil
23501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23521.1Skamil
23531.13Schristos		DPRINTF("Before exiting of the child process\n");
23541.1Skamil		_exit(exitval);
23551.1Skamil	}
23561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23571.1Skamil
23581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23601.1Skamil
23611.1Skamil	validate_status_stopped(status, sigval);
23621.1Skamil
23631.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
23641.1Skamil	    child, getpid());
23651.1Skamil	errno = 0;
23661.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
23671.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23681.1Skamil
23691.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
23701.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
23711.1Skamil
23721.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
23731.1Skamil	    child, getpid());
23741.1Skamil	errno = 0;
23751.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
23761.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23771.1Skamil
23781.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
23791.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
23801.1Skamil
23811.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
23821.1Skamil	    child, getpid());
23831.1Skamil	errno = 0;
23841.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
23851.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23861.1Skamil
23871.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
23881.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
23891.1Skamil
23901.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
23911.1Skamil	    child, getpid());
23921.1Skamil	errno = 0;
23931.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
23941.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23951.1Skamil
23961.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
23971.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
23981.1Skamil
23991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24001.1Skamil	    "without signal to be sent\n");
24011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24021.1Skamil
24031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24051.1Skamil
24061.1Skamil	validate_status_exited(status, exitval);
24071.1Skamil
24081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24101.1Skamil}
24111.1Skamil
24121.1SkamilATF_TC(write_d1);
24131.1SkamilATF_TC_HEAD(write_d1, tc)
24141.1Skamil{
24151.1Skamil	atf_tc_set_md_var(tc, "descr",
24161.1Skamil	    "Verify PT_WRITE_D called once");
24171.1Skamil}
24181.1Skamil
24191.1SkamilATF_TC_BODY(write_d1, tc)
24201.1Skamil{
24211.1Skamil	const int exitval = 5;
24221.1Skamil	const int sigval = SIGSTOP;
24231.1Skamil	pid_t child, wpid;
24241.1Skamil	int lookup_me = 0;
24251.1Skamil	const int magic = (int)random();
24261.1Skamil#if defined(TWAIT_HAVE_STATUS)
24271.1Skamil	int status;
24281.1Skamil#endif
24291.1Skamil
24301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24321.1Skamil	if (child == 0) {
24331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24351.1Skamil
24361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24381.1Skamil
24391.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
24401.1Skamil
24411.13Schristos		DPRINTF("Before exiting of the child process\n");
24421.1Skamil		_exit(exitval);
24431.1Skamil	}
24441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24451.1Skamil
24461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24481.1Skamil
24491.1Skamil	validate_status_stopped(status, sigval);
24501.1Skamil
24511.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24521.1Skamil	    child, getpid());
24531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
24541.1Skamil
24551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24561.1Skamil	    "without signal to be sent\n");
24571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24581.1Skamil
24591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24611.1Skamil
24621.1Skamil	validate_status_exited(status, exitval);
24631.1Skamil
24641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24661.1Skamil}
24671.1Skamil
24681.1SkamilATF_TC(write_d2);
24691.1SkamilATF_TC_HEAD(write_d2, tc)
24701.1Skamil{
24711.1Skamil	atf_tc_set_md_var(tc, "descr",
24721.1Skamil	    "Verify PT_WRITE_D called twice");
24731.1Skamil}
24741.1Skamil
24751.1SkamilATF_TC_BODY(write_d2, tc)
24761.1Skamil{
24771.1Skamil	const int exitval = 5;
24781.1Skamil	const int sigval = SIGSTOP;
24791.1Skamil	pid_t child, wpid;
24801.1Skamil	int lookup_me1 = 0;
24811.1Skamil	int lookup_me2 = 0;
24821.1Skamil	const int magic1 = (int)random();
24831.1Skamil	const int magic2 = (int)random();
24841.1Skamil#if defined(TWAIT_HAVE_STATUS)
24851.1Skamil	int status;
24861.1Skamil#endif
24871.1Skamil
24881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24901.1Skamil	if (child == 0) {
24911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24931.1Skamil
24941.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24951.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24961.1Skamil
24971.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
24981.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
24991.1Skamil
25001.13Schristos		DPRINTF("Before exiting of the child process\n");
25011.1Skamil		_exit(exitval);
25021.1Skamil	}
25031.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25041.1Skamil
25051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25071.1Skamil
25081.1Skamil	validate_status_stopped(status, sigval);
25091.1Skamil
25101.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
25111.1Skamil	    child, getpid());
25121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
25131.1Skamil
25141.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
25151.1Skamil	    child, getpid());
25161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
25171.1Skamil
25181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25191.1Skamil	    "without signal to be sent\n");
25201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25211.1Skamil
25221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25241.1Skamil
25251.1Skamil	validate_status_exited(status, exitval);
25261.1Skamil
25271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25281.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25291.1Skamil}
25301.1Skamil
25311.1SkamilATF_TC(write_d3);
25321.1SkamilATF_TC_HEAD(write_d3, tc)
25331.1Skamil{
25341.1Skamil	atf_tc_set_md_var(tc, "descr",
25351.1Skamil	    "Verify PT_WRITE_D called three times");
25361.1Skamil}
25371.1Skamil
25381.1SkamilATF_TC_BODY(write_d3, tc)
25391.1Skamil{
25401.1Skamil	const int exitval = 5;
25411.1Skamil	const int sigval = SIGSTOP;
25421.1Skamil	pid_t child, wpid;
25431.1Skamil	int lookup_me1 = 0;
25441.1Skamil	int lookup_me2 = 0;
25451.1Skamil	int lookup_me3 = 0;
25461.1Skamil	const int magic1 = (int)random();
25471.1Skamil	const int magic2 = (int)random();
25481.1Skamil	const int magic3 = (int)random();
25491.1Skamil#if defined(TWAIT_HAVE_STATUS)
25501.1Skamil	int status;
25511.1Skamil#endif
25521.1Skamil
25531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25551.1Skamil	if (child == 0) {
25561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25581.1Skamil
25591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25611.1Skamil
25621.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
25631.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
25641.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
25651.1Skamil
25661.13Schristos		DPRINTF("Before exiting of the child process\n");
25671.1Skamil		_exit(exitval);
25681.1Skamil	}
25691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25701.1Skamil
25711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25731.1Skamil
25741.1Skamil	validate_status_stopped(status, sigval);
25751.1Skamil
25761.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
25771.1Skamil	    child, getpid());
25781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
25791.1Skamil
25801.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
25811.1Skamil	    child, getpid());
25821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
25831.1Skamil
25841.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
25851.1Skamil	    child, getpid());
25861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
25871.1Skamil
25881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25891.1Skamil	    "without signal to be sent\n");
25901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25911.1Skamil
25921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25941.1Skamil
25951.1Skamil	validate_status_exited(status, exitval);
25961.1Skamil
25971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25991.1Skamil}
26001.1Skamil
26011.1SkamilATF_TC(write_d4);
26021.1SkamilATF_TC_HEAD(write_d4, tc)
26031.1Skamil{
26041.1Skamil	atf_tc_set_md_var(tc, "descr",
26051.1Skamil	    "Verify PT_WRITE_D called four times");
26061.1Skamil}
26071.1Skamil
26081.1SkamilATF_TC_BODY(write_d4, tc)
26091.1Skamil{
26101.1Skamil	const int exitval = 5;
26111.1Skamil	const int sigval = SIGSTOP;
26121.1Skamil	pid_t child, wpid;
26131.1Skamil	int lookup_me1 = 0;
26141.1Skamil	int lookup_me2 = 0;
26151.1Skamil	int lookup_me3 = 0;
26161.1Skamil	int lookup_me4 = 0;
26171.1Skamil	const int magic1 = (int)random();
26181.1Skamil	const int magic2 = (int)random();
26191.1Skamil	const int magic3 = (int)random();
26201.1Skamil	const int magic4 = (int)random();
26211.1Skamil#if defined(TWAIT_HAVE_STATUS)
26221.1Skamil	int status;
26231.1Skamil#endif
26241.1Skamil
26251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26271.1Skamil	if (child == 0) {
26281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26301.1Skamil
26311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26331.1Skamil
26341.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26351.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26361.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
26371.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
26381.1Skamil
26391.13Schristos		DPRINTF("Before exiting of the child process\n");
26401.1Skamil		_exit(exitval);
26411.1Skamil	}
26421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26431.1Skamil
26441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26461.1Skamil
26471.1Skamil	validate_status_stopped(status, sigval);
26481.1Skamil
26491.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
26501.1Skamil	    child, getpid());
26511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
26521.1Skamil
26531.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
26541.1Skamil	    child, getpid());
26551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
26561.1Skamil
26571.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
26581.1Skamil	    child, getpid());
26591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
26601.1Skamil
26611.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
26621.1Skamil	    child, getpid());
26631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
26641.1Skamil
26651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26661.1Skamil	    "without signal to be sent\n");
26671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26681.1Skamil
26691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26711.1Skamil
26721.1Skamil	validate_status_exited(status, exitval);
26731.1Skamil
26741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26761.1Skamil}
26771.1Skamil
26781.1SkamilATF_TC(io_read_d_write_d_handshake1);
26791.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
26801.1Skamil{
26811.1Skamil	atf_tc_set_md_var(tc, "descr",
26821.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
26831.1Skamil}
26841.1Skamil
26851.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
26861.1Skamil{
26871.1Skamil	const int exitval = 5;
26881.1Skamil	const int sigval = SIGSTOP;
26891.1Skamil	pid_t child, wpid;
26901.1Skamil	uint8_t lookup_me_fromtracee = 0;
26911.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
26921.1Skamil	uint8_t lookup_me_totracee = 0;
26931.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
26941.1Skamil	struct ptrace_io_desc io_fromtracee = {
26951.1Skamil		.piod_op = PIOD_READ_D,
26961.1Skamil		.piod_offs = &lookup_me_fromtracee,
26971.1Skamil		.piod_addr = &lookup_me_fromtracee,
26981.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
26991.1Skamil	};
27001.1Skamil	struct ptrace_io_desc io_totracee = {
27011.1Skamil		.piod_op = PIOD_WRITE_D,
27021.1Skamil		.piod_offs = &lookup_me_totracee,
27031.1Skamil		.piod_addr = &lookup_me_totracee,
27041.1Skamil		.piod_len = sizeof(lookup_me_totracee)
27051.1Skamil	};
27061.1Skamil#if defined(TWAIT_HAVE_STATUS)
27071.1Skamil	int status;
27081.1Skamil#endif
27091.1Skamil
27101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27121.1Skamil	if (child == 0) {
27131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27151.1Skamil
27161.1Skamil		lookup_me_fromtracee = magic_fromtracee;
27171.1Skamil
27181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27201.1Skamil
27211.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
27221.1Skamil
27231.13Schristos		DPRINTF("Before exiting of the child process\n");
27241.1Skamil		_exit(exitval);
27251.1Skamil	}
27261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27271.1Skamil
27281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27301.1Skamil
27311.1Skamil	validate_status_stopped(status, sigval);
27321.1Skamil
27331.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
27341.1Skamil	    child, getpid());
27351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
27361.1Skamil
27371.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
27381.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
27391.1Skamil	    magic_fromtracee);
27401.1Skamil
27411.1Skamil	lookup_me_totracee = magic_totracee;
27421.1Skamil
27431.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
27441.1Skamil	    child, getpid());
27451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
27461.1Skamil
27471.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
27481.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
27491.1Skamil	    magic_totracee);
27501.1Skamil
27511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27521.1Skamil	    "without signal to be sent\n");
27531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27541.1Skamil
27551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27571.1Skamil
27581.1Skamil	validate_status_exited(status, exitval);
27591.1Skamil
27601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27621.1Skamil}
27631.1Skamil
27641.1SkamilATF_TC(io_read_d_write_d_handshake2);
27651.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
27661.1Skamil{
27671.1Skamil	atf_tc_set_md_var(tc, "descr",
27681.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
27691.1Skamil}
27701.1Skamil
27711.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
27721.1Skamil{
27731.1Skamil	const int exitval = 5;
27741.1Skamil	const int sigval = SIGSTOP;
27751.1Skamil	pid_t child, wpid;
27761.1Skamil	uint8_t lookup_me_fromtracee = 0;
27771.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
27781.1Skamil	uint8_t lookup_me_totracee = 0;
27791.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
27801.1Skamil	struct ptrace_io_desc io_fromtracee = {
27811.1Skamil		.piod_op = PIOD_READ_D,
27821.1Skamil		.piod_offs = &lookup_me_fromtracee,
27831.1Skamil		.piod_addr = &lookup_me_fromtracee,
27841.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
27851.1Skamil	};
27861.1Skamil	struct ptrace_io_desc io_totracee = {
27871.1Skamil		.piod_op = PIOD_WRITE_D,
27881.1Skamil		.piod_offs = &lookup_me_totracee,
27891.1Skamil		.piod_addr = &lookup_me_totracee,
27901.1Skamil		.piod_len = sizeof(lookup_me_totracee)
27911.1Skamil	};
27921.1Skamil#if defined(TWAIT_HAVE_STATUS)
27931.1Skamil	int status;
27941.1Skamil#endif
27951.1Skamil
27961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27981.1Skamil	if (child == 0) {
27991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28011.1Skamil
28021.1Skamil		lookup_me_fromtracee = magic_fromtracee;
28031.1Skamil
28041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28061.1Skamil
28071.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
28081.1Skamil
28091.13Schristos		DPRINTF("Before exiting of the child process\n");
28101.1Skamil		_exit(exitval);
28111.1Skamil	}
28121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28131.1Skamil
28141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28161.1Skamil
28171.1Skamil	validate_status_stopped(status, sigval);
28181.1Skamil
28191.1Skamil	lookup_me_totracee = magic_totracee;
28201.1Skamil
28211.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
28221.1Skamil	    child, getpid());
28231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
28241.1Skamil
28251.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
28261.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
28271.1Skamil	    magic_totracee);
28281.1Skamil
28291.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
28301.1Skamil	    child, getpid());
28311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
28321.1Skamil
28331.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
28341.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
28351.1Skamil	    magic_fromtracee);
28361.1Skamil
28371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28381.1Skamil	    "without signal to be sent\n");
28391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28401.1Skamil
28411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28431.1Skamil
28441.1Skamil	validate_status_exited(status, exitval);
28451.1Skamil
28461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28481.1Skamil}
28491.1Skamil
28501.1SkamilATF_TC(read_d_write_d_handshake1);
28511.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
28521.1Skamil{
28531.1Skamil	atf_tc_set_md_var(tc, "descr",
28541.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
28551.1Skamil}
28561.1Skamil
28571.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
28581.1Skamil{
28591.1Skamil	const int exitval = 5;
28601.1Skamil	const int sigval = SIGSTOP;
28611.1Skamil	pid_t child, wpid;
28621.1Skamil	int lookup_me_fromtracee = 0;
28631.1Skamil	const int magic_fromtracee = (int)random();
28641.1Skamil	int lookup_me_totracee = 0;
28651.1Skamil	const int magic_totracee = (int)random();
28661.1Skamil#if defined(TWAIT_HAVE_STATUS)
28671.1Skamil	int status;
28681.1Skamil#endif
28691.1Skamil
28701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28721.1Skamil	if (child == 0) {
28731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28751.1Skamil
28761.1Skamil		lookup_me_fromtracee = magic_fromtracee;
28771.1Skamil
28781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28801.1Skamil
28811.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
28821.1Skamil
28831.13Schristos		DPRINTF("Before exiting of the child process\n");
28841.1Skamil		_exit(exitval);
28851.1Skamil	}
28861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28871.1Skamil
28881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28901.1Skamil
28911.1Skamil	validate_status_stopped(status, sigval);
28921.1Skamil
28931.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
28941.1Skamil	    child, getpid());
28951.1Skamil	errno = 0;
28961.1Skamil	lookup_me_fromtracee =
28971.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
28981.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
28991.1Skamil
29001.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29011.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
29021.1Skamil	    magic_fromtracee);
29031.1Skamil
29041.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
29051.1Skamil	    child, getpid());
29061.1Skamil	ATF_REQUIRE
29071.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
29081.1Skamil	    != -1);
29091.1Skamil
29101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29111.1Skamil	    "without signal to be sent\n");
29121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29131.1Skamil
29141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29161.1Skamil
29171.1Skamil	validate_status_exited(status, exitval);
29181.1Skamil
29191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29211.1Skamil}
29221.1Skamil
29231.1SkamilATF_TC(read_d_write_d_handshake2);
29241.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
29251.1Skamil{
29261.1Skamil	atf_tc_set_md_var(tc, "descr",
29271.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
29281.1Skamil}
29291.1Skamil
29301.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
29311.1Skamil{
29321.1Skamil	const int exitval = 5;
29331.1Skamil	const int sigval = SIGSTOP;
29341.1Skamil	pid_t child, wpid;
29351.1Skamil	int lookup_me_fromtracee = 0;
29361.1Skamil	const int magic_fromtracee = (int)random();
29371.1Skamil	int lookup_me_totracee = 0;
29381.1Skamil	const int magic_totracee = (int)random();
29391.1Skamil#if defined(TWAIT_HAVE_STATUS)
29401.1Skamil	int status;
29411.1Skamil#endif
29421.1Skamil
29431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29451.1Skamil	if (child == 0) {
29461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29481.1Skamil
29491.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29501.1Skamil
29511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29531.1Skamil
29541.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
29551.1Skamil
29561.13Schristos		DPRINTF("Before exiting of the child process\n");
29571.1Skamil		_exit(exitval);
29581.1Skamil	}
29591.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29601.1Skamil
29611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29631.1Skamil
29641.1Skamil	validate_status_stopped(status, sigval);
29651.1Skamil
29661.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
29671.1Skamil	    child, getpid());
29681.1Skamil	ATF_REQUIRE
29691.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
29701.1Skamil	    != -1);
29711.1Skamil
29721.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
29731.1Skamil	    child, getpid());
29741.1Skamil	errno = 0;
29751.1Skamil	lookup_me_fromtracee =
29761.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
29771.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
29781.1Skamil
29791.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29801.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
29811.1Skamil	    magic_fromtracee);
29821.1Skamil
29831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29841.1Skamil	    "without signal to be sent\n");
29851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29861.1Skamil
29871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29891.1Skamil
29901.1Skamil	validate_status_exited(status, exitval);
29911.1Skamil
29921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29931.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29941.1Skamil}
29951.1Skamil
29961.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
29971.1Skamilstatic int __used
29981.1Skamildummy_fn1(int a, int b, int c, int d)
29991.1Skamil{
30001.1Skamil
30011.1Skamil	a *= 1;
30021.1Skamil	b += 2;
30031.1Skamil	c -= 3;
30041.1Skamil	d /= 4;
30051.1Skamil
30061.1Skamil	return a + b * c - d;
30071.1Skamil}
30081.1Skamil
30091.1Skamilstatic int __used
30101.1Skamildummy_fn2(int a, int b, int c, int d)
30111.1Skamil{
30121.1Skamil
30131.1Skamil	a *= 4;
30141.1Skamil	b += 3;
30151.1Skamil	c -= 2;
30161.1Skamil	d /= 1;
30171.1Skamil
30181.1Skamil	return a + b * c - d;
30191.1Skamil}
30201.1Skamil
30211.1Skamilstatic int __used
30221.1Skamildummy_fn3(int a, int b, int c, int d)
30231.1Skamil{
30241.1Skamil
30251.1Skamil	a *= 10;
30261.1Skamil	b += 20;
30271.1Skamil	c -= 30;
30281.1Skamil	d /= 40;
30291.1Skamil
30301.1Skamil	return a + b * c - d;
30311.1Skamil}
30321.1Skamil
30331.1Skamilstatic int __used
30341.1Skamildummy_fn4(int a, int b, int c, int d)
30351.1Skamil{
30361.1Skamil
30371.1Skamil	a *= 40;
30381.1Skamil	b += 30;
30391.1Skamil	c -= 20;
30401.1Skamil	d /= 10;
30411.1Skamil
30421.1Skamil	return a + b * c - d;
30431.1Skamil}
30441.1Skamil
30451.1SkamilATF_TC(io_read_i1);
30461.1SkamilATF_TC_HEAD(io_read_i1, tc)
30471.1Skamil{
30481.1Skamil	atf_tc_set_md_var(tc, "descr",
30491.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
30501.1Skamil}
30511.1Skamil
30521.1SkamilATF_TC_BODY(io_read_i1, tc)
30531.1Skamil{
30541.1Skamil	const int exitval = 5;
30551.1Skamil	const int sigval = SIGSTOP;
30561.1Skamil	pid_t child, wpid;
30571.1Skamil	uint8_t lookup_me = 0;
30581.1Skamil	uint8_t magic;
30591.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
30601.1Skamil	struct ptrace_io_desc io = {
30611.1Skamil		.piod_op = PIOD_READ_I,
30621.1Skamil		.piod_offs = dummy_fn1,
30631.1Skamil		.piod_addr = &lookup_me,
30641.1Skamil		.piod_len = sizeof(lookup_me)
30651.1Skamil	};
30661.1Skamil#if defined(TWAIT_HAVE_STATUS)
30671.1Skamil	int status;
30681.1Skamil#endif
30691.1Skamil
30701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30721.1Skamil	if (child == 0) {
30731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30751.1Skamil
30761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30781.1Skamil
30791.13Schristos		DPRINTF("Before exiting of the child process\n");
30801.1Skamil		_exit(exitval);
30811.1Skamil	}
30821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30831.1Skamil
30841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30861.1Skamil
30871.1Skamil	validate_status_stopped(status, sigval);
30881.1Skamil
30891.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
30901.1Skamil	    child, getpid());
30911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
30921.1Skamil
30931.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
30941.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
30951.1Skamil
30961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30971.1Skamil	    "without signal to be sent\n");
30981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30991.1Skamil
31001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31021.1Skamil
31031.1Skamil	validate_status_exited(status, exitval);
31041.1Skamil
31051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31071.1Skamil}
31081.1Skamil
31091.1SkamilATF_TC(io_read_i2);
31101.1SkamilATF_TC_HEAD(io_read_i2, tc)
31111.1Skamil{
31121.1Skamil	atf_tc_set_md_var(tc, "descr",
31131.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
31141.1Skamil}
31151.1Skamil
31161.1SkamilATF_TC_BODY(io_read_i2, tc)
31171.1Skamil{
31181.1Skamil	const int exitval = 5;
31191.1Skamil	const int sigval = SIGSTOP;
31201.1Skamil	pid_t child, wpid;
31211.1Skamil	uint16_t lookup_me = 0;
31221.1Skamil	uint16_t magic;
31231.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31241.1Skamil	struct ptrace_io_desc io = {
31251.1Skamil		.piod_op = PIOD_READ_I,
31261.1Skamil		.piod_offs = dummy_fn1,
31271.1Skamil		.piod_addr = &lookup_me,
31281.1Skamil		.piod_len = sizeof(lookup_me)
31291.1Skamil	};
31301.1Skamil#if defined(TWAIT_HAVE_STATUS)
31311.1Skamil	int status;
31321.1Skamil#endif
31331.1Skamil
31341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31361.1Skamil	if (child == 0) {
31371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31391.1Skamil
31401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31421.1Skamil
31431.13Schristos		DPRINTF("Before exiting of the child process\n");
31441.1Skamil		_exit(exitval);
31451.1Skamil	}
31461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31471.1Skamil
31481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31501.1Skamil
31511.1Skamil	validate_status_stopped(status, sigval);
31521.1Skamil
31531.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
31541.1Skamil	    child, getpid());
31551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
31561.1Skamil
31571.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
31581.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
31591.1Skamil
31601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31611.1Skamil	    "without signal to be sent\n");
31621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31631.1Skamil
31641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31661.1Skamil
31671.1Skamil	validate_status_exited(status, exitval);
31681.1Skamil
31691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31711.1Skamil}
31721.1Skamil
31731.1SkamilATF_TC(io_read_i3);
31741.1SkamilATF_TC_HEAD(io_read_i3, tc)
31751.1Skamil{
31761.1Skamil	atf_tc_set_md_var(tc, "descr",
31771.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
31781.1Skamil}
31791.1Skamil
31801.1SkamilATF_TC_BODY(io_read_i3, tc)
31811.1Skamil{
31821.1Skamil	const int exitval = 5;
31831.1Skamil	const int sigval = SIGSTOP;
31841.1Skamil	pid_t child, wpid;
31851.1Skamil	uint32_t lookup_me = 0;
31861.1Skamil	uint32_t magic;
31871.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
31881.1Skamil	struct ptrace_io_desc io = {
31891.1Skamil		.piod_op = PIOD_READ_I,
31901.1Skamil		.piod_offs = dummy_fn1,
31911.1Skamil		.piod_addr = &lookup_me,
31921.1Skamil		.piod_len = sizeof(lookup_me)
31931.1Skamil	};
31941.1Skamil#if defined(TWAIT_HAVE_STATUS)
31951.1Skamil	int status;
31961.1Skamil#endif
31971.1Skamil
31981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32001.1Skamil	if (child == 0) {
32011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32031.1Skamil
32041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32061.1Skamil
32071.13Schristos		DPRINTF("Before exiting of the child process\n");
32081.1Skamil		_exit(exitval);
32091.1Skamil	}
32101.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32111.1Skamil
32121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32141.1Skamil
32151.1Skamil	validate_status_stopped(status, sigval);
32161.1Skamil
32171.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32181.1Skamil	    child, getpid());
32191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32201.1Skamil
32211.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32221.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
32231.1Skamil
32241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32251.1Skamil	    "without signal to be sent\n");
32261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32271.1Skamil
32281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32301.1Skamil
32311.1Skamil	validate_status_exited(status, exitval);
32321.1Skamil
32331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32351.1Skamil}
32361.1Skamil
32371.1SkamilATF_TC(io_read_i4);
32381.1SkamilATF_TC_HEAD(io_read_i4, tc)
32391.1Skamil{
32401.1Skamil	atf_tc_set_md_var(tc, "descr",
32411.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
32421.1Skamil}
32431.1Skamil
32441.1SkamilATF_TC_BODY(io_read_i4, tc)
32451.1Skamil{
32461.1Skamil	const int exitval = 5;
32471.1Skamil	const int sigval = SIGSTOP;
32481.1Skamil	pid_t child, wpid;
32491.1Skamil	uint64_t lookup_me = 0;
32501.1Skamil	uint64_t magic;
32511.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
32521.1Skamil	struct ptrace_io_desc io = {
32531.1Skamil		.piod_op = PIOD_READ_I,
32541.1Skamil		.piod_offs = dummy_fn1,
32551.1Skamil		.piod_addr = &lookup_me,
32561.1Skamil		.piod_len = sizeof(lookup_me)
32571.1Skamil	};
32581.1Skamil#if defined(TWAIT_HAVE_STATUS)
32591.1Skamil	int status;
32601.1Skamil#endif
32611.1Skamil
32621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32641.1Skamil	if (child == 0) {
32651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32671.1Skamil
32681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32701.1Skamil
32711.13Schristos		DPRINTF("Before exiting of the child process\n");
32721.1Skamil		_exit(exitval);
32731.1Skamil	}
32741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32751.1Skamil
32761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32781.1Skamil
32791.1Skamil	validate_status_stopped(status, sigval);
32801.1Skamil
32811.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32821.1Skamil	    child, getpid());
32831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32841.1Skamil
32851.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32861.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
32871.1Skamil
32881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32891.1Skamil	    "without signal to be sent\n");
32901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32911.1Skamil
32921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32941.1Skamil
32951.1Skamil	validate_status_exited(status, exitval);
32961.1Skamil
32971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32991.1Skamil}
33001.1Skamil
33011.1SkamilATF_TC(read_i1);
33021.1SkamilATF_TC_HEAD(read_i1, tc)
33031.1Skamil{
33041.1Skamil	atf_tc_set_md_var(tc, "descr",
33051.1Skamil	    "Verify PT_READ_I called once");
33061.1Skamil}
33071.1Skamil
33081.1SkamilATF_TC_BODY(read_i1, tc)
33091.1Skamil{
33101.1Skamil	const int exitval = 5;
33111.1Skamil	const int sigval = SIGSTOP;
33121.1Skamil	pid_t child, wpid;
33131.1Skamil	int lookup_me = 0;
33141.1Skamil	int magic;
33151.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33161.1Skamil#if defined(TWAIT_HAVE_STATUS)
33171.1Skamil	int status;
33181.1Skamil#endif
33191.1Skamil
33201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33221.1Skamil	if (child == 0) {
33231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33251.1Skamil
33261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33281.1Skamil
33291.13Schristos		DPRINTF("Before exiting of the child process\n");
33301.1Skamil		_exit(exitval);
33311.1Skamil	}
33321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33331.1Skamil
33341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33361.1Skamil
33371.1Skamil	validate_status_stopped(status, sigval);
33381.1Skamil
33391.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33401.1Skamil	    child, getpid());
33411.1Skamil	errno = 0;
33421.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
33431.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33441.1Skamil
33451.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33461.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
33471.1Skamil
33481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33491.1Skamil	    "without signal to be sent\n");
33501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33511.1Skamil
33521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33541.1Skamil
33551.1Skamil	validate_status_exited(status, exitval);
33561.1Skamil
33571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33591.1Skamil}
33601.1Skamil
33611.1SkamilATF_TC(read_i2);
33621.1SkamilATF_TC_HEAD(read_i2, tc)
33631.1Skamil{
33641.1Skamil	atf_tc_set_md_var(tc, "descr",
33651.1Skamil	    "Verify PT_READ_I called twice");
33661.1Skamil}
33671.1Skamil
33681.1SkamilATF_TC_BODY(read_i2, tc)
33691.1Skamil{
33701.1Skamil	const int exitval = 5;
33711.1Skamil	const int sigval = SIGSTOP;
33721.1Skamil	pid_t child, wpid;
33731.1Skamil	int lookup_me1 = 0;
33741.1Skamil	int lookup_me2 = 0;
33751.1Skamil	int magic1;
33761.1Skamil	int magic2;
33771.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
33781.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
33791.1Skamil#if defined(TWAIT_HAVE_STATUS)
33801.1Skamil	int status;
33811.1Skamil#endif
33821.1Skamil
33831.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33841.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33851.1Skamil	if (child == 0) {
33861.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33871.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33881.1Skamil
33891.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33901.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33911.1Skamil
33921.13Schristos		DPRINTF("Before exiting of the child process\n");
33931.1Skamil		_exit(exitval);
33941.1Skamil	}
33951.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33961.1Skamil
33971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33991.1Skamil
34001.1Skamil	validate_status_stopped(status, sigval);
34011.1Skamil
34021.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
34031.1Skamil	    child, getpid());
34041.1Skamil	errno = 0;
34051.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
34061.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34071.1Skamil
34081.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
34091.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
34101.1Skamil
34111.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
34121.1Skamil	    child, getpid());
34131.1Skamil	errno = 0;
34141.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
34151.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34161.1Skamil
34171.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
34181.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
34191.1Skamil
34201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34211.1Skamil	    "without signal to be sent\n");
34221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34231.1Skamil
34241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34261.1Skamil
34271.1Skamil	validate_status_exited(status, exitval);
34281.1Skamil
34291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34311.1Skamil}
34321.1Skamil
34331.1SkamilATF_TC(read_i3);
34341.1SkamilATF_TC_HEAD(read_i3, tc)
34351.1Skamil{
34361.1Skamil	atf_tc_set_md_var(tc, "descr",
34371.1Skamil	    "Verify PT_READ_I called three times");
34381.1Skamil}
34391.1Skamil
34401.1SkamilATF_TC_BODY(read_i3, tc)
34411.1Skamil{
34421.1Skamil	const int exitval = 5;
34431.1Skamil	const int sigval = SIGSTOP;
34441.1Skamil	pid_t child, wpid;
34451.1Skamil	int lookup_me1 = 0;
34461.1Skamil	int lookup_me2 = 0;
34471.1Skamil	int lookup_me3 = 0;
34481.1Skamil	int magic1;
34491.1Skamil	int magic2;
34501.1Skamil	int magic3;
34511.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
34521.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
34531.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
34541.1Skamil#if defined(TWAIT_HAVE_STATUS)
34551.1Skamil	int status;
34561.1Skamil#endif
34571.1Skamil
34581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34601.1Skamil	if (child == 0) {
34611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34631.1Skamil
34641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34661.1Skamil
34671.13Schristos		DPRINTF("Before exiting of the child process\n");
34681.1Skamil		_exit(exitval);
34691.1Skamil	}
34701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34711.1Skamil
34721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34741.1Skamil
34751.1Skamil	validate_status_stopped(status, sigval);
34761.1Skamil
34771.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
34781.1Skamil	    child, getpid());
34791.1Skamil	errno = 0;
34801.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
34811.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34821.1Skamil
34831.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
34841.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
34851.1Skamil
34861.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
34871.1Skamil	    child, getpid());
34881.1Skamil	errno = 0;
34891.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
34901.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
34911.1Skamil
34921.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
34931.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
34941.1Skamil
34951.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
34961.1Skamil	    child, getpid());
34971.1Skamil	errno = 0;
34981.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
34991.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35001.1Skamil
35011.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
35021.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
35031.1Skamil
35041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35051.1Skamil	    "without signal to be sent\n");
35061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35071.1Skamil
35081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35101.1Skamil
35111.1Skamil	validate_status_exited(status, exitval);
35121.1Skamil
35131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35151.1Skamil}
35161.1Skamil
35171.1SkamilATF_TC(read_i4);
35181.1SkamilATF_TC_HEAD(read_i4, tc)
35191.1Skamil{
35201.1Skamil	atf_tc_set_md_var(tc, "descr",
35211.1Skamil	    "Verify PT_READ_I called four times");
35221.1Skamil}
35231.1Skamil
35241.1SkamilATF_TC_BODY(read_i4, tc)
35251.1Skamil{
35261.1Skamil	const int exitval = 5;
35271.1Skamil	const int sigval = SIGSTOP;
35281.1Skamil	pid_t child, wpid;
35291.1Skamil	int lookup_me1 = 0;
35301.1Skamil	int lookup_me2 = 0;
35311.1Skamil	int lookup_me3 = 0;
35321.1Skamil	int lookup_me4 = 0;
35331.1Skamil	int magic1;
35341.1Skamil	int magic2;
35351.1Skamil	int magic3;
35361.1Skamil	int magic4;
35371.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35381.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
35391.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
35401.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
35411.1Skamil#if defined(TWAIT_HAVE_STATUS)
35421.1Skamil	int status;
35431.1Skamil#endif
35441.1Skamil
35451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35471.1Skamil	if (child == 0) {
35481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35501.1Skamil
35511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35531.1Skamil
35541.13Schristos		DPRINTF("Before exiting of the child process\n");
35551.1Skamil		_exit(exitval);
35561.1Skamil	}
35571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35581.1Skamil
35591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35611.1Skamil
35621.1Skamil	validate_status_stopped(status, sigval);
35631.1Skamil
35641.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
35651.1Skamil	    child, getpid());
35661.1Skamil	errno = 0;
35671.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
35681.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35691.1Skamil
35701.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
35711.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
35721.1Skamil
35731.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
35741.1Skamil	    child, getpid());
35751.1Skamil	errno = 0;
35761.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
35771.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35781.1Skamil
35791.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
35801.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
35811.1Skamil
35821.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
35831.1Skamil	    child, getpid());
35841.1Skamil	errno = 0;
35851.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
35861.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35871.1Skamil
35881.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
35891.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
35901.1Skamil
35911.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
35921.1Skamil	    child, getpid());
35931.1Skamil	errno = 0;
35941.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
35951.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35961.1Skamil
35971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
35981.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
35991.1Skamil
36001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36011.1Skamil	    "without signal to be sent\n");
36021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36031.1Skamil
36041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36061.1Skamil
36071.1Skamil	validate_status_exited(status, exitval);
36081.1Skamil
36091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36111.1Skamil}
36121.1Skamil
36131.1Skamil#if defined(HAVE_GPREGS)
36141.1SkamilATF_TC(regs1);
36151.1SkamilATF_TC_HEAD(regs1, tc)
36161.1Skamil{
36171.1Skamil	atf_tc_set_md_var(tc, "descr",
36181.1Skamil	    "Verify plain PT_GETREGS call without further steps");
36191.1Skamil}
36201.1Skamil
36211.1SkamilATF_TC_BODY(regs1, tc)
36221.1Skamil{
36231.1Skamil	const int exitval = 5;
36241.1Skamil	const int sigval = SIGSTOP;
36251.1Skamil	pid_t child, wpid;
36261.1Skamil#if defined(TWAIT_HAVE_STATUS)
36271.1Skamil	int status;
36281.1Skamil#endif
36291.1Skamil	struct reg r;
36301.1Skamil
36311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36331.1Skamil	if (child == 0) {
36341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36361.1Skamil
36371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36391.1Skamil
36401.13Schristos		DPRINTF("Before exiting of the child process\n");
36411.1Skamil		_exit(exitval);
36421.1Skamil	}
36431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36441.1Skamil
36451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36471.1Skamil
36481.1Skamil	validate_status_stopped(status, sigval);
36491.1Skamil
36501.13Schristos	DPRINTF("Call GETREGS for the child process\n");
36511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
36521.1Skamil
36531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36541.1Skamil	    "without signal to be sent\n");
36551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36561.1Skamil
36571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36591.1Skamil
36601.1Skamil	validate_status_exited(status, exitval);
36611.1Skamil
36621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36641.1Skamil}
36651.1Skamil#endif
36661.1Skamil
36671.1Skamil#if defined(HAVE_GPREGS)
36681.1SkamilATF_TC(regs2);
36691.1SkamilATF_TC_HEAD(regs2, tc)
36701.1Skamil{
36711.1Skamil	atf_tc_set_md_var(tc, "descr",
36721.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
36731.1Skamil}
36741.1Skamil
36751.1SkamilATF_TC_BODY(regs2, tc)
36761.1Skamil{
36771.1Skamil	const int exitval = 5;
36781.1Skamil	const int sigval = SIGSTOP;
36791.1Skamil	pid_t child, wpid;
36801.1Skamil#if defined(TWAIT_HAVE_STATUS)
36811.1Skamil	int status;
36821.1Skamil#endif
36831.1Skamil	struct reg r;
36841.1Skamil
36851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36871.1Skamil	if (child == 0) {
36881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36901.1Skamil
36911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36931.1Skamil
36941.13Schristos		DPRINTF("Before exiting of the child process\n");
36951.1Skamil		_exit(exitval);
36961.1Skamil	}
36971.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36981.1Skamil
36991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37011.1Skamil
37021.1Skamil	validate_status_stopped(status, sigval);
37031.1Skamil
37041.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37061.1Skamil
37071.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
37081.1Skamil
37091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37101.1Skamil	    "without signal to be sent\n");
37111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37121.1Skamil
37131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37151.1Skamil
37161.1Skamil	validate_status_exited(status, exitval);
37171.1Skamil
37181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37201.1Skamil}
37211.1Skamil#endif
37221.1Skamil
37231.1Skamil#if defined(HAVE_GPREGS)
37241.1SkamilATF_TC(regs3);
37251.1SkamilATF_TC_HEAD(regs3, tc)
37261.1Skamil{
37271.1Skamil	atf_tc_set_md_var(tc, "descr",
37281.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
37291.1Skamil}
37301.1Skamil
37311.1SkamilATF_TC_BODY(regs3, tc)
37321.1Skamil{
37331.1Skamil	const int exitval = 5;
37341.1Skamil	const int sigval = SIGSTOP;
37351.1Skamil	pid_t child, wpid;
37361.1Skamil#if defined(TWAIT_HAVE_STATUS)
37371.1Skamil	int status;
37381.1Skamil#endif
37391.1Skamil	struct reg r;
37401.1Skamil
37411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37431.1Skamil	if (child == 0) {
37441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37461.1Skamil
37471.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37481.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37491.1Skamil
37501.13Schristos		DPRINTF("Before exiting of the child process\n");
37511.1Skamil		_exit(exitval);
37521.1Skamil	}
37531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37541.1Skamil
37551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37571.1Skamil
37581.1Skamil	validate_status_stopped(status, sigval);
37591.1Skamil
37601.13Schristos	DPRINTF("Call GETREGS for the child process\n");
37611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
37621.1Skamil
37631.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
37641.1Skamil
37651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37661.1Skamil	    "without signal to be sent\n");
37671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37681.1Skamil
37691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37711.1Skamil
37721.1Skamil	validate_status_exited(status, exitval);
37731.1Skamil
37741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37761.1Skamil}
37771.1Skamil#endif
37781.1Skamil
37791.1Skamil#if defined(HAVE_GPREGS)
37801.1SkamilATF_TC(regs4);
37811.1SkamilATF_TC_HEAD(regs4, tc)
37821.1Skamil{
37831.1Skamil	atf_tc_set_md_var(tc, "descr",
37841.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
37851.1Skamil}
37861.1Skamil
37871.1SkamilATF_TC_BODY(regs4, tc)
37881.1Skamil{
37891.1Skamil	const int exitval = 5;
37901.1Skamil	const int sigval = SIGSTOP;
37911.1Skamil	pid_t child, wpid;
37921.1Skamil#if defined(TWAIT_HAVE_STATUS)
37931.1Skamil	int status;
37941.1Skamil#endif
37951.1Skamil	struct reg r;
37961.1Skamil
37971.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37981.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37991.1Skamil	if (child == 0) {
38001.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38011.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38021.1Skamil
38031.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38041.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38051.1Skamil
38061.13Schristos		DPRINTF("Before exiting of the child process\n");
38071.1Skamil		_exit(exitval);
38081.1Skamil	}
38091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38101.1Skamil
38111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38131.1Skamil
38141.1Skamil	validate_status_stopped(status, sigval);
38151.1Skamil
38161.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38181.1Skamil
38191.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
38201.1Skamil
38211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38221.1Skamil	    "without signal to be sent\n");
38231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38241.1Skamil
38251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38271.1Skamil
38281.1Skamil	validate_status_exited(status, exitval);
38291.1Skamil
38301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38321.1Skamil}
38331.1Skamil#endif
38341.1Skamil
38351.1Skamil#if defined(HAVE_GPREGS)
38361.1SkamilATF_TC(regs5);
38371.1SkamilATF_TC_HEAD(regs5, tc)
38381.1Skamil{
38391.1Skamil	atf_tc_set_md_var(tc, "descr",
38401.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
38411.1Skamil}
38421.1Skamil
38431.1SkamilATF_TC_BODY(regs5, tc)
38441.1Skamil{
38451.1Skamil	const int exitval = 5;
38461.1Skamil	const int sigval = SIGSTOP;
38471.1Skamil	pid_t child, wpid;
38481.1Skamil#if defined(TWAIT_HAVE_STATUS)
38491.1Skamil	int status;
38501.1Skamil#endif
38511.1Skamil	struct reg r;
38521.1Skamil
38531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38551.1Skamil	if (child == 0) {
38561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38581.1Skamil
38591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38611.1Skamil
38621.13Schristos		DPRINTF("Before exiting of the child process\n");
38631.1Skamil		_exit(exitval);
38641.1Skamil	}
38651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38661.1Skamil
38671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38691.1Skamil
38701.1Skamil	validate_status_stopped(status, sigval);
38711.1Skamil
38721.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38741.1Skamil
38751.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
38761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38771.1Skamil
38781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38791.1Skamil	    "without signal to be sent\n");
38801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38811.1Skamil
38821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38841.1Skamil
38851.1Skamil	validate_status_exited(status, exitval);
38861.1Skamil
38871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38881.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38891.1Skamil}
38901.1Skamil#endif
38911.1Skamil
38921.1Skamil#if defined(HAVE_FPREGS)
38931.1SkamilATF_TC(fpregs1);
38941.1SkamilATF_TC_HEAD(fpregs1, tc)
38951.1Skamil{
38961.1Skamil	atf_tc_set_md_var(tc, "descr",
38971.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
38981.1Skamil}
38991.1Skamil
39001.1SkamilATF_TC_BODY(fpregs1, tc)
39011.1Skamil{
39021.1Skamil	const int exitval = 5;
39031.1Skamil	const int sigval = SIGSTOP;
39041.1Skamil	pid_t child, wpid;
39051.1Skamil#if defined(TWAIT_HAVE_STATUS)
39061.1Skamil	int status;
39071.1Skamil#endif
39081.1Skamil	struct fpreg r;
39091.1Skamil
39101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39121.1Skamil	if (child == 0) {
39131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39151.1Skamil
39161.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39171.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39181.1Skamil
39191.13Schristos		DPRINTF("Before exiting of the child process\n");
39201.1Skamil		_exit(exitval);
39211.1Skamil	}
39221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39231.1Skamil
39241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39261.1Skamil
39271.1Skamil	validate_status_stopped(status, sigval);
39281.1Skamil
39291.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
39301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
39311.1Skamil
39321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39331.1Skamil	    "without signal to be sent\n");
39341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39351.1Skamil
39361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39381.1Skamil
39391.1Skamil	validate_status_exited(status, exitval);
39401.1Skamil
39411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39431.1Skamil}
39441.1Skamil#endif
39451.1Skamil
39461.1Skamil#if defined(HAVE_FPREGS)
39471.1SkamilATF_TC(fpregs2);
39481.1SkamilATF_TC_HEAD(fpregs2, tc)
39491.1Skamil{
39501.1Skamil	atf_tc_set_md_var(tc, "descr",
39511.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
39521.1Skamil	    "regs");
39531.1Skamil}
39541.1Skamil
39551.1SkamilATF_TC_BODY(fpregs2, tc)
39561.1Skamil{
39571.1Skamil	const int exitval = 5;
39581.1Skamil	const int sigval = SIGSTOP;
39591.1Skamil	pid_t child, wpid;
39601.1Skamil#if defined(TWAIT_HAVE_STATUS)
39611.1Skamil	int status;
39621.1Skamil#endif
39631.1Skamil	struct fpreg r;
39641.1Skamil
39651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39671.1Skamil	if (child == 0) {
39681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39701.1Skamil
39711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39731.1Skamil
39741.13Schristos		DPRINTF("Before exiting of the child process\n");
39751.1Skamil		_exit(exitval);
39761.1Skamil	}
39771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39781.1Skamil
39791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39811.1Skamil
39821.1Skamil	validate_status_stopped(status, sigval);
39831.1Skamil
39841.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
39851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
39861.1Skamil
39871.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
39881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
39891.1Skamil
39901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39911.1Skamil	    "without signal to be sent\n");
39921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39931.1Skamil
39941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39961.1Skamil
39971.1Skamil	validate_status_exited(status, exitval);
39981.1Skamil
39991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40011.1Skamil}
40021.1Skamil#endif
40031.1Skamil
40041.1Skamil#if defined(PT_STEP)
40051.1Skamilstatic void
40061.2Skamilptrace_step(int N, int setstep)
40071.1Skamil{
40081.1Skamil	const int exitval = 5;
40091.1Skamil	const int sigval = SIGSTOP;
40101.1Skamil	pid_t child, wpid;
40111.1Skamil#if defined(TWAIT_HAVE_STATUS)
40121.1Skamil	int status;
40131.1Skamil#endif
40141.1Skamil	int happy;
40151.1Skamil
40161.1Skamil#if defined(__arm__)
40171.1Skamil	/* PT_STEP not supported on arm 32-bit */
40181.1Skamil	atf_tc_expect_fail("PR kern/52119");
40191.1Skamil#endif
40201.1Skamil
40211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40231.1Skamil	if (child == 0) {
40241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40261.1Skamil
40271.1Skamil		happy = check_happy(999);
40281.1Skamil
40291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40311.1Skamil
40321.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
40331.1Skamil
40341.13Schristos		DPRINTF("Before exiting of the child process\n");
40351.1Skamil		_exit(exitval);
40361.1Skamil	}
40371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40381.1Skamil
40391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40411.1Skamil
40421.1Skamil	validate_status_stopped(status, sigval);
40431.1Skamil
40441.1Skamil	while (N --> 0) {
40451.2Skamil		if (setstep) {
40461.13Schristos			DPRINTF("Before resuming the child process where it "
40471.2Skamil			    "left off and without signal to be sent (use "
40481.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
40491.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
40501.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
40511.2Skamil			    != -1);
40521.2Skamil		} else {
40531.13Schristos			DPRINTF("Before resuming the child process where it "
40541.2Skamil			    "left off and without signal to be sent (use "
40551.2Skamil			    "PT_STEP)\n");
40561.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
40571.2Skamil			    != -1);
40581.2Skamil		}
40591.1Skamil
40601.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40611.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
40621.1Skamil		    child);
40631.1Skamil
40641.1Skamil		validate_status_stopped(status, SIGTRAP);
40651.2Skamil
40661.2Skamil		if (setstep) {
40671.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
40681.2Skamil		}
40691.1Skamil	}
40701.1Skamil
40711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40721.1Skamil	    "without signal to be sent\n");
40731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40741.1Skamil
40751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40771.1Skamil
40781.1Skamil	validate_status_exited(status, exitval);
40791.1Skamil
40801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40811.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40821.1Skamil}
40831.1Skamil#endif
40841.1Skamil
40851.1Skamil#if defined(PT_STEP)
40861.1SkamilATF_TC(step1);
40871.1SkamilATF_TC_HEAD(step1, tc)
40881.1Skamil{
40891.1Skamil	atf_tc_set_md_var(tc, "descr",
40901.1Skamil	    "Verify single PT_STEP call");
40911.1Skamil}
40921.1Skamil
40931.1SkamilATF_TC_BODY(step1, tc)
40941.1Skamil{
40951.2Skamil	ptrace_step(1, 0);
40961.1Skamil}
40971.1Skamil#endif
40981.1Skamil
40991.1Skamil#if defined(PT_STEP)
41001.1SkamilATF_TC(step2);
41011.1SkamilATF_TC_HEAD(step2, tc)
41021.1Skamil{
41031.1Skamil	atf_tc_set_md_var(tc, "descr",
41041.1Skamil	    "Verify PT_STEP called twice");
41051.1Skamil}
41061.1Skamil
41071.1SkamilATF_TC_BODY(step2, tc)
41081.1Skamil{
41091.2Skamil	ptrace_step(2, 0);
41101.1Skamil}
41111.1Skamil#endif
41121.1Skamil
41131.1Skamil#if defined(PT_STEP)
41141.1SkamilATF_TC(step3);
41151.1SkamilATF_TC_HEAD(step3, tc)
41161.1Skamil{
41171.1Skamil	atf_tc_set_md_var(tc, "descr",
41181.1Skamil	    "Verify PT_STEP called three times");
41191.1Skamil}
41201.1Skamil
41211.1SkamilATF_TC_BODY(step3, tc)
41221.1Skamil{
41231.2Skamil	ptrace_step(3, 0);
41241.1Skamil}
41251.1Skamil#endif
41261.1Skamil
41271.1Skamil#if defined(PT_STEP)
41281.1SkamilATF_TC(step4);
41291.1SkamilATF_TC_HEAD(step4, tc)
41301.1Skamil{
41311.1Skamil	atf_tc_set_md_var(tc, "descr",
41321.1Skamil	    "Verify PT_STEP called four times");
41331.1Skamil}
41341.1Skamil
41351.1SkamilATF_TC_BODY(step4, tc)
41361.1Skamil{
41371.2Skamil	ptrace_step(4, 0);
41381.2Skamil}
41391.2Skamil#endif
41401.2Skamil
41411.2Skamil#if defined(PT_STEP)
41421.2SkamilATF_TC(setstep1);
41431.2SkamilATF_TC_HEAD(setstep1, tc)
41441.2Skamil{
41451.2Skamil	atf_tc_set_md_var(tc, "descr",
41461.2Skamil	    "Verify single PT_SETSTEP call");
41471.2Skamil}
41481.2Skamil
41491.2SkamilATF_TC_BODY(setstep1, tc)
41501.2Skamil{
41511.2Skamil	ptrace_step(1, 1);
41521.2Skamil}
41531.2Skamil#endif
41541.2Skamil
41551.2Skamil#if defined(PT_STEP)
41561.2SkamilATF_TC(setstep2);
41571.2SkamilATF_TC_HEAD(setstep2, tc)
41581.2Skamil{
41591.2Skamil	atf_tc_set_md_var(tc, "descr",
41601.2Skamil	    "Verify PT_SETSTEP called twice");
41611.2Skamil}
41621.2Skamil
41631.2SkamilATF_TC_BODY(setstep2, tc)
41641.2Skamil{
41651.2Skamil	ptrace_step(2, 1);
41661.2Skamil}
41671.2Skamil#endif
41681.2Skamil
41691.2Skamil#if defined(PT_STEP)
41701.2SkamilATF_TC(setstep3);
41711.2SkamilATF_TC_HEAD(setstep3, tc)
41721.2Skamil{
41731.2Skamil	atf_tc_set_md_var(tc, "descr",
41741.2Skamil	    "Verify PT_SETSTEP called three times");
41751.2Skamil}
41761.2Skamil
41771.2SkamilATF_TC_BODY(setstep3, tc)
41781.2Skamil{
41791.2Skamil	ptrace_step(3, 1);
41801.2Skamil}
41811.2Skamil#endif
41821.2Skamil
41831.2Skamil#if defined(PT_STEP)
41841.2SkamilATF_TC(setstep4);
41851.2SkamilATF_TC_HEAD(setstep4, tc)
41861.2Skamil{
41871.2Skamil	atf_tc_set_md_var(tc, "descr",
41881.2Skamil	    "Verify PT_SETSTEP called four times");
41891.2Skamil}
41901.2Skamil
41911.2SkamilATF_TC_BODY(setstep4, tc)
41921.2Skamil{
41931.2Skamil	ptrace_step(4, 1);
41941.1Skamil}
41951.1Skamil#endif
41961.1Skamil
41971.1SkamilATF_TC(kill1);
41981.1SkamilATF_TC_HEAD(kill1, tc)
41991.1Skamil{
42001.1Skamil	atf_tc_set_md_var(tc, "descr",
42011.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
42021.1Skamil}
42031.1Skamil
42041.1SkamilATF_TC_BODY(kill1, tc)
42051.1Skamil{
42061.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
42071.1Skamil	pid_t child, wpid;
42081.1Skamil#if defined(TWAIT_HAVE_STATUS)
42091.1Skamil	int status;
42101.1Skamil#endif
42111.1Skamil
42121.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42131.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42141.1Skamil	if (child == 0) {
42151.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42161.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42171.1Skamil
42181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42201.1Skamil
42211.1Skamil		/* NOTREACHED */
42221.1Skamil		FORKEE_ASSERTX(0 &&
42231.1Skamil		    "Child should be terminated by a signal from its parent");
42241.1Skamil	}
42251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42261.1Skamil
42271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42291.1Skamil
42301.1Skamil	validate_status_stopped(status, sigval);
42311.1Skamil
42321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42331.1Skamil	    "without signal to be sent\n");
42341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
42351.1Skamil
42361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42381.1Skamil
42391.1Skamil	validate_status_signaled(status, sigsent, 0);
42401.1Skamil
42411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42431.1Skamil}
42441.1Skamil
42451.1SkamilATF_TC(kill2);
42461.1SkamilATF_TC_HEAD(kill2, tc)
42471.1Skamil{
42481.1Skamil	atf_tc_set_md_var(tc, "descr",
42491.1Skamil	    "Verify that PT_KILL terminates child");
42501.1Skamil}
42511.1Skamil
42521.1SkamilATF_TC_BODY(kill2, tc)
42531.1Skamil{
42541.1Skamil	const int sigval = SIGSTOP;
42551.1Skamil	pid_t child, wpid;
42561.1Skamil#if defined(TWAIT_HAVE_STATUS)
42571.1Skamil	int status;
42581.1Skamil#endif
42591.1Skamil
42601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42621.1Skamil	if (child == 0) {
42631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42651.1Skamil
42661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42681.1Skamil
42691.1Skamil		/* NOTREACHED */
42701.1Skamil		FORKEE_ASSERTX(0 &&
42711.1Skamil		    "Child should be terminated by a signal from its parent");
42721.1Skamil	}
42731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42741.1Skamil
42751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42771.1Skamil
42781.1Skamil	validate_status_stopped(status, sigval);
42791.1Skamil
42801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42811.1Skamil	    "without signal to be sent\n");
42821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
42831.1Skamil
42841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42861.1Skamil
42871.1Skamil	validate_status_signaled(status, SIGKILL, 0);
42881.1Skamil
42891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42911.1Skamil}
42921.1Skamil
42931.1SkamilATF_TC(lwpinfo1);
42941.1SkamilATF_TC_HEAD(lwpinfo1, tc)
42951.1Skamil{
42961.1Skamil	atf_tc_set_md_var(tc, "descr",
42971.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
42981.1Skamil}
42991.1Skamil
43001.1SkamilATF_TC_BODY(lwpinfo1, tc)
43011.1Skamil{
43021.1Skamil	const int exitval = 5;
43031.1Skamil	const int sigval = SIGSTOP;
43041.1Skamil	pid_t child, wpid;
43051.1Skamil#if defined(TWAIT_HAVE_STATUS)
43061.1Skamil	int status;
43071.1Skamil#endif
43081.1Skamil	struct ptrace_lwpinfo info = {0, 0};
43091.1Skamil
43101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43121.1Skamil	if (child == 0) {
43131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43151.1Skamil
43161.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43171.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43181.1Skamil
43191.13Schristos		DPRINTF("Before exiting of the child process\n");
43201.1Skamil		_exit(exitval);
43211.1Skamil	}
43221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43231.1Skamil
43241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43261.1Skamil
43271.1Skamil	validate_status_stopped(status, sigval);
43281.1Skamil
43291.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
43301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
43311.1Skamil
43321.13Schristos	DPRINTF("Assert that there exists a thread\n");
43331.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
43341.1Skamil
43351.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
43361.1Skamil	    info.pl_lwpid);
43371.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
43381.1Skamil	    "Received event %d != expected event %d",
43391.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
43401.1Skamil
43411.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
43421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
43431.1Skamil
43441.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
43451.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
43461.1Skamil
43471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43481.1Skamil	    "without signal to be sent\n");
43491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43501.1Skamil
43511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43531.1Skamil
43541.1Skamil	validate_status_exited(status, exitval);
43551.1Skamil
43561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43581.1Skamil}
43591.1Skamil
43601.1Skamil#if defined(TWAIT_HAVE_PID)
43611.1SkamilATF_TC(lwpinfo2);
43621.1SkamilATF_TC_HEAD(lwpinfo2, tc)
43631.1Skamil{
43641.1Skamil	atf_tc_set_md_var(tc, "descr",
43651.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
43661.1Skamil	    "tracer)");
43671.1Skamil}
43681.1Skamil
43691.1SkamilATF_TC_BODY(lwpinfo2, tc)
43701.1Skamil{
43711.1Skamil	struct msg_fds parent_tracee, parent_tracer;
43721.1Skamil	const int exitval_tracee = 5;
43731.1Skamil	const int exitval_tracer = 10;
43741.1Skamil	pid_t tracee, tracer, wpid;
43751.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
43761.1Skamil#if defined(TWAIT_HAVE_STATUS)
43771.1Skamil	int status;
43781.1Skamil#endif
43791.1Skamil	struct ptrace_lwpinfo info = {0, 0};
43801.1Skamil
43811.13Schristos	DPRINTF("Spawn tracee\n");
43821.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
43831.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
43841.1Skamil	tracee = atf_utils_fork();
43851.1Skamil	if (tracee == 0) {
43861.1Skamil
43871.1Skamil		/* Wait for message from the parent */
43881.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
43891.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
43901.1Skamil
43911.1Skamil		_exit(exitval_tracee);
43921.1Skamil	}
43931.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
43941.1Skamil
43951.13Schristos	DPRINTF("Spawn debugger\n");
43961.1Skamil	tracer = atf_utils_fork();
43971.1Skamil	if (tracer == 0) {
43981.1Skamil		/* No IPC to communicate with the child */
43991.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
44001.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
44011.1Skamil
44021.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
44031.1Skamil		FORKEE_REQUIRE_SUCCESS(
44041.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44051.1Skamil
44061.1Skamil		forkee_status_stopped(status, SIGSTOP);
44071.1Skamil
44081.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44091.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44101.1Skamil		    != -1);
44111.1Skamil
44121.13Schristos		DPRINTF("Assert that there exists a thread\n");
44131.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
44141.1Skamil
44151.13Schristos		DPRINTF("Assert that lwp thread %d received event "
44161.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
44171.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
44181.1Skamil
44191.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
44201.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
44211.1Skamil		    != -1);
44221.1Skamil
44231.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
44241.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
44251.1Skamil
44261.1Skamil		/* Resume tracee with PT_CONTINUE */
44271.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
44281.1Skamil
44291.1Skamil		/* Inform parent that tracer has attached to tracee */
44301.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
44311.1Skamil		/* Wait for parent */
44321.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
44331.1Skamil
44341.1Skamil		/* Wait for tracee and assert that it exited */
44351.1Skamil		FORKEE_REQUIRE_SUCCESS(
44361.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
44371.1Skamil
44381.1Skamil		forkee_status_exited(status, exitval_tracee);
44391.1Skamil
44401.13Schristos		DPRINTF("Before exiting of the tracer process\n");
44411.1Skamil		_exit(exitval_tracer);
44421.1Skamil	}
44431.1Skamil
44441.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
44451.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
44461.1Skamil
44471.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
44481.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
44491.1Skamil
44501.13Schristos	DPRINTF("Detect that tracee is zombie\n");
44511.1Skamil	await_zombie(tracee);
44521.1Skamil
44531.13Schristos	DPRINTF("Assert that there is no status about tracee - "
44541.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
44551.1Skamil	TWAIT_REQUIRE_SUCCESS(
44561.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
44571.1Skamil
44581.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
44591.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
44601.1Skamil
44611.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
44621.1Skamil	    TWAIT_FNAME);
44631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
44641.1Skamil	    tracer);
44651.1Skamil
44661.1Skamil	validate_status_exited(status, exitval_tracer);
44671.1Skamil
44681.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
44691.1Skamil	    TWAIT_FNAME);
44701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
44711.1Skamil	    tracee);
44721.1Skamil
44731.1Skamil	validate_status_exited(status, exitval_tracee);
44741.1Skamil
44751.1Skamil	msg_close(&parent_tracer);
44761.1Skamil	msg_close(&parent_tracee);
44771.1Skamil}
44781.1Skamil#endif
44791.1Skamil
44801.1SkamilATF_TC(siginfo1);
44811.1SkamilATF_TC_HEAD(siginfo1, tc)
44821.1Skamil{
44831.1Skamil	atf_tc_set_md_var(tc, "descr",
44841.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
44851.1Skamil}
44861.1Skamil
44871.1SkamilATF_TC_BODY(siginfo1, tc)
44881.1Skamil{
44891.1Skamil	const int exitval = 5;
44901.1Skamil	const int sigval = SIGTRAP;
44911.1Skamil	pid_t child, wpid;
44921.1Skamil#if defined(TWAIT_HAVE_STATUS)
44931.1Skamil	int status;
44941.1Skamil#endif
44951.1Skamil	struct ptrace_siginfo info;
44961.1Skamil	memset(&info, 0, sizeof(info));
44971.1Skamil
44981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
45001.1Skamil	if (child == 0) {
45011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
45021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
45031.1Skamil
45041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
45051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
45061.1Skamil
45071.13Schristos		DPRINTF("Before exiting of the child process\n");
45081.1Skamil		_exit(exitval);
45091.1Skamil	}
45101.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
45111.1Skamil
45121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45141.1Skamil
45151.1Skamil	validate_status_stopped(status, sigval);
45161.1Skamil
45171.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
45181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
45191.1Skamil
45201.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
45211.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
45221.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
45231.1Skamil	    info.psi_siginfo.si_errno);
45241.1Skamil
45251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
45261.1Skamil	    "without signal to be sent\n");
45271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
45281.1Skamil
45291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45311.1Skamil
45321.1Skamil	validate_status_exited(status, exitval);
45331.1Skamil
45341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
45361.1Skamil}
45371.1Skamil
45381.1SkamilATF_TC(siginfo2);
45391.1SkamilATF_TC_HEAD(siginfo2, tc)
45401.1Skamil{
45411.1Skamil	atf_tc_set_md_var(tc, "descr",
45421.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
45431.1Skamil	    "modification of SIGINT from tracee");
45441.1Skamil}
45451.1Skamil
45461.1Skamilstatic int siginfo2_caught = 0;
45471.1Skamil
45481.1Skamilstatic void
45491.1Skamilsiginfo2_sighandler(int sig)
45501.1Skamil{
45511.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
45521.1Skamil
45531.1Skamil	++siginfo2_caught;
45541.1Skamil}
45551.1Skamil
45561.1SkamilATF_TC_BODY(siginfo2, tc)
45571.1Skamil{
45581.1Skamil	const int exitval = 5;
45591.1Skamil	const int sigval = SIGINT;
45601.1Skamil	pid_t child, wpid;
45611.1Skamil	struct sigaction sa;
45621.1Skamil#if defined(TWAIT_HAVE_STATUS)
45631.1Skamil	int status;
45641.1Skamil#endif
45651.1Skamil	struct ptrace_siginfo info;
45661.1Skamil	memset(&info, 0, sizeof(info));
45671.1Skamil
45681.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
45691.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
45701.1Skamil	if (child == 0) {
45711.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
45721.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
45731.1Skamil
45741.1Skamil		sa.sa_handler = siginfo2_sighandler;
45751.1Skamil		sa.sa_flags = SA_SIGINFO;
45761.1Skamil		sigemptyset(&sa.sa_mask);
45771.1Skamil
45781.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
45791.1Skamil
45801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
45811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
45821.1Skamil
45831.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
45841.1Skamil
45851.13Schristos		DPRINTF("Before exiting of the child process\n");
45861.1Skamil		_exit(exitval);
45871.1Skamil	}
45881.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
45891.1Skamil
45901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45921.1Skamil
45931.1Skamil	validate_status_stopped(status, sigval);
45941.1Skamil
45951.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
45961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
45971.1Skamil
45981.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
45991.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
46001.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
46011.1Skamil	    info.psi_siginfo.si_errno);
46021.1Skamil
46031.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
46041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
46051.1Skamil
46061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46071.1Skamil	    "without signal to be sent\n");
46081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
46091.1Skamil
46101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46121.1Skamil
46131.1Skamil	validate_status_exited(status, exitval);
46141.1Skamil
46151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46171.1Skamil}
46181.1Skamil
46191.1SkamilATF_TC(siginfo3);
46201.1SkamilATF_TC_HEAD(siginfo3, tc)
46211.1Skamil{
46221.1Skamil	atf_tc_set_md_var(tc, "descr",
46231.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
46241.1Skamil	    "setting signal to new value");
46251.1Skamil}
46261.1Skamil
46271.1Skamilstatic int siginfo3_caught = 0;
46281.1Skamil
46291.1Skamilstatic void
46301.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
46311.1Skamil{
46321.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
46331.1Skamil
46341.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
46351.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
46361.1Skamil
46371.1Skamil	++siginfo3_caught;
46381.1Skamil}
46391.1Skamil
46401.1SkamilATF_TC_BODY(siginfo3, tc)
46411.1Skamil{
46421.1Skamil	const int exitval = 5;
46431.1Skamil	const int sigval = SIGINT;
46441.1Skamil	const int sigfaked = SIGTRAP;
46451.1Skamil	const int sicodefaked = TRAP_BRKPT;
46461.1Skamil	pid_t child, wpid;
46471.1Skamil	struct sigaction sa;
46481.1Skamil#if defined(TWAIT_HAVE_STATUS)
46491.1Skamil	int status;
46501.1Skamil#endif
46511.1Skamil	struct ptrace_siginfo info;
46521.1Skamil	memset(&info, 0, sizeof(info));
46531.1Skamil
46541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46561.1Skamil	if (child == 0) {
46571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46591.1Skamil
46601.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
46611.1Skamil		sa.sa_flags = SA_SIGINFO;
46621.1Skamil		sigemptyset(&sa.sa_mask);
46631.1Skamil
46641.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
46651.1Skamil
46661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46681.1Skamil
46691.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
46701.1Skamil
46711.13Schristos		DPRINTF("Before exiting of the child process\n");
46721.1Skamil		_exit(exitval);
46731.1Skamil	}
46741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46751.1Skamil
46761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46781.1Skamil
46791.1Skamil	validate_status_stopped(status, sigval);
46801.1Skamil
46811.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
46821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
46831.1Skamil
46841.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
46851.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
46861.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
46871.1Skamil	    info.psi_siginfo.si_errno);
46881.1Skamil
46891.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
46901.1Skamil	    sigfaked, sicodefaked);
46911.1Skamil	info.psi_siginfo.si_signo = sigfaked;
46921.1Skamil	info.psi_siginfo.si_code = sicodefaked;
46931.1Skamil
46941.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
46951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
46961.1Skamil
46971.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
46981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
46991.1Skamil
47001.13Schristos	DPRINTF("Before checking siginfo_t\n");
47011.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
47021.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
47031.1Skamil
47041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47051.1Skamil	    "without signal to be sent\n");
47061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
47071.1Skamil
47081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47101.1Skamil
47111.1Skamil	validate_status_exited(status, exitval);
47121.1Skamil
47131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47151.1Skamil}
47161.1Skamil
47171.1SkamilATF_TC(siginfo4);
47181.1SkamilATF_TC_HEAD(siginfo4, tc)
47191.1Skamil{
47201.1Skamil	atf_tc_set_md_var(tc, "descr",
47211.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
47221.1Skamil}
47231.1Skamil
47241.1SkamilATF_TC_BODY(siginfo4, tc)
47251.1Skamil{
47261.1Skamil	const int sigval = SIGTRAP;
47271.1Skamil	pid_t child, wpid;
47281.1Skamil#if defined(TWAIT_HAVE_STATUS)
47291.1Skamil	int status;
47301.1Skamil#endif
47311.1Skamil
47321.1Skamil	struct ptrace_siginfo info;
47331.1Skamil	memset(&info, 0, sizeof(info));
47341.1Skamil
47351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47371.1Skamil	if (child == 0) {
47381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47401.1Skamil
47411.13Schristos		DPRINTF("Before calling execve(2) from child\n");
47421.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
47431.1Skamil
47441.1Skamil		FORKEE_ASSERT(0 && "Not reached");
47451.1Skamil	}
47461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47471.1Skamil
47481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47501.1Skamil
47511.1Skamil	validate_status_stopped(status, sigval);
47521.1Skamil
47531.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47551.1Skamil
47561.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47571.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47581.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47591.1Skamil	    info.psi_siginfo.si_errno);
47601.1Skamil
47611.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
47621.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
47631.1Skamil
47641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47651.1Skamil	    "without signal to be sent\n");
47661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47671.1Skamil
47681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47701.1Skamil
47711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47721.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47731.1Skamil}
47741.1Skamil
47751.1Skamil#if defined(TWAIT_HAVE_PID)
47761.1SkamilATF_TC(siginfo5);
47771.1SkamilATF_TC_HEAD(siginfo5, tc)
47781.1Skamil{
47791.1Skamil	atf_tc_set_md_var(tc, "descr",
47801.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
47811.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
47821.1Skamil}
47831.1Skamil
47841.1SkamilATF_TC_BODY(siginfo5, tc)
47851.1Skamil{
47861.1Skamil	const int exitval = 5;
47871.1Skamil	const int exitval2 = 15;
47881.1Skamil	const int sigval = SIGSTOP;
47891.1Skamil	pid_t child, child2, wpid;
47901.1Skamil#if defined(TWAIT_HAVE_STATUS)
47911.1Skamil	int status;
47921.1Skamil#endif
47931.1Skamil	ptrace_state_t state;
47941.1Skamil	const int slen = sizeof(state);
47951.1Skamil	ptrace_event_t event;
47961.1Skamil	const int elen = sizeof(event);
47971.1Skamil	struct ptrace_siginfo info;
47981.1Skamil
47991.1Skamil	memset(&info, 0, sizeof(info));
48001.1Skamil
48011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48031.1Skamil	if (child == 0) {
48041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48061.1Skamil
48071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
48081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
48091.1Skamil
48101.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
48111.1Skamil
48121.1Skamil		if (child2 == 0)
48131.1Skamil			_exit(exitval2);
48141.1Skamil
48151.1Skamil		FORKEE_REQUIRE_SUCCESS
48161.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
48171.1Skamil
48181.1Skamil		forkee_status_exited(status, exitval2);
48191.1Skamil
48201.13Schristos		DPRINTF("Before exiting of the child process\n");
48211.1Skamil		_exit(exitval);
48221.1Skamil	}
48231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
48241.1Skamil
48251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48271.1Skamil
48281.1Skamil	validate_status_stopped(status, sigval);
48291.1Skamil
48301.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48321.1Skamil
48331.13Schristos	DPRINTF("Before checking siginfo_t\n");
48341.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
48351.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
48361.1Skamil
48371.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
48381.1Skamil	event.pe_set_event = PTRACE_FORK;
48391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
48401.1Skamil
48411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48421.1Skamil	    "without signal to be sent\n");
48431.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
48441.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
48451.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
48461.1Skamil                "state.pe_other_pid=child)\n", child);
48471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
48481.1Skamil
48491.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
48501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48511.1Skamil
48521.1Skamil	validate_status_stopped(status, SIGTRAP);
48531.1Skamil
48541.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48561.1Skamil
48571.13Schristos	DPRINTF("Before checking siginfo_t\n");
48581.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
48591.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
48601.1Skamil
48611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
48621.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
48631.1Skamil
48641.1Skamil	child2 = state.pe_other_pid;
48651.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
48661.1Skamil
48671.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
48681.1Skamil	    TWAIT_FNAME, child2, child);
48691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
48701.1Skamil	    child2);
48711.1Skamil
48721.1Skamil	validate_status_stopped(status, SIGTRAP);
48731.1Skamil
48741.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48761.1Skamil
48771.13Schristos	DPRINTF("Before checking siginfo_t\n");
48781.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
48791.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
48801.1Skamil
48811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
48821.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
48831.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
48841.1Skamil
48851.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
48861.1Skamil	    "without signal to be sent\n");
48871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
48881.1Skamil
48891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48901.1Skamil	    "without signal to be sent\n");
48911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
48921.1Skamil
48931.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
48941.1Skamil	    TWAIT_FNAME);
48951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
48961.1Skamil	    child2);
48971.1Skamil
48981.1Skamil	validate_status_exited(status, exitval2);
48991.1Skamil
49001.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
49011.1Skamil	    TWAIT_FNAME);
49021.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
49031.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
49041.1Skamil
49051.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
49061.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
49071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49081.1Skamil
49091.1Skamil	validate_status_stopped(status, SIGCHLD);
49101.1Skamil
49111.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49131.1Skamil
49141.13Schristos	DPRINTF("Before checking siginfo_t\n");
49151.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
49161.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
49171.1Skamil
49181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49191.1Skamil	    "without signal to be sent\n");
49201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49211.1Skamil
49221.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
49231.1Skamil	    TWAIT_FNAME);
49241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49251.1Skamil
49261.1Skamil	validate_status_exited(status, exitval);
49271.1Skamil
49281.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
49291.1Skamil	    TWAIT_FNAME);
49301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49311.1Skamil}
49321.1Skamil#endif
49331.1Skamil
49341.1Skamil#if defined(PT_STEP)
49351.1SkamilATF_TC(siginfo6);
49361.1SkamilATF_TC_HEAD(siginfo6, tc)
49371.1Skamil{
49381.1Skamil	atf_tc_set_md_var(tc, "descr",
49391.1Skamil	    "Verify single PT_STEP call with signal information check");
49401.1Skamil}
49411.1Skamil
49421.1SkamilATF_TC_BODY(siginfo6, tc)
49431.1Skamil{
49441.1Skamil	const int exitval = 5;
49451.1Skamil	const int sigval = SIGSTOP;
49461.1Skamil	pid_t child, wpid;
49471.1Skamil#if defined(TWAIT_HAVE_STATUS)
49481.1Skamil	int status;
49491.1Skamil#endif
49501.1Skamil	int happy;
49511.1Skamil	struct ptrace_siginfo info;
49521.1Skamil
49531.1Skamil#if defined(__arm__)
49541.1Skamil	/* PT_STEP not supported on arm 32-bit */
49551.1Skamil	atf_tc_expect_fail("PR kern/52119");
49561.1Skamil#endif
49571.1Skamil
49581.1Skamil	memset(&info, 0, sizeof(info));
49591.1Skamil
49601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49621.1Skamil	if (child == 0) {
49631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49651.1Skamil
49661.1Skamil		happy = check_happy(100);
49671.1Skamil
49681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49701.1Skamil
49711.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
49721.1Skamil
49731.13Schristos		DPRINTF("Before exiting of the child process\n");
49741.1Skamil		_exit(exitval);
49751.1Skamil	}
49761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49771.1Skamil
49781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49801.1Skamil
49811.1Skamil	validate_status_stopped(status, sigval);
49821.1Skamil
49831.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49851.1Skamil
49861.13Schristos	DPRINTF("Before checking siginfo_t\n");
49871.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
49881.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
49891.1Skamil
49901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49911.1Skamil	    "without signal to be sent (use PT_STEP)\n");
49921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
49931.1Skamil
49941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49961.1Skamil
49971.1Skamil	validate_status_stopped(status, SIGTRAP);
49981.1Skamil
49991.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50011.1Skamil
50021.13Schristos	DPRINTF("Before checking siginfo_t\n");
50031.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
50041.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
50051.1Skamil
50061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50071.1Skamil	    "without signal to be sent\n");
50081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50091.1Skamil
50101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50121.1Skamil
50131.1Skamil	validate_status_exited(status, exitval);
50141.1Skamil
50151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50171.1Skamil}
50181.1Skamil#endif
50191.1Skamil
50201.1Skamilvolatile lwpid_t the_lwp_id = 0;
50211.1Skamil
50221.1Skamilstatic void
50231.1Skamillwp_main_func(void *arg)
50241.1Skamil{
50251.1Skamil	the_lwp_id = _lwp_self();
50261.1Skamil	_lwp_exit();
50271.1Skamil}
50281.1Skamil
50291.1SkamilATF_TC(lwp_create1);
50301.1SkamilATF_TC_HEAD(lwp_create1, tc)
50311.1Skamil{
50321.1Skamil	atf_tc_set_md_var(tc, "descr",
50331.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
50341.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
50351.1Skamil}
50361.1Skamil
50371.1SkamilATF_TC_BODY(lwp_create1, tc)
50381.1Skamil{
50391.1Skamil	const int exitval = 5;
50401.1Skamil	const int sigval = SIGSTOP;
50411.1Skamil	pid_t child, wpid;
50421.1Skamil#if defined(TWAIT_HAVE_STATUS)
50431.1Skamil	int status;
50441.1Skamil#endif
50451.1Skamil	ptrace_state_t state;
50461.1Skamil	const int slen = sizeof(state);
50471.1Skamil	ptrace_event_t event;
50481.1Skamil	const int elen = sizeof(event);
50491.1Skamil	ucontext_t uc;
50501.1Skamil	lwpid_t lid;
50511.1Skamil	static const size_t ssize = 16*1024;
50521.1Skamil	void *stack;
50531.1Skamil
50541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50561.1Skamil	if (child == 0) {
50571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50591.1Skamil
50601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50621.1Skamil
50631.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
50641.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
50651.1Skamil
50661.13Schristos		DPRINTF("Before making context for new lwp in child\n");
50671.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
50681.1Skamil
50691.13Schristos		DPRINTF("Before creating new in child\n");
50701.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
50711.1Skamil
50721.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
50731.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
50741.1Skamil
50751.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
50761.1Skamil		    "are the same\n", lid, the_lwp_id);
50771.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
50781.1Skamil
50791.13Schristos		DPRINTF("Before exiting of the child process\n");
50801.1Skamil		_exit(exitval);
50811.1Skamil	}
50821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50831.1Skamil
50841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50861.1Skamil
50871.1Skamil	validate_status_stopped(status, sigval);
50881.1Skamil
50891.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
50901.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
50911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
50921.1Skamil
50931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50941.1Skamil	    "without signal to be sent\n");
50951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50961.1Skamil
50971.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
50981.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
50991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51001.1Skamil
51011.1Skamil	validate_status_stopped(status, SIGTRAP);
51021.1Skamil
51031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
51041.1Skamil
51051.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
51061.1Skamil
51071.1Skamil	lid = state.pe_lwp;
51081.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
51091.1Skamil
51101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51111.1Skamil	    "without signal to be sent\n");
51121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51131.1Skamil
51141.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
51151.1Skamil	    TWAIT_FNAME);
51161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51171.1Skamil
51181.1Skamil	validate_status_exited(status, exitval);
51191.1Skamil
51201.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
51211.1Skamil	    TWAIT_FNAME);
51221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51231.1Skamil}
51241.1Skamil
51251.1SkamilATF_TC(lwp_exit1);
51261.1SkamilATF_TC_HEAD(lwp_exit1, tc)
51271.1Skamil{
51281.1Skamil	atf_tc_set_md_var(tc, "descr",
51291.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
51301.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
51311.1Skamil}
51321.1Skamil
51331.1SkamilATF_TC_BODY(lwp_exit1, tc)
51341.1Skamil{
51351.1Skamil	const int exitval = 5;
51361.1Skamil	const int sigval = SIGSTOP;
51371.1Skamil	pid_t child, wpid;
51381.1Skamil#if defined(TWAIT_HAVE_STATUS)
51391.1Skamil	int status;
51401.1Skamil#endif
51411.1Skamil	ptrace_state_t state;
51421.1Skamil	const int slen = sizeof(state);
51431.1Skamil	ptrace_event_t event;
51441.1Skamil	const int elen = sizeof(event);
51451.1Skamil	ucontext_t uc;
51461.1Skamil	lwpid_t lid;
51471.1Skamil	static const size_t ssize = 16*1024;
51481.1Skamil	void *stack;
51491.1Skamil
51501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51521.1Skamil	if (child == 0) {
51531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51551.1Skamil
51561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
51571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
51581.1Skamil
51591.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
51601.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
51611.1Skamil
51621.13Schristos		DPRINTF("Before making context for new lwp in child\n");
51631.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
51641.1Skamil
51651.13Schristos		DPRINTF("Before creating new in child\n");
51661.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
51671.1Skamil
51681.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
51691.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
51701.1Skamil
51711.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
51721.1Skamil		    "are the same\n", lid, the_lwp_id);
51731.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
51741.1Skamil
51751.13Schristos		DPRINTF("Before exiting of the child process\n");
51761.1Skamil		_exit(exitval);
51771.1Skamil	}
51781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51791.1Skamil
51801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51821.1Skamil
51831.1Skamil	validate_status_stopped(status, sigval);
51841.1Skamil
51851.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
51861.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
51871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
51881.1Skamil
51891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51901.1Skamil	    "without signal to be sent\n");
51911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51921.1Skamil
51931.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
51941.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
51951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51961.1Skamil
51971.1Skamil	validate_status_stopped(status, SIGTRAP);
51981.1Skamil
51991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52001.1Skamil
52011.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
52021.1Skamil
52031.1Skamil	lid = state.pe_lwp;
52041.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
52051.1Skamil
52061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52071.1Skamil	    "without signal to be sent\n");
52081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52091.1Skamil
52101.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
52111.1Skamil	    TWAIT_FNAME);
52121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52131.1Skamil
52141.1Skamil	validate_status_exited(status, exitval);
52151.1Skamil
52161.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
52171.1Skamil	    TWAIT_FNAME);
52181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
52191.1Skamil}
52201.1Skamil
52211.1SkamilATF_TC(signal1);
52221.1SkamilATF_TC_HEAD(signal1, tc)
52231.1Skamil{
52241.1Skamil	atf_tc_set_md_var(tc, "descr",
52251.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
52261.1Skamil	    "from catching other signals");
52271.1Skamil}
52281.1Skamil
52291.1SkamilATF_TC_BODY(signal1, tc)
52301.1Skamil{
52311.1Skamil	const int exitval = 5;
52321.1Skamil	const int sigval = SIGSTOP;
52331.1Skamil	const int sigmasked = SIGTRAP;
52341.1Skamil	const int signotmasked = SIGINT;
52351.1Skamil	pid_t child, wpid;
52361.1Skamil#if defined(TWAIT_HAVE_STATUS)
52371.1Skamil	int status;
52381.1Skamil#endif
52391.1Skamil	sigset_t intmask;
52401.1Skamil
52411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52431.1Skamil	if (child == 0) {
52441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52461.1Skamil
52471.1Skamil		sigemptyset(&intmask);
52481.1Skamil		sigaddset(&intmask, sigmasked);
52491.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
52501.1Skamil
52511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52531.1Skamil
52541.13Schristos		DPRINTF("Before raising %s from child\n",
52551.1Skamil		    strsignal(signotmasked));
52561.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
52571.1Skamil
52581.13Schristos		DPRINTF("Before exiting of the child process\n");
52591.1Skamil		_exit(exitval);
52601.1Skamil	}
52611.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52621.1Skamil
52631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52651.1Skamil
52661.1Skamil	validate_status_stopped(status, sigval);
52671.1Skamil
52681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52691.1Skamil	    "without signal to be sent\n");
52701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52711.1Skamil
52721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52741.1Skamil
52751.1Skamil	validate_status_stopped(status, signotmasked);
52761.1Skamil
52771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52781.1Skamil	    "without signal to be sent\n");
52791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52801.1Skamil
52811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52831.1Skamil
52841.1Skamil	validate_status_exited(status, exitval);
52851.1Skamil
52861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
52881.1Skamil}
52891.1Skamil
52901.1SkamilATF_TC(signal2);
52911.1SkamilATF_TC_HEAD(signal2, tc)
52921.1Skamil{
52931.1Skamil	atf_tc_set_md_var(tc, "descr",
52941.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
52951.1Skamil	    "catching this raised signal");
52961.1Skamil}
52971.1Skamil
52981.1SkamilATF_TC_BODY(signal2, tc)
52991.1Skamil{
53001.1Skamil	const int exitval = 5;
53011.1Skamil	const int sigval = SIGSTOP;
53021.1Skamil	const int sigmasked = SIGTRAP;
53031.1Skamil	pid_t child, wpid;
53041.1Skamil#if defined(TWAIT_HAVE_STATUS)
53051.1Skamil	int status;
53061.1Skamil#endif
53071.1Skamil	sigset_t intmask;
53081.1Skamil
53091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53111.1Skamil	if (child == 0) {
53121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53141.1Skamil
53151.1Skamil		sigemptyset(&intmask);
53161.1Skamil		sigaddset(&intmask, sigmasked);
53171.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
53181.1Skamil
53191.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53201.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53211.1Skamil
53221.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
53231.1Skamil		    strsignal(sigmasked));
53241.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
53251.1Skamil
53261.13Schristos		DPRINTF("Before exiting of the child process\n");
53271.1Skamil		_exit(exitval);
53281.1Skamil	}
53291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53301.1Skamil
53311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53331.1Skamil
53341.1Skamil	validate_status_stopped(status, sigval);
53351.1Skamil
53361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53371.1Skamil	    "without signal to be sent\n");
53381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53391.1Skamil
53401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53421.1Skamil
53431.1Skamil	validate_status_exited(status, exitval);
53441.1Skamil
53451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53471.1Skamil}
53481.1Skamil
53491.1SkamilATF_TC(signal3);
53501.1SkamilATF_TC_HEAD(signal3, tc)
53511.1Skamil{
53521.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
53531.1Skamil	atf_tc_set_md_var(tc, "descr",
53541.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
53551.1Skamil	    "catching software breakpoints");
53561.1Skamil}
53571.1Skamil
53581.1SkamilATF_TC_BODY(signal3, tc)
53591.1Skamil{
53601.1Skamil	const int exitval = 5;
53611.1Skamil	const int sigval = SIGSTOP;
53621.1Skamil	const int sigmasked = SIGTRAP;
53631.1Skamil	pid_t child, wpid;
53641.1Skamil#if defined(TWAIT_HAVE_STATUS)
53651.1Skamil	int status;
53661.1Skamil#endif
53671.1Skamil	sigset_t intmask;
53681.1Skamil
53691.20Skamil	atf_tc_expect_fail("PR kern/51918");
53701.20Skamil
53711.20Skamil	// This test breaks now on some ports, temporarily disable it
53721.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
53731.20Skamil
53741.10Smartin#if defined(__sparc__)
53751.7Skamil	atf_tc_expect_timeout("PR kern/52167");
53761.7Skamil
53771.7Skamil	// timeout wins, failure still valid
53781.7Skamil	// atf_tc_expect_fail("PR kern/51918");
53791.7Skamil#endif
53801.1Skamil
53811.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53821.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53831.1Skamil	if (child == 0) {
53841.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53851.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53861.1Skamil
53871.1Skamil		sigemptyset(&intmask);
53881.1Skamil		sigaddset(&intmask, sigmasked);
53891.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
53901.1Skamil
53911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53931.1Skamil
53941.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
53951.4Skamil
53961.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
53971.4Skamil		PTRACE_BREAKPOINT_ASM;
53981.1Skamil#else
53991.4Skamil		/* port me */
54001.1Skamil#endif
54011.1Skamil
54021.13Schristos		DPRINTF("Before exiting of the child process\n");
54031.1Skamil		_exit(exitval);
54041.1Skamil	}
54051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54061.1Skamil
54071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54091.1Skamil
54101.1Skamil	validate_status_stopped(status, sigval);
54111.1Skamil
54121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54131.1Skamil	    "without signal to be sent\n");
54141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54151.1Skamil
54161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54181.1Skamil
54191.1Skamil	validate_status_stopped(status, sigmasked);
54201.1Skamil
54211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54221.1Skamil	    "without signal to be sent\n");
54231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54241.1Skamil
54251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54271.1Skamil
54281.1Skamil	validate_status_exited(status, exitval);
54291.1Skamil
54301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54321.1Skamil}
54331.1Skamil
54341.1Skamil#if defined(PT_STEP)
54351.1SkamilATF_TC(signal4);
54361.1SkamilATF_TC_HEAD(signal4, tc)
54371.1Skamil{
54381.1Skamil	atf_tc_set_md_var(tc, "descr",
54391.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
54401.1Skamil	    "catching single step trap");
54411.1Skamil}
54421.1Skamil
54431.1SkamilATF_TC_BODY(signal4, tc)
54441.1Skamil{
54451.1Skamil	const int exitval = 5;
54461.1Skamil	const int sigval = SIGSTOP;
54471.1Skamil	const int sigmasked = SIGTRAP;
54481.1Skamil	pid_t child, wpid;
54491.1Skamil#if defined(TWAIT_HAVE_STATUS)
54501.1Skamil	int status;
54511.1Skamil#endif
54521.1Skamil	sigset_t intmask;
54531.1Skamil	int happy;
54541.1Skamil
54551.1Skamil#if defined(__arm__)
54561.5Skamil	/* PT_STEP not supported on arm 32-bit */
54571.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
54581.1Skamil#endif
54591.1Skamil
54601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54621.1Skamil	if (child == 0) {
54631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54651.1Skamil
54661.1Skamil		happy = check_happy(100);
54671.1Skamil
54681.1Skamil		sigemptyset(&intmask);
54691.1Skamil		sigaddset(&intmask, sigmasked);
54701.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
54711.1Skamil
54721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54741.1Skamil
54751.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
54761.1Skamil
54771.13Schristos		DPRINTF("Before exiting of the child process\n");
54781.1Skamil		_exit(exitval);
54791.1Skamil	}
54801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54811.1Skamil
54821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54841.1Skamil
54851.1Skamil	validate_status_stopped(status, sigval);
54861.1Skamil
54871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54881.1Skamil	    "without signal to be sent\n");
54891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
54901.1Skamil
54911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54931.1Skamil
54941.1Skamil	validate_status_stopped(status, sigmasked);
54951.1Skamil
54961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54971.1Skamil	    "without signal to be sent\n");
54981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54991.1Skamil
55001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55021.1Skamil
55031.1Skamil	validate_status_exited(status, exitval);
55041.1Skamil
55051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55071.1Skamil}
55081.1Skamil#endif
55091.1Skamil
55101.1SkamilATF_TC(signal5);
55111.1SkamilATF_TC_HEAD(signal5, tc)
55121.1Skamil{
55131.1Skamil	atf_tc_set_md_var(tc, "descr",
55141.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55151.1Skamil	    "catching exec() breakpoint");
55161.1Skamil}
55171.1Skamil
55181.1SkamilATF_TC_BODY(signal5, tc)
55191.1Skamil{
55201.1Skamil	const int exitval = 5;
55211.1Skamil	const int sigval = SIGSTOP;
55221.1Skamil	const int sigmasked = SIGTRAP;
55231.1Skamil	pid_t child, wpid;
55241.1Skamil#if defined(TWAIT_HAVE_STATUS)
55251.1Skamil	int status;
55261.1Skamil#endif
55271.1Skamil	sigset_t intmask;
55281.1Skamil
55291.14Schristos	atf_tc_expect_fail("wrong signal");
55301.14Schristos
55311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55331.1Skamil	if (child == 0) {
55341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55361.1Skamil
55371.1Skamil		sigemptyset(&intmask);
55381.1Skamil		sigaddset(&intmask, sigmasked);
55391.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55401.1Skamil
55411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55431.1Skamil
55441.13Schristos		DPRINTF("Before calling execve(2) from child\n");
55451.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
55461.1Skamil
55471.13Schristos		DPRINTF("Before exiting of the child process\n");
55481.1Skamil		_exit(exitval);
55491.1Skamil	}
55501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55511.1Skamil
55521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55541.1Skamil
55551.1Skamil	validate_status_stopped(status, sigval);
55561.1Skamil
55571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55581.1Skamil	    "without signal to be sent\n");
55591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55601.1Skamil
55611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55631.1Skamil
55641.1Skamil	validate_status_stopped(status, sigmasked);
55651.1Skamil
55661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55671.1Skamil	    "without signal to be sent\n");
55681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55691.1Skamil
55701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55721.1Skamil
55731.1Skamil	validate_status_exited(status, exitval);
55741.1Skamil
55751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55771.1Skamil}
55781.1Skamil
55791.1Skamil#if defined(TWAIT_HAVE_PID)
55801.1SkamilATF_TC(signal6);
55811.1SkamilATF_TC_HEAD(signal6, tc)
55821.1Skamil{
55831.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
55841.1Skamil	atf_tc_set_md_var(tc, "descr",
55851.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55861.1Skamil	    "catching PTRACE_FORK breakpoint");
55871.1Skamil}
55881.1Skamil
55891.1SkamilATF_TC_BODY(signal6, tc)
55901.1Skamil{
55911.1Skamil	const int exitval = 5;
55921.1Skamil	const int exitval2 = 15;
55931.1Skamil	const int sigval = SIGSTOP;
55941.1Skamil	const int sigmasked = SIGTRAP;
55951.1Skamil	pid_t child, child2, wpid;
55961.1Skamil#if defined(TWAIT_HAVE_STATUS)
55971.1Skamil	int status;
55981.1Skamil#endif
55991.1Skamil	sigset_t intmask;
56001.1Skamil	ptrace_state_t state;
56011.1Skamil	const int slen = sizeof(state);
56021.1Skamil	ptrace_event_t event;
56031.1Skamil	const int elen = sizeof(event);
56041.1Skamil
56051.14Schristos	atf_tc_expect_timeout("PR kern/51918");
56061.14Schristos
56071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56091.1Skamil	if (child == 0) {
56101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56121.1Skamil
56131.1Skamil		sigemptyset(&intmask);
56141.1Skamil		sigaddset(&intmask, sigmasked);
56151.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56161.1Skamil
56171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56191.1Skamil
56201.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
56211.1Skamil
56221.1Skamil		if (child2 == 0)
56231.1Skamil			_exit(exitval2);
56241.1Skamil
56251.1Skamil		FORKEE_REQUIRE_SUCCESS
56261.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
56271.1Skamil
56281.1Skamil		forkee_status_exited(status, exitval2);
56291.1Skamil
56301.13Schristos		DPRINTF("Before exiting of the child process\n");
56311.1Skamil		_exit(exitval);
56321.1Skamil	}
56331.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56341.1Skamil
56351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56371.1Skamil
56381.1Skamil	validate_status_stopped(status, sigval);
56391.1Skamil
56401.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
56411.1Skamil	event.pe_set_event = PTRACE_FORK;
56421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
56431.1Skamil
56441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56451.1Skamil	    "without signal to be sent\n");
56461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56471.1Skamil
56481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56501.1Skamil
56511.1Skamil	validate_status_stopped(status, sigmasked);
56521.1Skamil
56531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
56541.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
56551.1Skamil
56561.1Skamil	child2 = state.pe_other_pid;
56571.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
56581.1Skamil
56591.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
56601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
56611.1Skamil	    child2);
56621.1Skamil
56631.1Skamil	validate_status_stopped(status, SIGTRAP);
56641.1Skamil
56651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
56661.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
56671.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
56681.1Skamil
56691.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
56701.1Skamil	    "without signal to be sent\n");
56711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
56721.1Skamil
56731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56741.1Skamil	    "without signal to be sent\n");
56751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56761.1Skamil
56771.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
56781.1Skamil	    TWAIT_FNAME);
56791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
56801.1Skamil	    child2);
56811.1Skamil
56821.1Skamil	validate_status_exited(status, exitval2);
56831.1Skamil
56841.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
56851.1Skamil	    TWAIT_FNAME);
56861.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
56871.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
56881.1Skamil
56891.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
56901.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
56911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56921.1Skamil
56931.1Skamil	validate_status_stopped(status, SIGCHLD);
56941.1Skamil
56951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56961.1Skamil	    "without signal to be sent\n");
56971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56981.1Skamil
56991.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
57001.1Skamil	    TWAIT_FNAME);
57011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57021.1Skamil
57031.1Skamil	validate_status_exited(status, exitval);
57041.1Skamil
57051.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
57061.1Skamil	    TWAIT_FNAME);
57071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57081.1Skamil}
57091.1Skamil#endif
57101.1Skamil
57111.1Skamil#if defined(TWAIT_HAVE_PID)
57121.1SkamilATF_TC(signal7);
57131.1SkamilATF_TC_HEAD(signal7, tc)
57141.1Skamil{
57151.1Skamil	atf_tc_set_md_var(tc, "descr",
57161.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57171.1Skamil	    "catching PTRACE_VFORK breakpoint");
57181.1Skamil}
57191.1Skamil
57201.1SkamilATF_TC_BODY(signal7, tc)
57211.1Skamil{
57221.1Skamil	const int exitval = 5;
57231.1Skamil	const int exitval2 = 15;
57241.1Skamil	const int sigval = SIGSTOP;
57251.1Skamil	const int sigmasked = SIGTRAP;
57261.1Skamil	pid_t child, child2, wpid;
57271.1Skamil#if defined(TWAIT_HAVE_STATUS)
57281.1Skamil	int status;
57291.1Skamil#endif
57301.1Skamil	sigset_t intmask;
57311.1Skamil	ptrace_state_t state;
57321.1Skamil	const int slen = sizeof(state);
57331.1Skamil	ptrace_event_t event;
57341.1Skamil	const int elen = sizeof(event);
57351.1Skamil
57361.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
57371.14Schristos
57381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57401.1Skamil	if (child == 0) {
57411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57431.1Skamil
57441.1Skamil		sigemptyset(&intmask);
57451.1Skamil		sigaddset(&intmask, sigmasked);
57461.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57471.1Skamil
57481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57501.1Skamil
57511.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
57521.1Skamil
57531.1Skamil		if (child2 == 0)
57541.1Skamil			_exit(exitval2);
57551.1Skamil
57561.1Skamil		FORKEE_REQUIRE_SUCCESS
57571.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
57581.1Skamil
57591.1Skamil		forkee_status_exited(status, exitval2);
57601.1Skamil
57611.13Schristos		DPRINTF("Before exiting of the child process\n");
57621.1Skamil		_exit(exitval);
57631.1Skamil	}
57641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57651.1Skamil
57661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57681.1Skamil
57691.1Skamil	validate_status_stopped(status, sigval);
57701.1Skamil
57711.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
57721.1Skamil	event.pe_set_event = PTRACE_VFORK;
57731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
57741.1Skamil
57751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57761.1Skamil	    "without signal to be sent\n");
57771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57781.1Skamil
57791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57811.1Skamil
57821.1Skamil	validate_status_stopped(status, sigmasked);
57831.1Skamil
57841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
57851.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
57861.1Skamil
57871.1Skamil	child2 = state.pe_other_pid;
57881.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
57891.1Skamil
57901.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
57911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
57921.1Skamil	    child2);
57931.1Skamil
57941.1Skamil	validate_status_stopped(status, SIGTRAP);
57951.1Skamil
57961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
57971.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
57981.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
57991.1Skamil
58001.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
58011.1Skamil	    "without signal to be sent\n");
58021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
58031.1Skamil
58041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58051.1Skamil	    "without signal to be sent\n");
58061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58071.1Skamil
58081.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
58091.1Skamil	    TWAIT_FNAME);
58101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58111.1Skamil	    child2);
58121.1Skamil
58131.1Skamil	validate_status_exited(status, exitval2);
58141.1Skamil
58151.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
58161.1Skamil	    TWAIT_FNAME);
58171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
58181.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
58191.1Skamil
58201.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
58211.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
58221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58231.1Skamil
58241.1Skamil	validate_status_stopped(status, SIGCHLD);
58251.1Skamil
58261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58271.1Skamil	    "without signal to be sent\n");
58281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58291.1Skamil
58301.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
58311.1Skamil	    TWAIT_FNAME);
58321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58331.1Skamil
58341.1Skamil	validate_status_exited(status, exitval);
58351.1Skamil
58361.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
58371.1Skamil	    TWAIT_FNAME);
58381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58391.1Skamil}
58401.1Skamil#endif
58411.1Skamil
58421.1SkamilATF_TC(signal8);
58431.1SkamilATF_TC_HEAD(signal8, tc)
58441.1Skamil{
58451.1Skamil	atf_tc_set_md_var(tc, "descr",
58461.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58471.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
58481.1Skamil}
58491.1Skamil
58501.1SkamilATF_TC_BODY(signal8, tc)
58511.1Skamil{
58521.1Skamil	const int exitval = 5;
58531.1Skamil	const int exitval2 = 15;
58541.1Skamil	const int sigval = SIGSTOP;
58551.1Skamil	const int sigmasked = SIGTRAP;
58561.1Skamil	pid_t child, child2, wpid;
58571.1Skamil#if defined(TWAIT_HAVE_STATUS)
58581.1Skamil	int status;
58591.1Skamil#endif
58601.1Skamil	sigset_t intmask;
58611.1Skamil	ptrace_state_t state;
58621.1Skamil	const int slen = sizeof(state);
58631.1Skamil	ptrace_event_t event;
58641.1Skamil	const int elen = sizeof(event);
58651.1Skamil
58661.14Schristos	atf_tc_expect_fail("PR kern/51918");
58671.14Schristos
58681.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58691.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58701.1Skamil	if (child == 0) {
58711.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58721.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58731.1Skamil
58741.1Skamil		sigemptyset(&intmask);
58751.1Skamil		sigaddset(&intmask, sigmasked);
58761.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58771.1Skamil
58781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58801.1Skamil
58811.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
58821.1Skamil
58831.1Skamil		if (child2 == 0)
58841.1Skamil			_exit(exitval2);
58851.1Skamil
58861.1Skamil		FORKEE_REQUIRE_SUCCESS
58871.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
58881.1Skamil
58891.1Skamil		forkee_status_exited(status, exitval2);
58901.1Skamil
58911.13Schristos		DPRINTF("Before exiting of the child process\n");
58921.1Skamil		_exit(exitval);
58931.1Skamil	}
58941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58951.1Skamil
58961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58981.1Skamil
58991.1Skamil	validate_status_stopped(status, sigval);
59001.1Skamil
59011.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
59021.1Skamil	    child);
59031.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
59041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
59051.1Skamil
59061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59071.1Skamil	    "without signal to be sent\n");
59081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59091.1Skamil
59101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59121.1Skamil
59131.1Skamil	validate_status_stopped(status, sigmasked);
59141.1Skamil
59151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
59161.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
59171.1Skamil
59181.1Skamil	child2 = state.pe_other_pid;
59191.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
59201.1Skamil
59211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59221.1Skamil	    "without signal to be sent\n");
59231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59241.1Skamil
59251.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
59261.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
59271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59281.1Skamil
59291.1Skamil	validate_status_stopped(status, SIGCHLD);
59301.1Skamil
59311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59321.1Skamil	    "without signal to be sent\n");
59331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59341.1Skamil
59351.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
59361.1Skamil	    TWAIT_FNAME);
59371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59381.1Skamil
59391.1Skamil	validate_status_exited(status, exitval);
59401.1Skamil
59411.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
59421.1Skamil	    TWAIT_FNAME);
59431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59441.1Skamil}
59451.1Skamil
59461.1SkamilATF_TC(signal9);
59471.1SkamilATF_TC_HEAD(signal9, tc)
59481.1Skamil{
59491.1Skamil	atf_tc_set_md_var(tc, "descr",
59501.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59511.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
59521.1Skamil}
59531.1Skamil
59541.1SkamilATF_TC_BODY(signal9, tc)
59551.1Skamil{
59561.1Skamil	const int exitval = 5;
59571.1Skamil	const int sigval = SIGSTOP;
59581.1Skamil	const int sigmasked = SIGTRAP;
59591.1Skamil	pid_t child, wpid;
59601.1Skamil#if defined(TWAIT_HAVE_STATUS)
59611.1Skamil	int status;
59621.1Skamil#endif
59631.1Skamil	sigset_t intmask;
59641.1Skamil	ptrace_state_t state;
59651.1Skamil	const int slen = sizeof(state);
59661.1Skamil	ptrace_event_t event;
59671.1Skamil	const int elen = sizeof(event);
59681.1Skamil	ucontext_t uc;
59691.1Skamil	lwpid_t lid;
59701.1Skamil	static const size_t ssize = 16*1024;
59711.1Skamil	void *stack;
59721.1Skamil
59731.14Schristos	atf_tc_expect_fail("PR kern/51918");
59741.14Schristos
59751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59771.1Skamil	if (child == 0) {
59781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59801.1Skamil
59811.1Skamil		sigemptyset(&intmask);
59821.1Skamil		sigaddset(&intmask, sigmasked);
59831.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59841.1Skamil
59851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59871.1Skamil
59881.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
59891.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
59901.1Skamil
59911.13Schristos		DPRINTF("Before making context for new lwp in child\n");
59921.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
59931.1Skamil
59941.13Schristos		DPRINTF("Before creating new in child\n");
59951.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
59961.1Skamil
59971.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
59981.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
59991.1Skamil
60001.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
60011.1Skamil		    "are the same\n", lid, the_lwp_id);
60021.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
60031.1Skamil
60041.13Schristos		DPRINTF("Before exiting of the child process\n");
60051.1Skamil		_exit(exitval);
60061.1Skamil	}
60071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60081.1Skamil
60091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60111.1Skamil
60121.1Skamil	validate_status_stopped(status, sigval);
60131.1Skamil
60141.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
60151.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
60161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60171.1Skamil
60181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60191.1Skamil	    "without signal to be sent\n");
60201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60211.1Skamil
60221.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60231.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
60241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60251.1Skamil
60261.1Skamil	validate_status_stopped(status, sigmasked);
60271.1Skamil
60281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60291.1Skamil
60301.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
60311.1Skamil
60321.1Skamil	lid = state.pe_lwp;
60331.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
60341.1Skamil
60351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60361.1Skamil	    "without signal to be sent\n");
60371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60381.1Skamil
60391.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60401.1Skamil	    TWAIT_FNAME);
60411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60421.1Skamil
60431.1Skamil	validate_status_exited(status, exitval);
60441.1Skamil
60451.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60461.1Skamil	    TWAIT_FNAME);
60471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60481.1Skamil}
60491.1Skamil
60501.1SkamilATF_TC(signal10);
60511.1SkamilATF_TC_HEAD(signal10, tc)
60521.1Skamil{
60531.1Skamil	atf_tc_set_md_var(tc, "descr",
60541.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
60551.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
60561.1Skamil}
60571.1Skamil
60581.1SkamilATF_TC_BODY(signal10, tc)
60591.1Skamil{
60601.1Skamil	const int exitval = 5;
60611.1Skamil	const int sigval = SIGSTOP;
60621.1Skamil	const int sigmasked = SIGTRAP;
60631.1Skamil	pid_t child, wpid;
60641.1Skamil#if defined(TWAIT_HAVE_STATUS)
60651.1Skamil	int status;
60661.1Skamil#endif
60671.1Skamil	sigset_t intmask;
60681.1Skamil	ptrace_state_t state;
60691.1Skamil	const int slen = sizeof(state);
60701.1Skamil	ptrace_event_t event;
60711.1Skamil	const int elen = sizeof(event);
60721.1Skamil	ucontext_t uc;
60731.1Skamil	lwpid_t lid;
60741.1Skamil	static const size_t ssize = 16*1024;
60751.1Skamil	void *stack;
60761.1Skamil
60771.14Schristos	atf_tc_expect_fail("PR kern/51918");
60781.14Schristos
60791.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60801.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60811.1Skamil	if (child == 0) {
60821.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60831.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60841.1Skamil
60851.1Skamil		sigemptyset(&intmask);
60861.1Skamil		sigaddset(&intmask, sigmasked);
60871.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60881.1Skamil
60891.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60901.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60911.1Skamil
60921.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
60931.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
60941.1Skamil
60951.13Schristos		DPRINTF("Before making context for new lwp in child\n");
60961.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
60971.1Skamil
60981.13Schristos		DPRINTF("Before creating new in child\n");
60991.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
61001.1Skamil
61011.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
61021.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
61031.1Skamil
61041.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
61051.1Skamil		    "are the same\n", lid, the_lwp_id);
61061.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
61071.1Skamil
61081.13Schristos		DPRINTF("Before exiting of the child process\n");
61091.1Skamil		_exit(exitval);
61101.1Skamil	}
61111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61121.1Skamil
61131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61151.1Skamil
61161.1Skamil	validate_status_stopped(status, sigval);
61171.1Skamil
61181.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
61191.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
61201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
61211.1Skamil
61221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61231.1Skamil	    "without signal to be sent\n");
61241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61251.1Skamil
61261.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61271.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
61281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61291.1Skamil
61301.1Skamil	validate_status_stopped(status, sigmasked);
61311.1Skamil
61321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61331.1Skamil
61341.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
61351.1Skamil
61361.1Skamil	lid = state.pe_lwp;
61371.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
61381.1Skamil
61391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61401.1Skamil	    "without signal to be sent\n");
61411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61421.1Skamil
61431.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61441.1Skamil	    TWAIT_FNAME);
61451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61461.1Skamil
61471.1Skamil	validate_status_exited(status, exitval);
61481.1Skamil
61491.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61501.1Skamil	    TWAIT_FNAME);
61511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61521.1Skamil}
61531.1Skamil
61541.1Skamilstatic void
61551.1Skamillwp_main_stop(void *arg)
61561.1Skamil{
61571.1Skamil	the_lwp_id = _lwp_self();
61581.1Skamil
61591.1Skamil	raise(SIGTRAP);
61601.1Skamil
61611.1Skamil	_lwp_exit();
61621.1Skamil}
61631.1Skamil
61641.1SkamilATF_TC(suspend1);
61651.1SkamilATF_TC_HEAD(suspend1, tc)
61661.1Skamil{
61671.1Skamil	atf_tc_set_md_var(tc, "descr",
61681.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
61691.1Skamil	    "resumed by a tracee");
61701.1Skamil}
61711.1Skamil
61721.1SkamilATF_TC_BODY(suspend1, tc)
61731.1Skamil{
61741.1Skamil	const int exitval = 5;
61751.1Skamil	const int sigval = SIGSTOP;
61761.1Skamil	pid_t child, wpid;
61771.1Skamil#if defined(TWAIT_HAVE_STATUS)
61781.1Skamil	int status;
61791.1Skamil#endif
61801.1Skamil	ucontext_t uc;
61811.1Skamil	lwpid_t lid;
61821.1Skamil	static const size_t ssize = 16*1024;
61831.1Skamil	void *stack;
61841.1Skamil	struct ptrace_lwpinfo pl;
61851.1Skamil	struct ptrace_siginfo psi;
61861.1Skamil	volatile int go = 0;
61871.1Skamil
61881.17Skamil	// Feature pending for refactoring
61891.17Skamil	atf_tc_expect_fail("PR kern/51995");
61901.17Skamil
61911.16Skamil	// Hangs with qemu
61921.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
61931.16Skamil
61941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61961.1Skamil	if (child == 0) {
61971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61991.1Skamil
62001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62021.1Skamil
62031.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
62041.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
62051.1Skamil
62061.13Schristos		DPRINTF("Before making context for new lwp in child\n");
62071.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
62081.1Skamil
62091.13Schristos		DPRINTF("Before creating new in child\n");
62101.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
62111.1Skamil
62121.1Skamil		while (go == 0)
62131.1Skamil			continue;
62141.1Skamil
62151.1Skamil		raise(SIGINT);
62161.1Skamil
62171.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
62181.1Skamil
62191.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
62201.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
62211.1Skamil
62221.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
62231.1Skamil		    "are the same\n", lid, the_lwp_id);
62241.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
62251.1Skamil
62261.13Schristos		DPRINTF("Before exiting of the child process\n");
62271.1Skamil		_exit(exitval);
62281.1Skamil	}
62291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62301.1Skamil
62311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62331.1Skamil
62341.1Skamil	validate_status_stopped(status, sigval);
62351.1Skamil
62361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62371.1Skamil	    "without signal to be sent\n");
62381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62391.1Skamil
62401.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62411.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
62421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62431.1Skamil
62441.1Skamil	validate_status_stopped(status, SIGTRAP);
62451.1Skamil
62461.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
62471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
62481.1Skamil
62491.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
62501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
62511.1Skamil
62521.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
62531.1Skamil	    child, getpid());
62541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
62551.1Skamil
62561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62571.1Skamil	    "without signal to be sent\n");
62581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62591.1Skamil
62601.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62611.1Skamil	    "SIGINT\n", TWAIT_FNAME);
62621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62631.1Skamil
62641.1Skamil	validate_status_stopped(status, SIGINT);
62651.1Skamil
62661.1Skamil	pl.pl_lwpid = 0;
62671.1Skamil
62681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
62691.1Skamil	while (pl.pl_lwpid != 0) {
62701.1Skamil
62711.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
62721.1Skamil		switch (pl.pl_lwpid) {
62731.1Skamil		case 1:
62741.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
62751.1Skamil			break;
62761.1Skamil		case 2:
62771.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
62781.1Skamil			break;
62791.1Skamil		}
62801.1Skamil	}
62811.1Skamil
62821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62831.1Skamil	    "without signal to be sent\n");
62841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62851.1Skamil
62861.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62871.1Skamil	    TWAIT_FNAME);
62881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62891.1Skamil
62901.1Skamil	validate_status_exited(status, exitval);
62911.1Skamil
62921.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62931.1Skamil	    TWAIT_FNAME);
62941.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62951.1Skamil}
62961.1Skamil
62971.1SkamilATF_TC(suspend2);
62981.1SkamilATF_TC_HEAD(suspend2, tc)
62991.1Skamil{
63001.1Skamil	atf_tc_set_md_var(tc, "descr",
63011.1Skamil	    "Verify that the while the only thread within a process is "
63021.1Skamil	    "suspended, the whole process cannot be unstopped");
63031.1Skamil}
63041.1Skamil
63051.1SkamilATF_TC_BODY(suspend2, tc)
63061.1Skamil{
63071.1Skamil	const int exitval = 5;
63081.1Skamil	const int sigval = SIGSTOP;
63091.1Skamil	pid_t child, wpid;
63101.1Skamil#if defined(TWAIT_HAVE_STATUS)
63111.1Skamil	int status;
63121.1Skamil#endif
63131.1Skamil	struct ptrace_siginfo psi;
63141.1Skamil
63151.17Skamil	// Feature pending for refactoring
63161.17Skamil	atf_tc_expect_fail("PR kern/51995");
63171.17Skamil
63181.16Skamil	// Hangs with qemu
63191.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
63201.16Skamil
63211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63231.1Skamil	if (child == 0) {
63241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63261.1Skamil
63271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63291.1Skamil
63301.13Schristos		DPRINTF("Before exiting of the child process\n");
63311.1Skamil		_exit(exitval);
63321.1Skamil	}
63331.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63341.1Skamil
63351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63371.1Skamil
63381.1Skamil	validate_status_stopped(status, sigval);
63391.1Skamil
63401.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
63411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
63421.1Skamil
63431.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
63441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
63451.1Skamil
63461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63471.1Skamil	    "without signal to be sent\n");
63481.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
63491.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
63501.1Skamil
63511.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
63521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
63531.1Skamil
63541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63551.1Skamil	    "without signal to be sent\n");
63561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63571.1Skamil
63581.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63591.1Skamil	    TWAIT_FNAME);
63601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63611.1Skamil
63621.1Skamil	validate_status_exited(status, exitval);
63631.1Skamil
63641.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63651.1Skamil	    TWAIT_FNAME);
63661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63671.1Skamil}
63681.1Skamil
63691.1SkamilATF_TC(resume1);
63701.1SkamilATF_TC_HEAD(resume1, tc)
63711.1Skamil{
63721.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
63731.1Skamil	atf_tc_set_md_var(tc, "descr",
63741.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
63751.1Skamil	    "resumed by the debugger");
63761.1Skamil}
63771.1Skamil
63781.1SkamilATF_TC_BODY(resume1, tc)
63791.1Skamil{
63801.1Skamil	struct msg_fds fds;
63811.1Skamil	const int exitval = 5;
63821.1Skamil	const int sigval = SIGSTOP;
63831.1Skamil	pid_t child, wpid;
63841.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
63851.1Skamil#if defined(TWAIT_HAVE_STATUS)
63861.1Skamil	int status;
63871.1Skamil#endif
63881.1Skamil	ucontext_t uc;
63891.1Skamil	lwpid_t lid;
63901.1Skamil	static const size_t ssize = 16*1024;
63911.1Skamil	void *stack;
63921.1Skamil	struct ptrace_lwpinfo pl;
63931.1Skamil	struct ptrace_siginfo psi;
63941.1Skamil
63951.17Skamil	// Feature pending for refactoring
63961.17Skamil	atf_tc_expect_fail("PR kern/51995");
63971.17Skamil
63981.15Schristos	// Hangs with qemu
63991.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
64001.1Skamil
64011.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
64021.1Skamil
64031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64051.1Skamil	if (child == 0) {
64061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64081.1Skamil
64091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64111.1Skamil
64121.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64131.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64141.1Skamil
64151.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64161.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
64171.1Skamil
64181.13Schristos		DPRINTF("Before creating new in child\n");
64191.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64201.1Skamil
64211.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
64221.1Skamil
64231.1Skamil		raise(SIGINT);
64241.1Skamil
64251.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64261.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64271.1Skamil
64281.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64291.1Skamil		    "are the same\n", lid, the_lwp_id);
64301.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64311.1Skamil
64321.13Schristos		DPRINTF("Before exiting of the child process\n");
64331.1Skamil		_exit(exitval);
64341.1Skamil	}
64351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64361.1Skamil
64371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64391.1Skamil
64401.1Skamil	validate_status_stopped(status, sigval);
64411.1Skamil
64421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64431.1Skamil	    "without signal to be sent\n");
64441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64451.1Skamil
64461.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64471.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64491.1Skamil
64501.1Skamil	validate_status_stopped(status, SIGTRAP);
64511.1Skamil
64521.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
64531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
64541.1Skamil
64551.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
64561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
64571.1Skamil
64581.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
64591.1Skamil
64601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64611.1Skamil	    "without signal to be sent\n");
64621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64631.1Skamil
64641.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64651.1Skamil	    "SIGINT\n", TWAIT_FNAME);
64661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64671.1Skamil
64681.1Skamil	validate_status_stopped(status, SIGINT);
64691.1Skamil
64701.1Skamil	pl.pl_lwpid = 0;
64711.1Skamil
64721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
64731.1Skamil	while (pl.pl_lwpid != 0) {
64741.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
64751.1Skamil		switch (pl.pl_lwpid) {
64761.1Skamil		case 1:
64771.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
64781.1Skamil			break;
64791.1Skamil		case 2:
64801.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
64811.1Skamil			break;
64821.1Skamil		}
64831.1Skamil	}
64841.1Skamil
64851.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
64861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
64871.1Skamil
64881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64891.1Skamil	    "without signal to be sent\n");
64901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64911.1Skamil
64921.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64931.1Skamil	    TWAIT_FNAME);
64941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64951.1Skamil
64961.1Skamil	validate_status_exited(status, exitval);
64971.1Skamil
64981.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64991.1Skamil	    TWAIT_FNAME);
65001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65011.1Skamil
65021.1Skamil	msg_close(&fds);
65031.1Skamil
65041.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
65051.1Skamil	sleep(10);
65061.1Skamil}
65071.1Skamil
65081.1SkamilATF_TC(syscall1);
65091.1SkamilATF_TC_HEAD(syscall1, tc)
65101.1Skamil{
65111.1Skamil	atf_tc_set_md_var(tc, "descr",
65121.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
65131.1Skamil}
65141.1Skamil
65151.1SkamilATF_TC_BODY(syscall1, tc)
65161.1Skamil{
65171.1Skamil	const int exitval = 5;
65181.1Skamil	const int sigval = SIGSTOP;
65191.1Skamil	pid_t child, wpid;
65201.1Skamil#if defined(TWAIT_HAVE_STATUS)
65211.1Skamil	int status;
65221.1Skamil#endif
65231.1Skamil	struct ptrace_siginfo info;
65241.1Skamil	memset(&info, 0, sizeof(info));
65251.1Skamil
65261.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65271.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65281.1Skamil	if (child == 0) {
65291.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65301.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65311.1Skamil
65321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65341.1Skamil
65351.1Skamil		syscall(SYS_getpid);
65361.1Skamil
65371.13Schristos		DPRINTF("Before exiting of the child process\n");
65381.1Skamil		_exit(exitval);
65391.1Skamil	}
65401.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65411.1Skamil
65421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65441.1Skamil
65451.1Skamil	validate_status_stopped(status, sigval);
65461.1Skamil
65471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65481.1Skamil	    "without signal to be sent\n");
65491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
65501.1Skamil
65511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65531.1Skamil
65541.1Skamil	validate_status_stopped(status, SIGTRAP);
65551.1Skamil
65561.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
65571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
65581.1Skamil
65591.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
65601.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
65611.1Skamil
65621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65631.1Skamil	    "without signal to be sent\n");
65641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
65651.1Skamil
65661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65681.1Skamil
65691.1Skamil	validate_status_stopped(status, SIGTRAP);
65701.1Skamil
65711.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
65721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
65731.1Skamil
65741.13Schristos	DPRINTF("Before checking siginfo_t\n");
65751.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
65761.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
65771.1Skamil
65781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65791.1Skamil	    "without signal to be sent\n");
65801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65811.1Skamil
65821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65841.1Skamil
65851.1Skamil	validate_status_exited(status, exitval);
65861.1Skamil
65871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65881.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65891.1Skamil}
65901.1Skamil
65911.1SkamilATF_TC(syscallemu1);
65921.1SkamilATF_TC_HEAD(syscallemu1, tc)
65931.1Skamil{
65941.1Skamil	atf_tc_set_md_var(tc, "descr",
65951.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
65961.1Skamil}
65971.1Skamil
65981.1SkamilATF_TC_BODY(syscallemu1, tc)
65991.1Skamil{
66001.1Skamil	const int exitval = 5;
66011.1Skamil	const int sigval = SIGSTOP;
66021.1Skamil	pid_t child, wpid;
66031.1Skamil#if defined(TWAIT_HAVE_STATUS)
66041.1Skamil	int status;
66051.1Skamil#endif
66061.1Skamil
66071.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
66081.6Skamil	/* syscallemu does not work on sparc (32-bit) */
66091.6Skamil	atf_tc_expect_fail("PR kern/52166");
66101.6Skamil#endif
66111.6Skamil
66121.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66131.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66141.1Skamil	if (child == 0) {
66151.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66161.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66171.1Skamil
66181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66201.1Skamil
66211.1Skamil		syscall(SYS_exit, 100);
66221.1Skamil
66231.13Schristos		DPRINTF("Before exiting of the child process\n");
66241.1Skamil		_exit(exitval);
66251.1Skamil	}
66261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66271.1Skamil
66281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66301.1Skamil
66311.1Skamil	validate_status_stopped(status, sigval);
66321.1Skamil
66331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66341.1Skamil	    "without signal to be sent\n");
66351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66361.1Skamil
66371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66391.1Skamil
66401.1Skamil	validate_status_stopped(status, SIGTRAP);
66411.1Skamil
66421.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
66431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
66441.1Skamil
66451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66461.1Skamil	    "without signal to be sent\n");
66471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
66481.1Skamil
66491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66511.1Skamil
66521.1Skamil	validate_status_stopped(status, SIGTRAP);
66531.1Skamil
66541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66551.1Skamil	    "without signal to be sent\n");
66561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66571.1Skamil
66581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66601.1Skamil
66611.1Skamil	validate_status_exited(status, exitval);
66621.1Skamil
66631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66651.1Skamil}
66661.1Skamil
66671.26Skamil#if defined(TWAIT_HAVE_PID)
66681.26SkamilATF_TC(race1);
66691.26SkamilATF_TC_HEAD(race1, tc)
66701.26Skamil{
66711.26Skamil	atf_tc_set_md_var(tc, "descr",
66721.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
66731.26Skamil	    "process and no other error is reported");
66741.26Skamil}
66751.26Skamil
66761.26SkamilATF_TC_BODY(race1, tc)
66771.26Skamil{
66781.26Skamil	time_t start, end;
66791.26Skamil	double diff;
66801.26Skamil	unsigned long N = 0;
66811.26Skamil
66821.26Skamil	/* Reuse this test with attach1 */
66831.26Skamil
66841.26Skamil	start = time(NULL);
66851.26Skamil	while (true) {
66861.26Skamil		DPRINTF("Step: %lu\n", N);
66871.26Skamil		attach1_raw(true);
66881.26Skamil		end = time(NULL);
66891.26Skamil		diff = difftime(end, start);
66901.26Skamil		if (diff >= 5.0)
66911.26Skamil			break;
66921.26Skamil		++N;
66931.26Skamil	}
66941.26Skamil	DPRINTF("Iterations: %lu\n", N);
66951.26Skamil}
66961.26Skamil#endif
66971.26Skamil
66981.1Skamil#include "t_ptrace_amd64_wait.h"
66991.1Skamil#include "t_ptrace_i386_wait.h"
67001.1Skamil#include "t_ptrace_x86_wait.h"
67011.1Skamil
67021.1SkamilATF_TP_ADD_TCS(tp)
67031.1Skamil{
67041.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
67051.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
67061.33Skamil
67071.33Skamil//	ATF_TP_ADD_TC(tp, traceme_raise1); // not yet
67081.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
67091.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
67101.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
67111.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
67121.33Skamil
67131.1Skamil	ATF_TP_ADD_TC(tp, traceme2);
67141.1Skamil	ATF_TP_ADD_TC(tp, traceme3);
67151.1Skamil
67161.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
67171.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
67181.1Skamil	ATF_TP_ADD_TC(tp, attach3);
67191.1Skamil	ATF_TP_ADD_TC(tp, attach4);
67201.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
67211.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
67221.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
67231.1Skamil
67241.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
67251.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
67261.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
67271.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
67281.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
67291.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
67301.1Skamil
67311.31Skamil	ATF_TP_ADD_TC(tp, fork1);
67321.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
67331.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
67341.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
67351.31Skamil	ATF_TP_ADD_TC(tp, fork5);
67361.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
67371.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
67381.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
67391.31Skamil
67401.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
67411.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
67421.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
67431.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
67441.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
67451.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
67461.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
67471.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
67481.1Skamil
67491.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
67501.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
67511.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
67521.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
67531.1Skamil
67541.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
67551.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
67561.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
67571.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
67581.1Skamil
67591.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
67601.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
67611.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
67621.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
67631.1Skamil
67641.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
67651.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
67661.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
67671.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
67681.1Skamil
67691.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
67701.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
67711.1Skamil
67721.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
67731.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
67741.1Skamil
67751.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
67761.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
67771.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
67781.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
67791.1Skamil
67801.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
67811.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
67821.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
67831.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
67841.1Skamil
67851.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
67861.1Skamil
67871.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
67881.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
67891.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
67901.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
67911.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
67921.1Skamil
67931.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
67941.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
67951.1Skamil
67961.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
67971.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
67981.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
67991.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
68001.1Skamil
68011.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
68021.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
68031.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
68041.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
68051.2Skamil
68061.1Skamil	ATF_TP_ADD_TC(tp, kill1);
68071.1Skamil	ATF_TP_ADD_TC(tp, kill2);
68081.1Skamil
68091.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
68101.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
68111.1Skamil
68121.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
68131.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
68141.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
68151.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
68161.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
68171.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
68181.1Skamil
68191.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
68201.1Skamil
68211.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
68221.1Skamil
68231.1Skamil	ATF_TP_ADD_TC(tp, signal1);
68241.1Skamil	ATF_TP_ADD_TC(tp, signal2);
68251.1Skamil	ATF_TP_ADD_TC(tp, signal3);
68261.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
68271.1Skamil	ATF_TP_ADD_TC(tp, signal5);
68281.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
68291.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
68301.1Skamil	ATF_TP_ADD_TC(tp, signal8);
68311.1Skamil	ATF_TP_ADD_TC(tp, signal9);
68321.1Skamil	ATF_TP_ADD_TC(tp, signal10);
68331.1Skamil
68341.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
68351.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
68361.1Skamil
68371.1Skamil	ATF_TP_ADD_TC(tp, resume1);
68381.1Skamil
68391.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
68401.1Skamil
68411.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
68421.1Skamil
68431.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
68441.26Skamil
68451.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
68461.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
68471.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
68481.1Skamil
68491.1Skamil	return atf_no_error();
68501.1Skamil}
6851