t_ptrace_wait.c revision 1.18
11.18Schristos/*	$NetBSD: t_ptrace_wait.c,v 1.18 2017/12/23 22:07:57 christos 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.18Schristos__RCSID("$NetBSD: t_ptrace_wait.c,v 1.18 2017/12/23 22:07:57 christos 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.1Skamil#include <unistd.h>
521.1Skamil
531.1Skamil#include <atf-c.h>
541.1Skamil
551.1Skamil#include "h_macros.h"
561.1Skamil
571.1Skamil#include "t_ptrace_wait.h"
581.1Skamil#include "msg.h"
591.1Skamil
601.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
611.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
621.1Skamil
631.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
641.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
651.1Skamil
661.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
671.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
681.1Skamil
691.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
701.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
711.13Schristos
721.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
731.13Schristos    strerror(errno))
741.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
751.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
761.13Schristos
771.13Schristosstatic int debug = 0;
781.13Schristos
791.13Schristos#define DPRINTF(a, ...)	do  \
801.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
811.13Schristos    while (/*CONSTCOND*/0)
821.1Skamil
831.1Skamil
841.1SkamilATF_TC(traceme1);
851.1SkamilATF_TC_HEAD(traceme1, tc)
861.1Skamil{
871.1Skamil	atf_tc_set_md_var(tc, "descr",
881.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
891.1Skamil}
901.1Skamil
911.1SkamilATF_TC_BODY(traceme1, tc)
921.1Skamil{
931.1Skamil	const int exitval = 5;
941.1Skamil	const int sigval = SIGSTOP;
951.1Skamil	pid_t child, wpid;
961.1Skamil#if defined(TWAIT_HAVE_STATUS)
971.1Skamil	int status;
981.1Skamil#endif
991.1Skamil
1001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1021.1Skamil	if (child == 0) {
1031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1051.1Skamil
1061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1081.1Skamil
1091.13Schristos		DPRINTF("Before exiting of the child process\n");
1101.1Skamil		_exit(exitval);
1111.1Skamil	}
1121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1131.1Skamil
1141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1161.1Skamil
1171.1Skamil	validate_status_stopped(status, sigval);
1181.1Skamil
1191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
1201.1Skamil	    "without signal to be sent\n");
1211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1221.1Skamil
1231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1251.1Skamil
1261.1Skamil	validate_status_exited(status, exitval);
1271.1Skamil
1281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1301.1Skamil}
1311.1Skamil
1321.1SkamilATF_TC(traceme2);
1331.1SkamilATF_TC_HEAD(traceme2, tc)
1341.1Skamil{
1351.1Skamil	atf_tc_set_md_var(tc, "descr",
1361.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
1371.1Skamil}
1381.1Skamil
1391.1Skamilstatic int traceme2_caught = 0;
1401.1Skamil
1411.1Skamilstatic void
1421.1Skamiltraceme2_sighandler(int sig)
1431.1Skamil{
1441.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
1451.1Skamil
1461.1Skamil	++traceme2_caught;
1471.1Skamil}
1481.1Skamil
1491.1SkamilATF_TC_BODY(traceme2, tc)
1501.1Skamil{
1511.1Skamil	const int exitval = 5;
1521.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT;
1531.1Skamil	pid_t child, wpid;
1541.1Skamil	struct sigaction sa;
1551.1Skamil#if defined(TWAIT_HAVE_STATUS)
1561.1Skamil	int status;
1571.1Skamil#endif
1581.1Skamil
1591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1611.1Skamil	if (child == 0) {
1621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1641.1Skamil
1651.1Skamil		sa.sa_handler = traceme2_sighandler;
1661.1Skamil		sa.sa_flags = SA_SIGINFO;
1671.1Skamil		sigemptyset(&sa.sa_mask);
1681.1Skamil
1691.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1701.1Skamil
1711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1731.1Skamil
1741.1Skamil		FORKEE_ASSERT_EQ(traceme2_caught, 1);
1751.1Skamil
1761.13Schristos		DPRINTF("Before exiting of the child process\n");
1771.1Skamil		_exit(exitval);
1781.1Skamil	}
1791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1801.1Skamil
1811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1831.1Skamil
1841.1Skamil	validate_status_stopped(status, sigval);
1851.1Skamil
1861.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
1871.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
1881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1891.1Skamil
1901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1921.1Skamil
1931.1Skamil	validate_status_exited(status, exitval);
1941.1Skamil
1951.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1971.1Skamil}
1981.1Skamil
1991.1SkamilATF_TC(traceme3);
2001.1SkamilATF_TC_HEAD(traceme3, tc)
2011.1Skamil{
2021.1Skamil	atf_tc_set_md_var(tc, "descr",
2031.1Skamil	    "Verify SIGSTOP followed by termination by a signal in a child");
2041.1Skamil}
2051.1Skamil
2061.1SkamilATF_TC_BODY(traceme3, tc)
2071.1Skamil{
2081.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
2091.1Skamil	pid_t child, wpid;
2101.1Skamil#if defined(TWAIT_HAVE_STATUS)
2111.1Skamil	int status;
2121.1Skamil#endif
2131.1Skamil
2141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2161.1Skamil	if (child == 0) {
2171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2191.1Skamil
2201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2221.1Skamil
2231.1Skamil		/* NOTREACHED */
2241.1Skamil		FORKEE_ASSERTX(0 &&
2251.1Skamil		    "Child should be terminated by a signal from its parent");
2261.1Skamil	}
2271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2281.1Skamil
2291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2311.1Skamil
2321.1Skamil	validate_status_stopped(status, sigval);
2331.1Skamil
2341.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2351.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2371.1Skamil
2381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2401.1Skamil
2411.1Skamil	validate_status_signaled(status, sigsent, 0);
2421.1Skamil
2431.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2451.1Skamil}
2461.1Skamil
2471.1SkamilATF_TC(traceme4);
2481.1SkamilATF_TC_HEAD(traceme4, tc)
2491.1Skamil{
2501.1Skamil	atf_tc_set_md_var(tc, "descr",
2511.1Skamil	    "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child");
2521.1Skamil}
2531.1Skamil
2541.1SkamilATF_TC_BODY(traceme4, tc)
2551.1Skamil{
2561.1Skamil	const int exitval = 5;
2571.1Skamil	const int sigval = SIGSTOP, sigsent = SIGCONT;
2581.1Skamil	pid_t child, wpid;
2591.1Skamil#if defined(TWAIT_HAVE_STATUS)
2601.1Skamil	int status;
2611.1Skamil#endif
2621.1Skamil
2631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2651.1Skamil	if (child == 0) {
2661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2681.1Skamil
2691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2711.1Skamil
2721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigsent));
2731.1Skamil		FORKEE_ASSERT(raise(sigsent) == 0);
2741.1Skamil
2751.13Schristos		DPRINTF("Before exiting of the child process\n");
2761.1Skamil		_exit(exitval);
2771.1Skamil	}
2781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),child);
2791.1Skamil
2801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2821.1Skamil
2831.1Skamil	validate_status_stopped(status, sigval);
2841.1Skamil
2851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2861.1Skamil	    "without signal to be sent\n");
2871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2881.1Skamil
2891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2911.1Skamil
2921.1Skamil	validate_status_stopped(status, sigsent);
2931.1Skamil
2941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2951.1Skamil	    "without signal to be sent\n");
2961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2971.1Skamil
2981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3001.1Skamil
3011.1Skamil	validate_status_exited(status, exitval);
3021.1Skamil
3031.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
3041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3051.1Skamil}
3061.1Skamil
3071.1Skamil#if defined(TWAIT_HAVE_PID)
3081.1SkamilATF_TC(attach1);
3091.1SkamilATF_TC_HEAD(attach1, tc)
3101.1Skamil{
3111.1Skamil	atf_tc_set_md_var(tc, "descr",
3121.1Skamil	    "Assert that tracer sees process termination before the parent");
3131.1Skamil}
3141.1Skamil
3151.1SkamilATF_TC_BODY(attach1, tc)
3161.1Skamil{
3171.1Skamil	struct msg_fds parent_tracee, parent_tracer;
3181.1Skamil	const int exitval_tracee = 5;
3191.1Skamil	const int exitval_tracer = 10;
3201.1Skamil	pid_t tracee, tracer, wpid;
3211.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3221.1Skamil#if defined(TWAIT_HAVE_STATUS)
3231.1Skamil	int status;
3241.1Skamil#endif
3251.1Skamil
3261.13Schristos	DPRINTF("Spawn tracee\n");
3271.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3281.1Skamil	tracee = atf_utils_fork();
3291.1Skamil	if (tracee == 0) {
3301.1Skamil		// Wait for parent to let us exit
3311.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3321.1Skamil		_exit(exitval_tracee);
3331.1Skamil	}
3341.1Skamil
3351.13Schristos	DPRINTF("Spawn debugger\n");
3361.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3371.1Skamil	tracer = atf_utils_fork();
3381.1Skamil	if (tracer == 0) {
3391.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3401.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3411.1Skamil
3421.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3431.1Skamil		FORKEE_REQUIRE_SUCCESS(
3441.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3451.1Skamil
3461.1Skamil		forkee_status_stopped(status, SIGSTOP);
3471.1Skamil
3481.1Skamil		/* Resume tracee with PT_CONTINUE */
3491.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3501.1Skamil
3511.1Skamil		/* Inform parent that tracer has attached to tracee */
3521.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3531.1Skamil
3541.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3551.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3561.1Skamil
3571.1Skamil		/* Wait for tracee and assert that it exited */
3581.1Skamil		FORKEE_REQUIRE_SUCCESS(
3591.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3601.1Skamil
3611.1Skamil		forkee_status_exited(status, exitval_tracee);
3621.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3631.1Skamil
3641.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3651.1Skamil		_exit(exitval_tracer);
3661.1Skamil	}
3671.1Skamil
3681.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3691.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3701.1Skamil
3711.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3721.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3731.1Skamil
3741.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3751.1Skamil	await_zombie(tracee);
3761.1Skamil
3771.1Skamil
3781.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3791.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3801.1Skamil	    TWAIT_FNAME);
3811.1Skamil	TWAIT_REQUIRE_SUCCESS(
3821.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
3831.1Skamil
3841.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
3851.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
3861.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3871.1Skamil	    TWAIT_FNAME);
3881.1Skamil
3891.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
3901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3911.1Skamil	    tracer);
3921.1Skamil
3931.1Skamil	validate_status_exited(status, exitval_tracer);
3941.1Skamil
3951.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
3961.1Skamil	    TWAIT_FNAME);
3971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
3981.1Skamil	    tracee);
3991.1Skamil
4001.1Skamil	validate_status_exited(status, exitval_tracee);
4011.1Skamil
4021.1Skamil	msg_close(&parent_tracer);
4031.1Skamil	msg_close(&parent_tracee);
4041.1Skamil}
4051.1Skamil#endif
4061.1Skamil
4071.1Skamil#if defined(TWAIT_HAVE_PID)
4081.1SkamilATF_TC(attach2);
4091.1SkamilATF_TC_HEAD(attach2, tc)
4101.1Skamil{
4111.1Skamil	atf_tc_set_md_var(tc, "descr",
4121.1Skamil	    "Assert that any tracer sees process termination before its "
4131.1Skamil	    "parent");
4141.1Skamil}
4151.1Skamil
4161.1SkamilATF_TC_BODY(attach2, tc)
4171.1Skamil{
4181.1Skamil	struct msg_fds parent_tracer, parent_tracee;
4191.1Skamil	const int exitval_tracee = 5;
4201.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
4211.1Skamil	pid_t tracee, tracer, wpid;
4221.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4231.1Skamil#if defined(TWAIT_HAVE_STATUS)
4241.1Skamil	int status;
4251.1Skamil#endif
4261.1Skamil
4271.13Schristos	DPRINTF("Spawn tracee\n");
4281.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4291.1Skamil	tracee = atf_utils_fork();
4301.1Skamil	if (tracee == 0) {
4311.1Skamil		/* Wait for message from the parent */
4321.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4331.1Skamil		_exit(exitval_tracee);
4341.1Skamil	}
4351.1Skamil
4361.13Schristos	DPRINTF("Spawn debugger\n");
4371.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4381.1Skamil	tracer = atf_utils_fork();
4391.1Skamil	if (tracer == 0) {
4401.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4411.1Skamil		tracer = atf_utils_fork();
4421.1Skamil		if (tracer != 0)
4431.1Skamil			_exit(exitval_tracer1);
4441.1Skamil
4451.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4461.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4471.1Skamil
4481.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4491.1Skamil		FORKEE_REQUIRE_SUCCESS(
4501.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4511.1Skamil
4521.1Skamil		forkee_status_stopped(status, SIGSTOP);
4531.1Skamil
4541.1Skamil		/* Resume tracee with PT_CONTINUE */
4551.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4561.1Skamil
4571.1Skamil		/* Inform parent that tracer has attached to tracee */
4581.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4591.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4601.1Skamil
4611.1Skamil		/* Wait for tracee and assert that it exited */
4621.1Skamil		FORKEE_REQUIRE_SUCCESS(
4631.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4641.1Skamil
4651.1Skamil		forkee_status_exited(status, exitval_tracee);
4661.1Skamil
4671.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4681.1Skamil		_exit(exitval_tracer2);
4691.1Skamil	}
4701.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4711.1Skamil	    "%s()\n", TWAIT_FNAME);
4721.1Skamil	TWAIT_REQUIRE_SUCCESS(
4731.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4741.1Skamil
4751.1Skamil	validate_status_exited(status, exitval_tracer1);
4761.1Skamil
4771.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4781.1Skamil	    TWAIT_FNAME);
4791.1Skamil	TWAIT_REQUIRE_SUCCESS(
4801.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4811.1Skamil
4821.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4831.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
4841.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4851.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
4861.1Skamil
4871.13Schristos	DPRINTF("Detect that tracee is zombie\n");
4881.1Skamil	await_zombie(tracee);
4891.1Skamil
4901.13Schristos	DPRINTF("Assert that there is no status about tracee - "
4911.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4921.1Skamil	TWAIT_REQUIRE_SUCCESS(
4931.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4941.1Skamil
4951.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
4961.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
4971.1Skamil
4981.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4991.1Skamil	    TWAIT_FNAME);
5001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
5011.1Skamil	    tracee);
5021.1Skamil
5031.1Skamil	validate_status_exited(status, exitval_tracee);
5041.1Skamil
5051.1Skamil	msg_close(&parent_tracer);
5061.1Skamil	msg_close(&parent_tracee);
5071.1Skamil
5081.1Skamil}
5091.1Skamil#endif
5101.1Skamil
5111.1SkamilATF_TC(attach3);
5121.1SkamilATF_TC_HEAD(attach3, tc)
5131.1Skamil{
5141.1Skamil	atf_tc_set_md_var(tc, "descr",
5151.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
5161.1Skamil}
5171.1Skamil
5181.1SkamilATF_TC_BODY(attach3, tc)
5191.1Skamil{
5201.1Skamil	struct msg_fds parent_tracee;
5211.1Skamil	const int exitval_tracee = 5;
5221.1Skamil	pid_t tracee, wpid;
5231.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5241.1Skamil#if defined(TWAIT_HAVE_STATUS)
5251.1Skamil	int status;
5261.1Skamil#endif
5271.1Skamil
5281.13Schristos	DPRINTF("Spawn tracee\n");
5291.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5301.1Skamil	tracee = atf_utils_fork();
5311.1Skamil	if (tracee == 0) {
5321.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5331.13Schristos		DPRINTF("Parent should now attach to tracee\n");
5341.1Skamil
5351.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5361.1Skamil		/* Wait for message from the parent */
5371.1Skamil		_exit(exitval_tracee);
5381.1Skamil	}
5391.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5401.1Skamil
5411.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5431.1Skamil
5441.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5451.1Skamil	    TWAIT_FNAME);
5461.1Skamil	TWAIT_REQUIRE_SUCCESS(
5471.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5481.1Skamil
5491.1Skamil	validate_status_stopped(status, SIGSTOP);
5501.1Skamil
5511.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5531.1Skamil
5541.13Schristos	DPRINTF("Let the tracee exit now\n");
5551.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5561.1Skamil
5571.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5581.1Skamil	TWAIT_REQUIRE_SUCCESS(
5591.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5601.1Skamil
5611.1Skamil	validate_status_exited(status, exitval_tracee);
5621.1Skamil
5631.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5651.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5661.1Skamil
5671.1Skamil	msg_close(&parent_tracee);
5681.1Skamil}
5691.1Skamil
5701.1SkamilATF_TC(attach4);
5711.1SkamilATF_TC_HEAD(attach4, tc)
5721.1Skamil{
5731.1Skamil	atf_tc_set_md_var(tc, "descr",
5741.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
5751.1Skamil}
5761.1Skamil
5771.1SkamilATF_TC_BODY(attach4, tc)
5781.1Skamil{
5791.1Skamil	struct msg_fds parent_tracee;
5801.1Skamil	const int exitval_tracer = 5;
5811.1Skamil	pid_t tracer, wpid;
5821.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5831.1Skamil#if defined(TWAIT_HAVE_STATUS)
5841.1Skamil	int status;
5851.1Skamil#endif
5861.1Skamil
5871.13Schristos	DPRINTF("Spawn tracer\n");
5881.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5891.1Skamil	tracer = atf_utils_fork();
5901.1Skamil	if (tracer == 0) {
5911.1Skamil
5921.1Skamil		/* Wait for message from the parent */
5931.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5941.1Skamil
5951.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
5961.1Skamil		    getppid());
5971.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
5981.1Skamil
5991.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
6001.1Skamil		    TWAIT_FNAME);
6011.1Skamil		FORKEE_REQUIRE_SUCCESS(
6021.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
6031.1Skamil
6041.1Skamil		forkee_status_stopped(status, SIGSTOP);
6051.1Skamil
6061.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
6071.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
6081.1Skamil		    != -1);
6091.1Skamil
6101.1Skamil		/* Tell parent we are ready */
6111.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
6121.1Skamil
6131.1Skamil		_exit(exitval_tracer);
6141.1Skamil	}
6151.1Skamil
6161.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
6171.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6181.13Schristos	DPRINTF("Allow the tracer to exit now\n");
6191.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
6201.1Skamil
6211.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
6221.1Skamil	TWAIT_REQUIRE_SUCCESS(
6231.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6241.1Skamil
6251.1Skamil	validate_status_exited(status, exitval_tracer);
6261.1Skamil
6271.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
6281.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6291.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
6301.1Skamil
6311.1Skamil	msg_close(&parent_tracee);
6321.1Skamil}
6331.1Skamil
6341.1Skamil#if defined(TWAIT_HAVE_PID)
6351.1SkamilATF_TC(attach5);
6361.1SkamilATF_TC_HEAD(attach5, tc)
6371.1Skamil{
6381.1Skamil	atf_tc_set_md_var(tc, "descr",
6391.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6401.1Skamil	    "(check getppid(2))");
6411.1Skamil}
6421.1Skamil
6431.1SkamilATF_TC_BODY(attach5, tc)
6441.1Skamil{
6451.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6461.1Skamil	const int exitval_tracee = 5;
6471.1Skamil	const int exitval_tracer = 10;
6481.1Skamil	pid_t parent, tracee, tracer, wpid;
6491.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6501.1Skamil#if defined(TWAIT_HAVE_STATUS)
6511.1Skamil	int status;
6521.1Skamil#endif
6531.1Skamil
6541.13Schristos	DPRINTF("Spawn tracee\n");
6551.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6561.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6571.1Skamil	tracee = atf_utils_fork();
6581.1Skamil	if (tracee == 0) {
6591.1Skamil		parent = getppid();
6601.1Skamil
6611.1Skamil		/* Emit message to the parent */
6621.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6631.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6641.1Skamil
6651.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6661.1Skamil
6671.1Skamil		_exit(exitval_tracee);
6681.1Skamil	}
6691.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6701.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6711.1Skamil
6721.13Schristos	DPRINTF("Spawn debugger\n");
6731.1Skamil	tracer = atf_utils_fork();
6741.1Skamil	if (tracer == 0) {
6751.1Skamil		/* No IPC to communicate with the child */
6761.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6771.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6781.1Skamil
6791.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6801.1Skamil		FORKEE_REQUIRE_SUCCESS(
6811.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6821.1Skamil
6831.1Skamil		forkee_status_stopped(status, SIGSTOP);
6841.1Skamil
6851.1Skamil		/* Resume tracee with PT_CONTINUE */
6861.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6871.1Skamil
6881.1Skamil		/* Inform parent that tracer has attached to tracee */
6891.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
6901.1Skamil
6911.1Skamil		/* Wait for parent to tell use that tracee should have exited */
6921.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
6931.1Skamil
6941.1Skamil		/* Wait for tracee and assert that it exited */
6951.1Skamil		FORKEE_REQUIRE_SUCCESS(
6961.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6971.1Skamil
6981.1Skamil		forkee_status_exited(status, exitval_tracee);
6991.1Skamil
7001.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7011.1Skamil		_exit(exitval_tracer);
7021.1Skamil	}
7031.1Skamil
7041.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7051.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
7061.1Skamil
7071.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7081.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
7091.1Skamil
7101.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7111.1Skamil	await_zombie(tracee);
7121.1Skamil
7131.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7141.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7151.1Skamil	TWAIT_REQUIRE_SUCCESS(
7161.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7171.1Skamil
7181.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7191.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
7201.1Skamil
7211.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7231.1Skamil	    tracer);
7241.1Skamil
7251.1Skamil	validate_status_exited(status, exitval_tracer);
7261.1Skamil
7271.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7281.1Skamil	    TWAIT_FNAME);
7291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7301.1Skamil	    tracee);
7311.1Skamil
7321.1Skamil	validate_status_exited(status, exitval_tracee);
7331.1Skamil
7341.1Skamil	msg_close(&parent_tracer);
7351.1Skamil	msg_close(&parent_tracee);
7361.1Skamil}
7371.1Skamil#endif
7381.1Skamil
7391.1Skamil#if defined(TWAIT_HAVE_PID)
7401.1SkamilATF_TC(attach6);
7411.1SkamilATF_TC_HEAD(attach6, tc)
7421.1Skamil{
7431.1Skamil	atf_tc_set_md_var(tc, "descr",
7441.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7451.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7461.1Skamil}
7471.1Skamil
7481.1SkamilATF_TC_BODY(attach6, tc)
7491.1Skamil{
7501.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7511.1Skamil	const int exitval_tracee = 5;
7521.1Skamil	const int exitval_tracer = 10;
7531.1Skamil	pid_t parent, tracee, tracer, wpid;
7541.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7551.1Skamil#if defined(TWAIT_HAVE_STATUS)
7561.1Skamil	int status;
7571.1Skamil#endif
7581.1Skamil	int name[CTL_MAXNAME];
7591.1Skamil	struct kinfo_proc2 kp;
7601.1Skamil	size_t len = sizeof(kp);
7611.1Skamil	unsigned int namelen;
7621.1Skamil
7631.13Schristos	DPRINTF("Spawn tracee\n");
7641.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7651.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7661.1Skamil	tracee = atf_utils_fork();
7671.1Skamil	if (tracee == 0) {
7681.1Skamil		parent = getppid();
7691.1Skamil
7701.1Skamil		/* Emit message to the parent */
7711.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7721.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7731.1Skamil
7741.1Skamil		namelen = 0;
7751.1Skamil		name[namelen++] = CTL_KERN;
7761.1Skamil		name[namelen++] = KERN_PROC2;
7771.1Skamil		name[namelen++] = KERN_PROC_PID;
7781.1Skamil		name[namelen++] = getpid();
7791.1Skamil		name[namelen++] = len;
7801.1Skamil		name[namelen++] = 1;
7811.1Skamil
7821.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
7831.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
7841.1Skamil
7851.1Skamil		_exit(exitval_tracee);
7861.1Skamil	}
7871.1Skamil
7881.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
7891.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
7901.1Skamil
7911.13Schristos	DPRINTF("Spawn debugger\n");
7921.1Skamil	tracer = atf_utils_fork();
7931.1Skamil	if (tracer == 0) {
7941.1Skamil		/* No IPC to communicate with the child */
7951.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
7961.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7971.1Skamil
7981.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
7991.1Skamil		FORKEE_REQUIRE_SUCCESS(
8001.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8011.1Skamil
8021.1Skamil		forkee_status_stopped(status, SIGSTOP);
8031.1Skamil
8041.1Skamil		/* Resume tracee with PT_CONTINUE */
8051.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8061.1Skamil
8071.1Skamil		/* Inform parent that tracer has attached to tracee */
8081.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8091.1Skamil
8101.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8111.1Skamil
8121.1Skamil		/* Wait for tracee and assert that it exited */
8131.1Skamil		FORKEE_REQUIRE_SUCCESS(
8141.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8151.1Skamil
8161.1Skamil		forkee_status_exited(status, exitval_tracee);
8171.1Skamil
8181.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8191.1Skamil		_exit(exitval_tracer);
8201.1Skamil	}
8211.1Skamil
8221.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8231.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8241.1Skamil
8251.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8261.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8271.1Skamil
8281.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8291.1Skamil	await_zombie(tracee);
8301.1Skamil
8311.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8321.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8331.1Skamil	TWAIT_REQUIRE_SUCCESS(
8341.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8351.1Skamil
8361.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8371.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8381.1Skamil
8391.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8401.1Skamil	    TWAIT_FNAME);
8411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8421.1Skamil	    tracer);
8431.1Skamil
8441.1Skamil	validate_status_exited(status, exitval_tracer);
8451.1Skamil
8461.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8471.1Skamil	    TWAIT_FNAME);
8481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8491.1Skamil	    tracee);
8501.1Skamil
8511.1Skamil	validate_status_exited(status, exitval_tracee);
8521.1Skamil
8531.1Skamil	msg_close(&parent_tracee);
8541.1Skamil	msg_close(&parent_tracer);
8551.1Skamil}
8561.1Skamil#endif
8571.1Skamil
8581.1Skamil#if defined(TWAIT_HAVE_PID)
8591.1SkamilATF_TC(attach7);
8601.1SkamilATF_TC_HEAD(attach7, tc)
8611.1Skamil{
8621.1Skamil	atf_tc_set_md_var(tc, "descr",
8631.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8641.1Skamil	    "(check /proc/curproc/status 3rd column)");
8651.1Skamil}
8661.1Skamil
8671.1SkamilATF_TC_BODY(attach7, tc)
8681.1Skamil{
8691.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8701.1Skamil	int rv;
8711.1Skamil	const int exitval_tracee = 5;
8721.1Skamil	const int exitval_tracer = 10;
8731.1Skamil	pid_t parent, tracee, tracer, wpid;
8741.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8751.1Skamil#if defined(TWAIT_HAVE_STATUS)
8761.1Skamil	int status;
8771.1Skamil#endif
8781.1Skamil	FILE *fp;
8791.1Skamil	struct stat st;
8801.1Skamil	const char *fname = "/proc/curproc/status";
8811.1Skamil	char s_executable[MAXPATHLEN];
8821.1Skamil	int s_pid, s_ppid;
8831.1Skamil	/*
8841.1Skamil	 * Format:
8851.1Skamil	 *  EXECUTABLE PID PPID ...
8861.1Skamil	 */
8871.1Skamil
8881.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
8891.1Skamil	if (rv != 0) {
8901.1Skamil		atf_tc_skip("/proc/curproc/status not found");
8911.1Skamil	}
8921.1Skamil
8931.13Schristos	DPRINTF("Spawn tracee\n");
8941.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8951.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8961.1Skamil	tracee = atf_utils_fork();
8971.1Skamil	if (tracee == 0) {
8981.1Skamil		parent = getppid();
8991.1Skamil
9001.1Skamil		// Wait for parent to let us exit
9011.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
9021.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
9031.1Skamil
9041.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
9051.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
9061.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
9071.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
9081.1Skamil
9091.1Skamil		_exit(exitval_tracee);
9101.1Skamil	}
9111.1Skamil
9121.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9131.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
9141.1Skamil
9151.13Schristos	DPRINTF("Spawn debugger\n");
9161.1Skamil	tracer = atf_utils_fork();
9171.1Skamil	if (tracer == 0) {
9181.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9191.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9201.1Skamil
9211.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9221.1Skamil		FORKEE_REQUIRE_SUCCESS(
9231.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9241.1Skamil
9251.1Skamil		forkee_status_stopped(status, SIGSTOP);
9261.1Skamil
9271.1Skamil		/* Resume tracee with PT_CONTINUE */
9281.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9291.1Skamil
9301.1Skamil		/* Inform parent that tracer has attached to tracee */
9311.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9321.1Skamil
9331.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9341.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9351.1Skamil
9361.1Skamil		/* Wait for tracee and assert that it exited */
9371.1Skamil		FORKEE_REQUIRE_SUCCESS(
9381.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9391.1Skamil
9401.1Skamil		forkee_status_exited(status, exitval_tracee);
9411.1Skamil
9421.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9431.1Skamil		_exit(exitval_tracer);
9441.1Skamil	}
9451.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9461.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9471.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9481.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9491.1Skamil
9501.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9511.1Skamil	await_zombie(tracee);
9521.1Skamil
9531.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9541.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9551.1Skamil	TWAIT_REQUIRE_SUCCESS(
9561.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9571.1Skamil
9581.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9591.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9601.1Skamil
9611.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9621.1Skamil	    TWAIT_FNAME);
9631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9641.1Skamil	    tracer);
9651.1Skamil
9661.1Skamil	validate_status_exited(status, exitval_tracer);
9671.1Skamil
9681.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9691.1Skamil	    TWAIT_FNAME);
9701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9711.1Skamil	    tracee);
9721.1Skamil
9731.1Skamil	validate_status_exited(status, exitval_tracee);
9741.1Skamil
9751.1Skamil	msg_close(&parent_tracee);
9761.1Skamil	msg_close(&parent_tracer);
9771.1Skamil}
9781.1Skamil#endif
9791.1Skamil
9801.1SkamilATF_TC(eventmask1);
9811.1SkamilATF_TC_HEAD(eventmask1, tc)
9821.1Skamil{
9831.1Skamil	atf_tc_set_md_var(tc, "descr",
9841.1Skamil	    "Verify that empty EVENT_MASK is preserved");
9851.1Skamil}
9861.1Skamil
9871.1SkamilATF_TC_BODY(eventmask1, tc)
9881.1Skamil{
9891.1Skamil	const int exitval = 5;
9901.1Skamil	const int sigval = SIGSTOP;
9911.1Skamil	pid_t child, wpid;
9921.1Skamil#if defined(TWAIT_HAVE_STATUS)
9931.1Skamil	int status;
9941.1Skamil#endif
9951.1Skamil	ptrace_event_t set_event, get_event;
9961.1Skamil	const int len = sizeof(ptrace_event_t);
9971.1Skamil
9981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
9991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10001.1Skamil	if (child == 0) {
10011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10031.1Skamil
10041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10061.1Skamil
10071.13Schristos		DPRINTF("Before exiting of the child process\n");
10081.1Skamil		_exit(exitval);
10091.1Skamil	}
10101.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10111.1Skamil
10121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10141.1Skamil
10151.1Skamil	validate_status_stopped(status, sigval);
10161.1Skamil
10171.1Skamil	set_event.pe_set_event = 0;
10181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10201.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10211.1Skamil
10221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10231.1Skamil	    "without signal to be sent\n");
10241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10251.1Skamil
10261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10281.1Skamil
10291.1Skamil	validate_status_exited(status, exitval);
10301.1Skamil
10311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10331.1Skamil}
10341.1Skamil
10351.1SkamilATF_TC(eventmask2);
10361.1SkamilATF_TC_HEAD(eventmask2, tc)
10371.1Skamil{
10381.1Skamil	atf_tc_set_md_var(tc, "descr",
10391.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10401.1Skamil}
10411.1Skamil
10421.1SkamilATF_TC_BODY(eventmask2, tc)
10431.1Skamil{
10441.1Skamil	const int exitval = 5;
10451.1Skamil	const int sigval = SIGSTOP;
10461.1Skamil	pid_t child, wpid;
10471.1Skamil#if defined(TWAIT_HAVE_STATUS)
10481.1Skamil	int status;
10491.1Skamil#endif
10501.1Skamil	ptrace_event_t set_event, get_event;
10511.1Skamil	const int len = sizeof(ptrace_event_t);
10521.1Skamil
10531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10551.1Skamil	if (child == 0) {
10561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10581.1Skamil
10591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10611.1Skamil
10621.13Schristos		DPRINTF("Before exiting of the child process\n");
10631.1Skamil		_exit(exitval);
10641.1Skamil	}
10651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10661.1Skamil
10671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10691.1Skamil
10701.1Skamil	validate_status_stopped(status, sigval);
10711.1Skamil
10721.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10751.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10761.1Skamil
10771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10781.1Skamil	    "without signal to be sent\n");
10791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10801.1Skamil
10811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10831.1Skamil
10841.1Skamil	validate_status_exited(status, exitval);
10851.1Skamil
10861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10881.1Skamil}
10891.1Skamil
10901.1SkamilATF_TC(eventmask3);
10911.1SkamilATF_TC_HEAD(eventmask3, tc)
10921.1Skamil{
10931.1Skamil	atf_tc_set_md_var(tc, "descr",
10941.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
10951.1Skamil}
10961.1Skamil
10971.1SkamilATF_TC_BODY(eventmask3, tc)
10981.1Skamil{
10991.1Skamil	const int exitval = 5;
11001.1Skamil	const int sigval = SIGSTOP;
11011.1Skamil	pid_t child, wpid;
11021.1Skamil#if defined(TWAIT_HAVE_STATUS)
11031.1Skamil	int status;
11041.1Skamil#endif
11051.1Skamil	ptrace_event_t set_event, get_event;
11061.1Skamil	const int len = sizeof(ptrace_event_t);
11071.1Skamil
11081.14Schristos	atf_tc_expect_fail("PR kern/51630");
11091.14Schristos
11101.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11111.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11121.1Skamil	if (child == 0) {
11131.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11141.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11151.1Skamil
11161.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11171.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11181.1Skamil
11191.13Schristos		DPRINTF("Before exiting of the child process\n");
11201.1Skamil		_exit(exitval);
11211.1Skamil	}
11221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11231.1Skamil
11241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11261.1Skamil
11271.1Skamil	validate_status_stopped(status, sigval);
11281.1Skamil
11291.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
11301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
11311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11321.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11331.1Skamil
11341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11351.1Skamil	    "without signal to be sent\n");
11361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11371.1Skamil
11381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11401.1Skamil
11411.1Skamil	validate_status_exited(status, exitval);
11421.1Skamil
11431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11451.1Skamil}
11461.1Skamil
11471.1SkamilATF_TC(eventmask4);
11481.1SkamilATF_TC_HEAD(eventmask4, tc)
11491.1Skamil{
11501.1Skamil	atf_tc_set_md_var(tc, "descr",
11511.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11521.1Skamil}
11531.1Skamil
11541.1SkamilATF_TC_BODY(eventmask4, tc)
11551.1Skamil{
11561.1Skamil	const int exitval = 5;
11571.1Skamil	const int sigval = SIGSTOP;
11581.1Skamil	pid_t child, wpid;
11591.1Skamil#if defined(TWAIT_HAVE_STATUS)
11601.1Skamil	int status;
11611.1Skamil#endif
11621.1Skamil	ptrace_event_t set_event, get_event;
11631.1Skamil	const int len = sizeof(ptrace_event_t);
11641.1Skamil
11651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11671.1Skamil	if (child == 0) {
11681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11701.1Skamil
11711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11731.1Skamil
11741.13Schristos		DPRINTF("Before exiting of the child process\n");
11751.1Skamil		_exit(exitval);
11761.1Skamil	}
11771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11781.1Skamil
11791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11811.1Skamil
11821.1Skamil	validate_status_stopped(status, sigval);
11831.1Skamil
11841.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
11851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11871.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11881.1Skamil
11891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11901.1Skamil	    "without signal to be sent\n");
11911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11921.1Skamil
11931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11951.1Skamil
11961.1Skamil	validate_status_exited(status, exitval);
11971.1Skamil
11981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12001.1Skamil}
12011.1Skamil
12021.1SkamilATF_TC(eventmask5);
12031.1SkamilATF_TC_HEAD(eventmask5, tc)
12041.1Skamil{
12051.1Skamil	atf_tc_set_md_var(tc, "descr",
12061.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
12071.1Skamil}
12081.1Skamil
12091.1SkamilATF_TC_BODY(eventmask5, tc)
12101.1Skamil{
12111.1Skamil	const int exitval = 5;
12121.1Skamil	const int sigval = SIGSTOP;
12131.1Skamil	pid_t child, wpid;
12141.1Skamil#if defined(TWAIT_HAVE_STATUS)
12151.1Skamil	int status;
12161.1Skamil#endif
12171.1Skamil	ptrace_event_t set_event, get_event;
12181.1Skamil	const int len = sizeof(ptrace_event_t);
12191.1Skamil
12201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12221.1Skamil	if (child == 0) {
12231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12251.1Skamil
12261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12281.1Skamil
12291.13Schristos		DPRINTF("Before exiting of the child process\n");
12301.1Skamil		_exit(exitval);
12311.1Skamil	}
12321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12331.1Skamil
12341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12361.1Skamil
12371.1Skamil	validate_status_stopped(status, sigval);
12381.1Skamil
12391.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12421.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12431.1Skamil
12441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12451.1Skamil	    "without signal to be sent\n");
12461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12471.1Skamil
12481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12501.1Skamil
12511.1Skamil	validate_status_exited(status, exitval);
12521.1Skamil
12531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12551.1Skamil}
12561.1Skamil
12571.1SkamilATF_TC(eventmask6);
12581.1SkamilATF_TC_HEAD(eventmask6, tc)
12591.1Skamil{
12601.1Skamil	atf_tc_set_md_var(tc, "descr",
12611.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12621.1Skamil}
12631.1Skamil
12641.1SkamilATF_TC_BODY(eventmask6, tc)
12651.1Skamil{
12661.1Skamil	const int exitval = 5;
12671.1Skamil	const int sigval = SIGSTOP;
12681.1Skamil	pid_t child, wpid;
12691.1Skamil#if defined(TWAIT_HAVE_STATUS)
12701.1Skamil	int status;
12711.1Skamil#endif
12721.1Skamil	ptrace_event_t set_event, get_event;
12731.1Skamil	const int len = sizeof(ptrace_event_t);
12741.1Skamil
12751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12771.1Skamil	if (child == 0) {
12781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12801.1Skamil
12811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12831.1Skamil
12841.13Schristos		DPRINTF("Before exiting of the child process\n");
12851.1Skamil		_exit(exitval);
12861.1Skamil	}
12871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12881.1Skamil
12891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12911.1Skamil
12921.1Skamil	validate_status_stopped(status, sigval);
12931.1Skamil
12941.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
12951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12971.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12981.1Skamil
12991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13001.1Skamil	    "without signal to be sent\n");
13011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13021.1Skamil
13031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13051.1Skamil
13061.1Skamil	validate_status_exited(status, exitval);
13071.1Skamil
13081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13101.1Skamil}
13111.1Skamil
13121.1Skamil#if defined(TWAIT_HAVE_PID)
13131.1SkamilATF_TC(fork1);
13141.1SkamilATF_TC_HEAD(fork1, tc)
13151.1Skamil{
13161.1Skamil	atf_tc_set_md_var(tc, "descr",
13171.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
13181.1Skamil	    "set to PTRACE_FORK");
13191.1Skamil}
13201.1Skamil
13211.1SkamilATF_TC_BODY(fork1, tc)
13221.1Skamil{
13231.1Skamil	const int exitval = 5;
13241.1Skamil	const int exitval2 = 15;
13251.1Skamil	const int sigval = SIGSTOP;
13261.1Skamil	pid_t child, child2, wpid;
13271.1Skamil#if defined(TWAIT_HAVE_STATUS)
13281.1Skamil	int status;
13291.1Skamil#endif
13301.1Skamil	ptrace_state_t state;
13311.1Skamil	const int slen = sizeof(state);
13321.1Skamil	ptrace_event_t event;
13331.1Skamil	const int elen = sizeof(event);
13341.1Skamil
13351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13371.1Skamil	if (child == 0) {
13381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13401.1Skamil
13411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13431.1Skamil
13441.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
13451.1Skamil
13461.1Skamil		if (child2 == 0)
13471.1Skamil			_exit(exitval2);
13481.1Skamil
13491.1Skamil		FORKEE_REQUIRE_SUCCESS
13501.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13511.1Skamil
13521.1Skamil		forkee_status_exited(status, exitval2);
13531.1Skamil
13541.13Schristos		DPRINTF("Before exiting of the child process\n");
13551.1Skamil		_exit(exitval);
13561.1Skamil	}
13571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13581.1Skamil
13591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13611.1Skamil
13621.1Skamil	validate_status_stopped(status, sigval);
13631.1Skamil
13641.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
13651.1Skamil	event.pe_set_event = PTRACE_FORK;
13661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13671.1Skamil
13681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13691.1Skamil	    "without signal to be sent\n");
13701.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
13711.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
13721.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
13731.1Skamil                "state.pe_other_pid=child)\n", child);
13741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13751.1Skamil
13761.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
13771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13781.1Skamil
13791.1Skamil	validate_status_stopped(status, SIGTRAP);
13801.1Skamil
13811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
13821.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
13831.1Skamil
13841.1Skamil	child2 = state.pe_other_pid;
13851.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
13861.1Skamil
13871.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
13881.1Skamil	    TWAIT_FNAME, child2, child);
13891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
13901.1Skamil	    child2);
13911.1Skamil
13921.1Skamil	validate_status_stopped(status, SIGTRAP);
13931.1Skamil
13941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
13951.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
13961.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
13971.1Skamil
13981.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
13991.1Skamil	    "without signal to be sent\n");
14001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
14011.1Skamil
14021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14031.1Skamil	    "without signal to be sent\n");
14041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14051.1Skamil
14061.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
14071.1Skamil	    TWAIT_FNAME);
14081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14091.1Skamil	    child2);
14101.1Skamil
14111.1Skamil	validate_status_exited(status, exitval2);
14121.1Skamil
14131.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
14141.1Skamil	    TWAIT_FNAME);
14151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
14161.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
14171.1Skamil
14181.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14191.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14211.1Skamil
14221.1Skamil	validate_status_stopped(status, SIGCHLD);
14231.1Skamil
14241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14251.1Skamil	    "without signal to be sent\n");
14261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14271.1Skamil
14281.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
14291.1Skamil	    TWAIT_FNAME);
14301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14311.1Skamil
14321.1Skamil	validate_status_exited(status, exitval);
14331.1Skamil
14341.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
14351.1Skamil	    TWAIT_FNAME);
14361.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14371.1Skamil}
14381.1Skamil#endif
14391.1Skamil
14401.1SkamilATF_TC(fork2);
14411.1SkamilATF_TC_HEAD(fork2, tc)
14421.1Skamil{
14431.1Skamil	atf_tc_set_md_var(tc, "descr",
14441.1Skamil	    "Verify that fork(2) is not intercepted by ptrace(2) with empty "
14451.1Skamil	    "EVENT_MASK");
14461.1Skamil}
14471.1Skamil
14481.1SkamilATF_TC_BODY(fork2, tc)
14491.1Skamil{
14501.1Skamil	const int exitval = 5;
14511.1Skamil	const int exitval2 = 15;
14521.1Skamil	const int sigval = SIGSTOP;
14531.1Skamil	pid_t child, child2, wpid;
14541.1Skamil#if defined(TWAIT_HAVE_STATUS)
14551.1Skamil	int status;
14561.1Skamil#endif
14571.1Skamil	ptrace_event_t event;
14581.1Skamil	const int elen = sizeof(event);
14591.1Skamil
14601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14621.1Skamil	if (child == 0) {
14631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14651.1Skamil
14661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14681.1Skamil
14691.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
14701.1Skamil
14711.1Skamil		if (child2 == 0)
14721.1Skamil			_exit(exitval2);
14731.1Skamil
14741.1Skamil		FORKEE_REQUIRE_SUCCESS
14751.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
14761.1Skamil
14771.1Skamil		forkee_status_exited(status, exitval2);
14781.1Skamil
14791.13Schristos		DPRINTF("Before exiting of the child process\n");
14801.1Skamil		_exit(exitval);
14811.1Skamil	}
14821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14831.1Skamil
14841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14861.1Skamil
14871.1Skamil	validate_status_stopped(status, sigval);
14881.1Skamil
14891.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
14901.1Skamil	event.pe_set_event = 0;
14911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
14921.1Skamil
14931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14941.1Skamil	    "without signal to be sent\n");
14951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14961.1Skamil
14971.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14981.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15001.1Skamil
15011.1Skamil	validate_status_stopped(status, SIGCHLD);
15021.1Skamil
15031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15041.1Skamil	    "without signal to be sent\n");
15051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15061.1Skamil
15071.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
15081.1Skamil	    TWAIT_FNAME);
15091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15101.1Skamil
15111.1Skamil	validate_status_exited(status, exitval);
15121.1Skamil
15131.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
15141.1Skamil	    TWAIT_FNAME);
15151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15161.1Skamil}
15171.1Skamil
15181.1Skamil#if defined(TWAIT_HAVE_PID)
15191.1SkamilATF_TC(vfork1);
15201.1SkamilATF_TC_HEAD(vfork1, tc)
15211.1Skamil{
15221.1Skamil	atf_tc_set_md_var(tc, "descr",
15231.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
15241.1Skamil	    "set to PTRACE_VFORK");
15251.1Skamil}
15261.1Skamil
15271.1SkamilATF_TC_BODY(vfork1, tc)
15281.1Skamil{
15291.1Skamil	const int exitval = 5;
15301.1Skamil	const int exitval2 = 15;
15311.1Skamil	const int sigval = SIGSTOP;
15321.1Skamil	pid_t child, child2, wpid;
15331.1Skamil#if defined(TWAIT_HAVE_STATUS)
15341.1Skamil	int status;
15351.1Skamil#endif
15361.1Skamil	ptrace_state_t state;
15371.1Skamil	const int slen = sizeof(state);
15381.1Skamil	ptrace_event_t event;
15391.1Skamil	const int elen = sizeof(event);
15401.1Skamil
15411.1Skamil	atf_tc_expect_fail("PR kern/51630");
15421.1Skamil
15431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15451.1Skamil	if (child == 0) {
15461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15481.1Skamil
15491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15511.1Skamil
15521.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
15531.1Skamil
15541.1Skamil		if (child2 == 0)
15551.1Skamil			_exit(exitval2);
15561.1Skamil
15571.1Skamil		FORKEE_REQUIRE_SUCCESS
15581.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
15591.1Skamil
15601.1Skamil		forkee_status_exited(status, exitval2);
15611.1Skamil
15621.13Schristos		DPRINTF("Before exiting of the child process\n");
15631.1Skamil		_exit(exitval);
15641.1Skamil	}
15651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15661.1Skamil
15671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15691.1Skamil
15701.1Skamil	validate_status_stopped(status, sigval);
15711.1Skamil
15721.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
15731.1Skamil	event.pe_set_event = PTRACE_VFORK;
15741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
15751.1Skamil
15761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15771.1Skamil	    "without signal to be sent\n");
15781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15791.1Skamil
15801.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
15811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15821.1Skamil
15831.1Skamil	validate_status_stopped(status, SIGTRAP);
15841.1Skamil
15851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
15861.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
15871.1Skamil
15881.1Skamil	child2 = state.pe_other_pid;
15891.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
15901.1Skamil
15911.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
15921.1Skamil	    TWAIT_FNAME, child2, child);
15931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
15941.1Skamil	    child2);
15951.1Skamil
15961.1Skamil	validate_status_stopped(status, SIGTRAP);
15971.1Skamil
15981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
15991.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
16001.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
16011.1Skamil
16021.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
16031.1Skamil	    "without signal to be sent\n");
16041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
16051.1Skamil
16061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16071.1Skamil	    "without signal to be sent\n");
16081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16091.1Skamil
16101.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
16111.1Skamil	    TWAIT_FNAME);
16121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
16131.1Skamil	    child2);
16141.1Skamil
16151.1Skamil	validate_status_exited(status, exitval2);
16161.1Skamil
16171.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
16181.1Skamil	    TWAIT_FNAME);
16191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
16201.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
16211.1Skamil
16221.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
16231.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
16241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16251.1Skamil
16261.1Skamil	validate_status_stopped(status, SIGCHLD);
16271.1Skamil
16281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16291.1Skamil	    "without signal to be sent\n");
16301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16311.1Skamil
16321.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
16331.1Skamil	    TWAIT_FNAME);
16341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16351.1Skamil
16361.1Skamil	validate_status_exited(status, exitval);
16371.1Skamil
16381.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
16391.1Skamil	    TWAIT_FNAME);
16401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16411.1Skamil}
16421.1Skamil#endif
16431.1Skamil
16441.1SkamilATF_TC(vfork2);
16451.1SkamilATF_TC_HEAD(vfork2, tc)
16461.1Skamil{
16471.1Skamil	atf_tc_set_md_var(tc, "descr",
16481.1Skamil	    "Verify that vfork(2) is not intercepted by ptrace(2) with empty "
16491.1Skamil	    "EVENT_MASK");
16501.1Skamil}
16511.1Skamil
16521.1SkamilATF_TC_BODY(vfork2, tc)
16531.1Skamil{
16541.1Skamil	const int exitval = 5;
16551.1Skamil	const int exitval2 = 15;
16561.1Skamil	const int sigval = SIGSTOP;
16571.1Skamil	pid_t child, child2, wpid;
16581.1Skamil#if defined(TWAIT_HAVE_STATUS)
16591.1Skamil	int status;
16601.1Skamil#endif
16611.1Skamil	ptrace_event_t event;
16621.1Skamil	const int elen = sizeof(event);
16631.1Skamil
16641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16661.1Skamil	if (child == 0) {
16671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16691.1Skamil
16701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16721.1Skamil
16731.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
16741.1Skamil
16751.1Skamil		if (child2 == 0)
16761.1Skamil			_exit(exitval2);
16771.1Skamil
16781.1Skamil		FORKEE_REQUIRE_SUCCESS
16791.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
16801.1Skamil
16811.1Skamil		forkee_status_exited(status, exitval2);
16821.1Skamil
16831.13Schristos		DPRINTF("Before exiting of the child process\n");
16841.1Skamil		_exit(exitval);
16851.1Skamil	}
16861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16871.1Skamil
16881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16901.1Skamil
16911.1Skamil	validate_status_stopped(status, sigval);
16921.1Skamil
16931.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
16941.1Skamil	event.pe_set_event = 0;
16951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
16961.1Skamil
16971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16981.1Skamil	    "without signal to be sent\n");
16991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17001.1Skamil
17011.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
17021.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
17031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17041.1Skamil
17051.1Skamil	validate_status_stopped(status, SIGCHLD);
17061.1Skamil
17071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17081.1Skamil	    "without signal to be sent\n");
17091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17101.1Skamil
17111.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
17121.1Skamil	    TWAIT_FNAME);
17131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17141.1Skamil
17151.1Skamil	validate_status_exited(status, exitval);
17161.1Skamil
17171.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
17181.1Skamil	    TWAIT_FNAME);
17191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17201.1Skamil}
17211.1Skamil
17221.1SkamilATF_TC(vforkdone1);
17231.1SkamilATF_TC_HEAD(vforkdone1, tc)
17241.1Skamil{
17251.1Skamil	atf_tc_set_md_var(tc, "descr",
17261.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
17271.1Skamil	    "set to PTRACE_VFORK_DONE");
17281.1Skamil}
17291.1Skamil
17301.1SkamilATF_TC_BODY(vforkdone1, tc)
17311.1Skamil{
17321.1Skamil	const int exitval = 5;
17331.1Skamil	const int exitval2 = 15;
17341.1Skamil	const int sigval = SIGSTOP;
17351.1Skamil	pid_t child, child2, wpid;
17361.1Skamil#if defined(TWAIT_HAVE_STATUS)
17371.1Skamil	int status;
17381.1Skamil#endif
17391.1Skamil	ptrace_state_t state;
17401.1Skamil	const int slen = sizeof(state);
17411.1Skamil	ptrace_event_t event;
17421.1Skamil	const int elen = sizeof(event);
17431.1Skamil
17441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17461.1Skamil	if (child == 0) {
17471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17491.1Skamil
17501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17521.1Skamil
17531.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
17541.1Skamil
17551.1Skamil		if (child2 == 0)
17561.1Skamil			_exit(exitval2);
17571.1Skamil
17581.1Skamil		FORKEE_REQUIRE_SUCCESS
17591.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
17601.1Skamil
17611.1Skamil		forkee_status_exited(status, exitval2);
17621.1Skamil
17631.13Schristos		DPRINTF("Before exiting of the child process\n");
17641.1Skamil		_exit(exitval);
17651.1Skamil	}
17661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17671.1Skamil
17681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17701.1Skamil
17711.1Skamil	validate_status_stopped(status, sigval);
17721.1Skamil
17731.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
17741.1Skamil	    child);
17751.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
17761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17771.1Skamil
17781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17791.1Skamil	    "without signal to be sent\n");
17801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17811.1Skamil
17821.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
17831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17841.1Skamil
17851.1Skamil	validate_status_stopped(status, SIGTRAP);
17861.1Skamil
17871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
17881.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
17891.1Skamil
17901.1Skamil	child2 = state.pe_other_pid;
17911.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
17921.1Skamil
17931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17941.1Skamil	    "without signal to be sent\n");
17951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17961.1Skamil
17971.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
17981.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
17991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18001.1Skamil
18011.1Skamil	validate_status_stopped(status, SIGCHLD);
18021.1Skamil
18031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18041.1Skamil	    "without signal to be sent\n");
18051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18061.1Skamil
18071.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
18081.1Skamil	    TWAIT_FNAME);
18091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18101.1Skamil
18111.1Skamil	validate_status_exited(status, exitval);
18121.1Skamil
18131.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
18141.1Skamil	    TWAIT_FNAME);
18151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18161.1Skamil}
18171.1Skamil
18181.1SkamilATF_TC(vforkdone2);
18191.1SkamilATF_TC_HEAD(vforkdone2, tc)
18201.1Skamil{
18211.1Skamil	atf_tc_set_md_var(tc, "descr",
18221.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
18231.1Skamil	    "set to PTRACE_FORK | PTRACE_VFORK_DONE");
18241.1Skamil}
18251.1Skamil
18261.1SkamilATF_TC_BODY(vforkdone2, tc)
18271.1Skamil{
18281.1Skamil	const int exitval = 5;
18291.1Skamil	const int exitval2 = 15;
18301.1Skamil	const int sigval = SIGSTOP;
18311.1Skamil	pid_t child, child2, wpid;
18321.1Skamil#if defined(TWAIT_HAVE_STATUS)
18331.1Skamil	int status;
18341.1Skamil#endif
18351.1Skamil	ptrace_state_t state;
18361.1Skamil	const int slen = sizeof(state);
18371.1Skamil	ptrace_event_t event;
18381.1Skamil	const int elen = sizeof(event);
18391.1Skamil
18401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18421.1Skamil	if (child == 0) {
18431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18451.1Skamil
18461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18481.1Skamil
18491.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
18501.1Skamil
18511.1Skamil		if (child2 == 0)
18521.1Skamil			_exit(exitval2);
18531.1Skamil
18541.1Skamil		FORKEE_REQUIRE_SUCCESS
18551.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
18561.1Skamil
18571.1Skamil		forkee_status_exited(status, exitval2);
18581.1Skamil
18591.13Schristos		DPRINTF("Before exiting of the child process\n");
18601.1Skamil		_exit(exitval);
18611.1Skamil	}
18621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18631.1Skamil
18641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18661.1Skamil
18671.1Skamil	validate_status_stopped(status, sigval);
18681.1Skamil
18691.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
18701.1Skamil	event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE;
18711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
18721.1Skamil
18731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18741.1Skamil	    "without signal to be sent\n");
18751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18761.1Skamil
18771.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
18781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18791.1Skamil
18801.1Skamil	validate_status_stopped(status, SIGTRAP);
18811.1Skamil
18821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
18831.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
18841.1Skamil
18851.1Skamil	child2 = state.pe_other_pid;
18861.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
18871.1Skamil
18881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18891.1Skamil	    "without signal to be sent\n");
18901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18911.1Skamil
18921.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18931.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18951.1Skamil
18961.1Skamil	validate_status_stopped(status, SIGCHLD);
18971.1Skamil
18981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18991.1Skamil	    "without signal to be sent\n");
19001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19011.1Skamil
19021.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
19031.1Skamil	    TWAIT_FNAME);
19041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19051.1Skamil
19061.1Skamil	validate_status_exited(status, exitval);
19071.1Skamil
19081.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
19091.1Skamil	    TWAIT_FNAME);
19101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19111.1Skamil}
19121.1Skamil
19131.1SkamilATF_TC(io_read_d1);
19141.1SkamilATF_TC_HEAD(io_read_d1, tc)
19151.1Skamil{
19161.1Skamil	atf_tc_set_md_var(tc, "descr",
19171.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
19181.1Skamil}
19191.1Skamil
19201.1SkamilATF_TC_BODY(io_read_d1, tc)
19211.1Skamil{
19221.1Skamil	const int exitval = 5;
19231.1Skamil	const int sigval = SIGSTOP;
19241.1Skamil	pid_t child, wpid;
19251.1Skamil	uint8_t lookup_me = 0;
19261.1Skamil	const uint8_t magic = 0xab;
19271.1Skamil	struct ptrace_io_desc io = {
19281.1Skamil		.piod_op = PIOD_READ_D,
19291.1Skamil		.piod_offs = &lookup_me,
19301.1Skamil		.piod_addr = &lookup_me,
19311.1Skamil		.piod_len = sizeof(lookup_me)
19321.1Skamil	};
19331.1Skamil#if defined(TWAIT_HAVE_STATUS)
19341.1Skamil	int status;
19351.1Skamil#endif
19361.1Skamil
19371.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19381.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19391.1Skamil	if (child == 0) {
19401.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19411.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19421.1Skamil
19431.1Skamil		lookup_me = magic;
19441.1Skamil
19451.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19461.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19471.1Skamil
19481.13Schristos		DPRINTF("Before exiting of the child process\n");
19491.1Skamil		_exit(exitval);
19501.1Skamil	}
19511.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19521.1Skamil
19531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19551.1Skamil
19561.1Skamil	validate_status_stopped(status, sigval);
19571.1Skamil
19581.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19591.1Skamil	    child, getpid());
19601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19611.1Skamil
19621.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19631.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
19641.1Skamil
19651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19661.1Skamil	    "without signal to be sent\n");
19671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19681.1Skamil
19691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19711.1Skamil
19721.1Skamil	validate_status_exited(status, exitval);
19731.1Skamil
19741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19761.1Skamil}
19771.1Skamil
19781.1SkamilATF_TC(io_read_d2);
19791.1SkamilATF_TC_HEAD(io_read_d2, tc)
19801.1Skamil{
19811.1Skamil	atf_tc_set_md_var(tc, "descr",
19821.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
19831.1Skamil}
19841.1Skamil
19851.1SkamilATF_TC_BODY(io_read_d2, tc)
19861.1Skamil{
19871.1Skamil	const int exitval = 5;
19881.1Skamil	const int sigval = SIGSTOP;
19891.1Skamil	pid_t child, wpid;
19901.1Skamil	uint16_t lookup_me = 0;
19911.1Skamil	const uint16_t magic = 0x1234;
19921.1Skamil	struct ptrace_io_desc io = {
19931.1Skamil		.piod_op = PIOD_READ_D,
19941.1Skamil		.piod_offs = &lookup_me,
19951.1Skamil		.piod_addr = &lookup_me,
19961.1Skamil		.piod_len = sizeof(lookup_me)
19971.1Skamil	};
19981.1Skamil#if defined(TWAIT_HAVE_STATUS)
19991.1Skamil	int status;
20001.1Skamil#endif
20011.1Skamil
20021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20041.1Skamil	if (child == 0) {
20051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20071.1Skamil
20081.1Skamil		lookup_me = magic;
20091.1Skamil
20101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20121.1Skamil
20131.13Schristos		DPRINTF("Before exiting of the child process\n");
20141.1Skamil		_exit(exitval);
20151.1Skamil	}
20161.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20171.1Skamil
20181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20201.1Skamil
20211.1Skamil	validate_status_stopped(status, sigval);
20221.1Skamil
20231.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20241.1Skamil	    child, getpid());
20251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20261.1Skamil
20271.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20281.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
20291.1Skamil
20301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20311.1Skamil	    "without signal to be sent\n");
20321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20331.1Skamil
20341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20361.1Skamil
20371.1Skamil	validate_status_exited(status, exitval);
20381.1Skamil
20391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20411.1Skamil}
20421.1Skamil
20431.1SkamilATF_TC(io_read_d3);
20441.1SkamilATF_TC_HEAD(io_read_d3, tc)
20451.1Skamil{
20461.1Skamil	atf_tc_set_md_var(tc, "descr",
20471.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
20481.1Skamil}
20491.1Skamil
20501.1SkamilATF_TC_BODY(io_read_d3, tc)
20511.1Skamil{
20521.1Skamil	const int exitval = 5;
20531.1Skamil	const int sigval = SIGSTOP;
20541.1Skamil	pid_t child, wpid;
20551.1Skamil	uint32_t lookup_me = 0;
20561.1Skamil	const uint32_t magic = 0x1234abcd;
20571.1Skamil	struct ptrace_io_desc io = {
20581.1Skamil		.piod_op = PIOD_READ_D,
20591.1Skamil		.piod_offs = &lookup_me,
20601.1Skamil		.piod_addr = &lookup_me,
20611.1Skamil		.piod_len = sizeof(lookup_me)
20621.1Skamil	};
20631.1Skamil#if defined(TWAIT_HAVE_STATUS)
20641.1Skamil	int status;
20651.1Skamil#endif
20661.1Skamil
20671.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20681.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20691.1Skamil	if (child == 0) {
20701.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20711.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20721.1Skamil
20731.1Skamil		lookup_me = magic;
20741.1Skamil
20751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20771.1Skamil
20781.13Schristos		DPRINTF("Before exiting of the child process\n");
20791.1Skamil		_exit(exitval);
20801.1Skamil	}
20811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20821.1Skamil
20831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20851.1Skamil
20861.1Skamil	validate_status_stopped(status, sigval);
20871.1Skamil
20881.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20891.1Skamil	    child, getpid());
20901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20911.1Skamil
20921.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20931.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
20941.1Skamil
20951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20961.1Skamil	    "without signal to be sent\n");
20971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20981.1Skamil
20991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21011.1Skamil
21021.1Skamil	validate_status_exited(status, exitval);
21031.1Skamil
21041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21061.1Skamil}
21071.1Skamil
21081.1SkamilATF_TC(io_read_d4);
21091.1SkamilATF_TC_HEAD(io_read_d4, tc)
21101.1Skamil{
21111.1Skamil	atf_tc_set_md_var(tc, "descr",
21121.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
21131.1Skamil}
21141.1Skamil
21151.1SkamilATF_TC_BODY(io_read_d4, tc)
21161.1Skamil{
21171.1Skamil	const int exitval = 5;
21181.1Skamil	const int sigval = SIGSTOP;
21191.1Skamil	pid_t child, wpid;
21201.1Skamil	uint64_t lookup_me = 0;
21211.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
21221.1Skamil	struct ptrace_io_desc io = {
21231.1Skamil		.piod_op = PIOD_READ_D,
21241.1Skamil		.piod_offs = &lookup_me,
21251.1Skamil		.piod_addr = &lookup_me,
21261.1Skamil		.piod_len = sizeof(lookup_me)
21271.1Skamil	};
21281.1Skamil#if defined(TWAIT_HAVE_STATUS)
21291.1Skamil	int status;
21301.1Skamil#endif
21311.1Skamil
21321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21341.1Skamil	if (child == 0) {
21351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21371.1Skamil
21381.1Skamil		lookup_me = magic;
21391.1Skamil
21401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21421.1Skamil
21431.13Schristos		DPRINTF("Before exiting of the child process\n");
21441.1Skamil		_exit(exitval);
21451.1Skamil	}
21461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
21521.1Skamil
21531.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21541.1Skamil	    child, getpid());
21551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21561.1Skamil
21571.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21581.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
21591.1Skamil
21601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21611.1Skamil	    "without signal to be sent\n");
21621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21631.1Skamil
21641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21661.1Skamil
21671.1Skamil	validate_status_exited(status, exitval);
21681.1Skamil
21691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21711.1Skamil}
21721.1Skamil
21731.1SkamilATF_TC(io_write_d1);
21741.1SkamilATF_TC_HEAD(io_write_d1, tc)
21751.1Skamil{
21761.1Skamil	atf_tc_set_md_var(tc, "descr",
21771.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
21781.1Skamil}
21791.1Skamil
21801.1SkamilATF_TC_BODY(io_write_d1, tc)
21811.1Skamil{
21821.1Skamil	const int exitval = 5;
21831.1Skamil	const int sigval = SIGSTOP;
21841.1Skamil	pid_t child, wpid;
21851.1Skamil	uint8_t lookup_me = 0;
21861.1Skamil	const uint8_t magic = 0xab;
21871.1Skamil	struct ptrace_io_desc io = {
21881.1Skamil		.piod_op = PIOD_WRITE_D,
21891.1Skamil		.piod_offs = &lookup_me,
21901.1Skamil		.piod_addr = &lookup_me,
21911.1Skamil		.piod_len = sizeof(lookup_me)
21921.1Skamil	};
21931.1Skamil#if defined(TWAIT_HAVE_STATUS)
21941.1Skamil	int status;
21951.1Skamil#endif
21961.1Skamil
21971.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21981.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21991.1Skamil	if (child == 0) {
22001.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22011.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22021.1Skamil
22031.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22041.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22051.1Skamil
22061.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22071.1Skamil
22081.13Schristos		DPRINTF("Before exiting of the child process\n");
22091.1Skamil		_exit(exitval);
22101.1Skamil	}
22111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22121.1Skamil
22131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22151.1Skamil
22161.1Skamil	validate_status_stopped(status, sigval);
22171.1Skamil
22181.1Skamil	lookup_me = magic;
22191.1Skamil
22201.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22211.1Skamil	    child, getpid());
22221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22231.1Skamil
22241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22251.1Skamil	    "without signal to be sent\n");
22261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22271.1Skamil
22281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22301.1Skamil
22311.1Skamil	validate_status_exited(status, exitval);
22321.1Skamil
22331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22351.1Skamil}
22361.1Skamil
22371.1SkamilATF_TC(io_write_d2);
22381.1SkamilATF_TC_HEAD(io_write_d2, tc)
22391.1Skamil{
22401.1Skamil	atf_tc_set_md_var(tc, "descr",
22411.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
22421.1Skamil}
22431.1Skamil
22441.1SkamilATF_TC_BODY(io_write_d2, tc)
22451.1Skamil{
22461.1Skamil	const int exitval = 5;
22471.1Skamil	const int sigval = SIGSTOP;
22481.1Skamil	pid_t child, wpid;
22491.1Skamil	uint16_t lookup_me = 0;
22501.1Skamil	const uint16_t magic = 0xab12;
22511.1Skamil	struct ptrace_io_desc io = {
22521.1Skamil		.piod_op = PIOD_WRITE_D,
22531.1Skamil		.piod_offs = &lookup_me,
22541.1Skamil		.piod_addr = &lookup_me,
22551.1Skamil		.piod_len = sizeof(lookup_me)
22561.1Skamil	};
22571.1Skamil#if defined(TWAIT_HAVE_STATUS)
22581.1Skamil	int status;
22591.1Skamil#endif
22601.1Skamil
22611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22631.1Skamil	if (child == 0) {
22641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22661.1Skamil
22671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22691.1Skamil
22701.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22711.1Skamil
22721.13Schristos		DPRINTF("Before exiting of the child process\n");
22731.1Skamil		_exit(exitval);
22741.1Skamil	}
22751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22761.1Skamil
22771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22791.1Skamil
22801.1Skamil	validate_status_stopped(status, sigval);
22811.1Skamil
22821.1Skamil	lookup_me = magic;
22831.1Skamil
22841.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22851.1Skamil	    child, getpid());
22861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22871.1Skamil
22881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22891.1Skamil	    "without signal to be sent\n");
22901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22911.1Skamil
22921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22941.1Skamil
22951.1Skamil	validate_status_exited(status, exitval);
22961.1Skamil
22971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22991.1Skamil}
23001.1Skamil
23011.1SkamilATF_TC(io_write_d3);
23021.1SkamilATF_TC_HEAD(io_write_d3, tc)
23031.1Skamil{
23041.1Skamil	atf_tc_set_md_var(tc, "descr",
23051.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
23061.1Skamil}
23071.1Skamil
23081.1SkamilATF_TC_BODY(io_write_d3, tc)
23091.1Skamil{
23101.1Skamil	const int exitval = 5;
23111.1Skamil	const int sigval = SIGSTOP;
23121.1Skamil	pid_t child, wpid;
23131.1Skamil	uint32_t lookup_me = 0;
23141.1Skamil	const uint32_t magic = 0xab127643;
23151.1Skamil	struct ptrace_io_desc io = {
23161.1Skamil		.piod_op = PIOD_WRITE_D,
23171.1Skamil		.piod_offs = &lookup_me,
23181.1Skamil		.piod_addr = &lookup_me,
23191.1Skamil		.piod_len = sizeof(lookup_me)
23201.1Skamil	};
23211.1Skamil#if defined(TWAIT_HAVE_STATUS)
23221.1Skamil	int status;
23231.1Skamil#endif
23241.1Skamil
23251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23271.1Skamil	if (child == 0) {
23281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23301.1Skamil
23311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23331.1Skamil
23341.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23351.1Skamil
23361.13Schristos		DPRINTF("Before exiting of the child process\n");
23371.1Skamil		_exit(exitval);
23381.1Skamil	}
23391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23401.1Skamil
23411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23431.1Skamil
23441.1Skamil	validate_status_stopped(status, sigval);
23451.1Skamil
23461.1Skamil	lookup_me = magic;
23471.1Skamil
23481.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23491.1Skamil	    child, getpid());
23501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23511.1Skamil
23521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23531.1Skamil	    "without signal to be sent\n");
23541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23551.1Skamil
23561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23581.1Skamil
23591.1Skamil	validate_status_exited(status, exitval);
23601.1Skamil
23611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23631.1Skamil}
23641.1Skamil
23651.1SkamilATF_TC(io_write_d4);
23661.1SkamilATF_TC_HEAD(io_write_d4, tc)
23671.1Skamil{
23681.1Skamil	atf_tc_set_md_var(tc, "descr",
23691.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
23701.1Skamil}
23711.1Skamil
23721.1SkamilATF_TC_BODY(io_write_d4, tc)
23731.1Skamil{
23741.1Skamil	const int exitval = 5;
23751.1Skamil	const int sigval = SIGSTOP;
23761.1Skamil	pid_t child, wpid;
23771.1Skamil	uint64_t lookup_me = 0;
23781.1Skamil	const uint64_t magic = 0xab12764376490123;
23791.1Skamil	struct ptrace_io_desc io = {
23801.1Skamil		.piod_op = PIOD_WRITE_D,
23811.1Skamil		.piod_offs = &lookup_me,
23821.1Skamil		.piod_addr = &lookup_me,
23831.1Skamil		.piod_len = sizeof(lookup_me)
23841.1Skamil	};
23851.1Skamil#if defined(TWAIT_HAVE_STATUS)
23861.1Skamil	int status;
23871.1Skamil#endif
23881.1Skamil
23891.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23901.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23911.1Skamil	if (child == 0) {
23921.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23931.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23941.1Skamil
23951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23971.1Skamil
23981.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23991.1Skamil
24001.13Schristos		DPRINTF("Before exiting of the child process\n");
24011.1Skamil		_exit(exitval);
24021.1Skamil	}
24031.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24041.1Skamil
24051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24071.1Skamil
24081.1Skamil	validate_status_stopped(status, sigval);
24091.1Skamil
24101.1Skamil	lookup_me = magic;
24111.1Skamil
24121.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24131.1Skamil	    child, getpid());
24141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24151.1Skamil
24161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24171.1Skamil	    "without signal to be sent\n");
24181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24191.1Skamil
24201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24221.1Skamil
24231.1Skamil	validate_status_exited(status, exitval);
24241.1Skamil
24251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24271.1Skamil}
24281.1Skamil
24291.1SkamilATF_TC(io_read_auxv1);
24301.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
24311.1Skamil{
24321.1Skamil	atf_tc_set_md_var(tc, "descr",
24331.1Skamil	    "Verify PT_READ_AUXV called for tracee");
24341.1Skamil}
24351.1Skamil
24361.1SkamilATF_TC_BODY(io_read_auxv1, tc)
24371.1Skamil{
24381.1Skamil	const int exitval = 5;
24391.1Skamil	const int sigval = SIGSTOP;
24401.1Skamil	pid_t child, wpid;
24411.1Skamil#if defined(TWAIT_HAVE_STATUS)
24421.1Skamil	int status;
24431.1Skamil#endif
24441.1Skamil	AuxInfo ai[100], *aip;
24451.1Skamil	struct ptrace_io_desc io = {
24461.1Skamil		.piod_op = PIOD_READ_AUXV,
24471.1Skamil		.piod_offs = 0,
24481.1Skamil		.piod_addr = ai,
24491.1Skamil		.piod_len = sizeof(ai)
24501.1Skamil	};
24511.1Skamil
24521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24541.1Skamil	if (child == 0) {
24551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24571.1Skamil
24581.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24591.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24601.1Skamil
24611.13Schristos		DPRINTF("Before exiting of the child process\n");
24621.1Skamil		_exit(exitval);
24631.1Skamil	}
24641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24651.1Skamil
24661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24681.1Skamil
24691.1Skamil	validate_status_stopped(status, sigval);
24701.1Skamil
24711.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
24721.1Skamil	    child, getpid());
24731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24741.1Skamil
24751.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
24761.1Skamil	ATF_REQUIRE(io.piod_len > 0);
24771.1Skamil
24781.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
24791.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
24801.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
24811.1Skamil
24821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24831.1Skamil	    "without signal to be sent\n");
24841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24851.1Skamil
24861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24881.1Skamil
24891.1Skamil	validate_status_exited(status, exitval);
24901.1Skamil
24911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24931.1Skamil}
24941.1Skamil
24951.1SkamilATF_TC(read_d1);
24961.1SkamilATF_TC_HEAD(read_d1, tc)
24971.1Skamil{
24981.1Skamil	atf_tc_set_md_var(tc, "descr",
24991.1Skamil	    "Verify PT_READ_D called once");
25001.1Skamil}
25011.1Skamil
25021.1SkamilATF_TC_BODY(read_d1, tc)
25031.1Skamil{
25041.1Skamil	const int exitval = 5;
25051.1Skamil	const int sigval = SIGSTOP;
25061.1Skamil	pid_t child, wpid;
25071.1Skamil	int lookup_me = 0;
25081.1Skamil	const int magic = (int)random();
25091.1Skamil#if defined(TWAIT_HAVE_STATUS)
25101.1Skamil	int status;
25111.1Skamil#endif
25121.1Skamil
25131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25151.1Skamil	if (child == 0) {
25161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25181.1Skamil
25191.1Skamil		lookup_me = magic;
25201.1Skamil
25211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25231.1Skamil
25241.13Schristos		DPRINTF("Before exiting of the child process\n");
25251.1Skamil		_exit(exitval);
25261.1Skamil	}
25271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25281.1Skamil
25291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25311.1Skamil
25321.1Skamil	validate_status_stopped(status, sigval);
25331.1Skamil
25341.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
25351.1Skamil	    child, getpid());
25361.1Skamil	errno = 0;
25371.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
25381.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25391.1Skamil
25401.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
25411.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
25421.1Skamil
25431.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25441.1Skamil	    "without signal to be sent\n");
25451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25461.1Skamil
25471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25491.1Skamil
25501.1Skamil	validate_status_exited(status, exitval);
25511.1Skamil
25521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25531.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25541.1Skamil}
25551.1Skamil
25561.1SkamilATF_TC(read_d2);
25571.1SkamilATF_TC_HEAD(read_d2, tc)
25581.1Skamil{
25591.1Skamil	atf_tc_set_md_var(tc, "descr",
25601.1Skamil	    "Verify PT_READ_D called twice");
25611.1Skamil}
25621.1Skamil
25631.1SkamilATF_TC_BODY(read_d2, tc)
25641.1Skamil{
25651.1Skamil	const int exitval = 5;
25661.1Skamil	const int sigval = SIGSTOP;
25671.1Skamil	pid_t child, wpid;
25681.1Skamil	int lookup_me1 = 0;
25691.1Skamil	int lookup_me2 = 0;
25701.1Skamil	const int magic1 = (int)random();
25711.1Skamil	const int magic2 = (int)random();
25721.1Skamil#if defined(TWAIT_HAVE_STATUS)
25731.1Skamil	int status;
25741.1Skamil#endif
25751.1Skamil
25761.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25771.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25781.1Skamil	if (child == 0) {
25791.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25801.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25811.1Skamil
25821.1Skamil		lookup_me1 = magic1;
25831.1Skamil		lookup_me2 = magic2;
25841.1Skamil
25851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25871.1Skamil
25881.13Schristos		DPRINTF("Before exiting of the child process\n");
25891.1Skamil		_exit(exitval);
25901.1Skamil	}
25911.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25921.1Skamil
25931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25951.1Skamil
25961.1Skamil	validate_status_stopped(status, sigval);
25971.1Skamil
25981.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
25991.1Skamil	    child, getpid());
26001.1Skamil	errno = 0;
26011.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26021.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26031.1Skamil
26041.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26051.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26061.1Skamil
26071.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26081.1Skamil	    child, getpid());
26091.1Skamil	errno = 0;
26101.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26111.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26121.1Skamil
26131.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26141.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26151.1Skamil
26161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26171.1Skamil	    "without signal to be sent\n");
26181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26191.1Skamil
26201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26221.1Skamil
26231.1Skamil	validate_status_exited(status, exitval);
26241.1Skamil
26251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26271.1Skamil}
26281.1Skamil
26291.1SkamilATF_TC(read_d3);
26301.1SkamilATF_TC_HEAD(read_d3, tc)
26311.1Skamil{
26321.1Skamil	atf_tc_set_md_var(tc, "descr",
26331.1Skamil	    "Verify PT_READ_D called three times");
26341.1Skamil}
26351.1Skamil
26361.1SkamilATF_TC_BODY(read_d3, tc)
26371.1Skamil{
26381.1Skamil	const int exitval = 5;
26391.1Skamil	const int sigval = SIGSTOP;
26401.1Skamil	pid_t child, wpid;
26411.1Skamil	int lookup_me1 = 0;
26421.1Skamil	int lookup_me2 = 0;
26431.1Skamil	int lookup_me3 = 0;
26441.1Skamil	const int magic1 = (int)random();
26451.1Skamil	const int magic2 = (int)random();
26461.1Skamil	const int magic3 = (int)random();
26471.1Skamil#if defined(TWAIT_HAVE_STATUS)
26481.1Skamil	int status;
26491.1Skamil#endif
26501.1Skamil
26511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26531.1Skamil	if (child == 0) {
26541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26561.1Skamil
26571.1Skamil		lookup_me1 = magic1;
26581.1Skamil		lookup_me2 = magic2;
26591.1Skamil		lookup_me3 = magic3;
26601.1Skamil
26611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26631.1Skamil
26641.13Schristos		DPRINTF("Before exiting of the child process\n");
26651.1Skamil		_exit(exitval);
26661.1Skamil	}
26671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
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_stopped(status, sigval);
26731.1Skamil
26741.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26751.1Skamil	    child, getpid());
26761.1Skamil	errno = 0;
26771.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26781.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26791.1Skamil
26801.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26811.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26821.1Skamil
26831.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26841.1Skamil	    child, getpid());
26851.1Skamil	errno = 0;
26861.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26881.1Skamil
26891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26901.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26911.1Skamil
26921.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
26931.1Skamil	    child, getpid());
26941.1Skamil	errno = 0;
26951.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
26961.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26971.1Skamil
26981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
26991.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27001.1Skamil
27011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27021.1Skamil	    "without signal to be sent\n");
27031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27041.1Skamil
27051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27071.1Skamil
27081.1Skamil	validate_status_exited(status, exitval);
27091.1Skamil
27101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27121.1Skamil}
27131.1Skamil
27141.1SkamilATF_TC(read_d4);
27151.1SkamilATF_TC_HEAD(read_d4, tc)
27161.1Skamil{
27171.1Skamil	atf_tc_set_md_var(tc, "descr",
27181.1Skamil	    "Verify PT_READ_D called four times");
27191.1Skamil}
27201.1Skamil
27211.1SkamilATF_TC_BODY(read_d4, tc)
27221.1Skamil{
27231.1Skamil	const int exitval = 5;
27241.1Skamil	const int sigval = SIGSTOP;
27251.1Skamil	pid_t child, wpid;
27261.1Skamil	int lookup_me1 = 0;
27271.1Skamil	int lookup_me2 = 0;
27281.1Skamil	int lookup_me3 = 0;
27291.1Skamil	int lookup_me4 = 0;
27301.1Skamil	const int magic1 = (int)random();
27311.1Skamil	const int magic2 = (int)random();
27321.1Skamil	const int magic3 = (int)random();
27331.1Skamil	const int magic4 = (int)random();
27341.1Skamil#if defined(TWAIT_HAVE_STATUS)
27351.1Skamil	int status;
27361.1Skamil#endif
27371.1Skamil
27381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27401.1Skamil	if (child == 0) {
27411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27431.1Skamil
27441.1Skamil		lookup_me1 = magic1;
27451.1Skamil		lookup_me2 = magic2;
27461.1Skamil		lookup_me3 = magic3;
27471.1Skamil		lookup_me4 = magic4;
27481.1Skamil
27491.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27501.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27511.1Skamil
27521.13Schristos		DPRINTF("Before exiting of the child process\n");
27531.1Skamil		_exit(exitval);
27541.1Skamil	}
27551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27561.1Skamil
27571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27591.1Skamil
27601.1Skamil	validate_status_stopped(status, sigval);
27611.1Skamil
27621.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
27631.1Skamil	    child, getpid());
27641.1Skamil	errno = 0;
27651.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
27661.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27671.1Skamil
27681.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27691.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27701.1Skamil
27711.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27721.1Skamil	    child, getpid());
27731.1Skamil	errno = 0;
27741.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27751.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27761.1Skamil
27771.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27781.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27791.1Skamil
27801.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27811.1Skamil	    child, getpid());
27821.1Skamil	errno = 0;
27831.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27841.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27851.1Skamil
27861.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27871.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27881.1Skamil
27891.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
27901.1Skamil	    child, getpid());
27911.1Skamil	errno = 0;
27921.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
27931.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27941.1Skamil
27951.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
27961.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
27971.1Skamil
27981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27991.1Skamil	    "without signal to be sent\n");
28001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28011.1Skamil
28021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28041.1Skamil
28051.1Skamil	validate_status_exited(status, exitval);
28061.1Skamil
28071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28091.1Skamil}
28101.1Skamil
28111.1SkamilATF_TC(write_d1);
28121.1SkamilATF_TC_HEAD(write_d1, tc)
28131.1Skamil{
28141.1Skamil	atf_tc_set_md_var(tc, "descr",
28151.1Skamil	    "Verify PT_WRITE_D called once");
28161.1Skamil}
28171.1Skamil
28181.1SkamilATF_TC_BODY(write_d1, tc)
28191.1Skamil{
28201.1Skamil	const int exitval = 5;
28211.1Skamil	const int sigval = SIGSTOP;
28221.1Skamil	pid_t child, wpid;
28231.1Skamil	int lookup_me = 0;
28241.1Skamil	const int magic = (int)random();
28251.1Skamil#if defined(TWAIT_HAVE_STATUS)
28261.1Skamil	int status;
28271.1Skamil#endif
28281.1Skamil
28291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28311.1Skamil	if (child == 0) {
28321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28341.1Skamil
28351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28371.1Skamil
28381.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
28391.1Skamil
28401.13Schristos		DPRINTF("Before exiting of the child process\n");
28411.1Skamil		_exit(exitval);
28421.1Skamil	}
28431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28441.1Skamil
28451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28471.1Skamil
28481.1Skamil	validate_status_stopped(status, sigval);
28491.1Skamil
28501.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
28511.1Skamil	    child, getpid());
28521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
28531.1Skamil
28541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28551.1Skamil	    "without signal to be sent\n");
28561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28571.1Skamil
28581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28601.1Skamil
28611.1Skamil	validate_status_exited(status, exitval);
28621.1Skamil
28631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28651.1Skamil}
28661.1Skamil
28671.1SkamilATF_TC(write_d2);
28681.1SkamilATF_TC_HEAD(write_d2, tc)
28691.1Skamil{
28701.1Skamil	atf_tc_set_md_var(tc, "descr",
28711.1Skamil	    "Verify PT_WRITE_D called twice");
28721.1Skamil}
28731.1Skamil
28741.1SkamilATF_TC_BODY(write_d2, tc)
28751.1Skamil{
28761.1Skamil	const int exitval = 5;
28771.1Skamil	const int sigval = SIGSTOP;
28781.1Skamil	pid_t child, wpid;
28791.1Skamil	int lookup_me1 = 0;
28801.1Skamil	int lookup_me2 = 0;
28811.1Skamil	const int magic1 = (int)random();
28821.1Skamil	const int magic2 = (int)random();
28831.1Skamil#if defined(TWAIT_HAVE_STATUS)
28841.1Skamil	int status;
28851.1Skamil#endif
28861.1Skamil
28871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28891.1Skamil	if (child == 0) {
28901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28921.1Skamil
28931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28951.1Skamil
28961.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
28971.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
28981.1Skamil
28991.13Schristos		DPRINTF("Before exiting of the child process\n");
29001.1Skamil		_exit(exitval);
29011.1Skamil	}
29021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29031.1Skamil
29041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29061.1Skamil
29071.1Skamil	validate_status_stopped(status, sigval);
29081.1Skamil
29091.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29101.1Skamil	    child, getpid());
29111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29121.1Skamil
29131.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29141.1Skamil	    child, getpid());
29151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29161.1Skamil
29171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29181.1Skamil	    "without signal to be sent\n");
29191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29201.1Skamil
29211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29231.1Skamil
29241.1Skamil	validate_status_exited(status, exitval);
29251.1Skamil
29261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29281.1Skamil}
29291.1Skamil
29301.1SkamilATF_TC(write_d3);
29311.1SkamilATF_TC_HEAD(write_d3, tc)
29321.1Skamil{
29331.1Skamil	atf_tc_set_md_var(tc, "descr",
29341.1Skamil	    "Verify PT_WRITE_D called three times");
29351.1Skamil}
29361.1Skamil
29371.1SkamilATF_TC_BODY(write_d3, tc)
29381.1Skamil{
29391.1Skamil	const int exitval = 5;
29401.1Skamil	const int sigval = SIGSTOP;
29411.1Skamil	pid_t child, wpid;
29421.1Skamil	int lookup_me1 = 0;
29431.1Skamil	int lookup_me2 = 0;
29441.1Skamil	int lookup_me3 = 0;
29451.1Skamil	const int magic1 = (int)random();
29461.1Skamil	const int magic2 = (int)random();
29471.1Skamil	const int magic3 = (int)random();
29481.1Skamil#if defined(TWAIT_HAVE_STATUS)
29491.1Skamil	int status;
29501.1Skamil#endif
29511.1Skamil
29521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29541.1Skamil	if (child == 0) {
29551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29571.1Skamil
29581.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29591.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29601.1Skamil
29611.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29621.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29631.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
29641.1Skamil
29651.13Schristos		DPRINTF("Before exiting of the child process\n");
29661.1Skamil		_exit(exitval);
29671.1Skamil	}
29681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29691.1Skamil
29701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29721.1Skamil
29731.1Skamil	validate_status_stopped(status, sigval);
29741.1Skamil
29751.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29761.1Skamil	    child, getpid());
29771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29781.1Skamil
29791.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29801.1Skamil	    child, getpid());
29811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29821.1Skamil
29831.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
29841.1Skamil	    child, getpid());
29851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
29861.1Skamil
29871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29881.1Skamil	    "without signal to be sent\n");
29891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29901.1Skamil
29911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29931.1Skamil
29941.1Skamil	validate_status_exited(status, exitval);
29951.1Skamil
29961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29981.1Skamil}
29991.1Skamil
30001.1SkamilATF_TC(write_d4);
30011.1SkamilATF_TC_HEAD(write_d4, tc)
30021.1Skamil{
30031.1Skamil	atf_tc_set_md_var(tc, "descr",
30041.1Skamil	    "Verify PT_WRITE_D called four times");
30051.1Skamil}
30061.1Skamil
30071.1SkamilATF_TC_BODY(write_d4, tc)
30081.1Skamil{
30091.1Skamil	const int exitval = 5;
30101.1Skamil	const int sigval = SIGSTOP;
30111.1Skamil	pid_t child, wpid;
30121.1Skamil	int lookup_me1 = 0;
30131.1Skamil	int lookup_me2 = 0;
30141.1Skamil	int lookup_me3 = 0;
30151.1Skamil	int lookup_me4 = 0;
30161.1Skamil	const int magic1 = (int)random();
30171.1Skamil	const int magic2 = (int)random();
30181.1Skamil	const int magic3 = (int)random();
30191.1Skamil	const int magic4 = (int)random();
30201.1Skamil#if defined(TWAIT_HAVE_STATUS)
30211.1Skamil	int status;
30221.1Skamil#endif
30231.1Skamil
30241.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30251.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30261.1Skamil	if (child == 0) {
30271.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30281.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30291.1Skamil
30301.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30311.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30321.1Skamil
30331.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
30341.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
30351.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
30361.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
30371.1Skamil
30381.13Schristos		DPRINTF("Before exiting of the child process\n");
30391.1Skamil		_exit(exitval);
30401.1Skamil	}
30411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30421.1Skamil
30431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30451.1Skamil
30461.1Skamil	validate_status_stopped(status, sigval);
30471.1Skamil
30481.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
30491.1Skamil	    child, getpid());
30501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
30511.1Skamil
30521.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30531.1Skamil	    child, getpid());
30541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30551.1Skamil
30561.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30571.1Skamil	    child, getpid());
30581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30591.1Skamil
30601.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
30611.1Skamil	    child, getpid());
30621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
30631.1Skamil
30641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30651.1Skamil	    "without signal to be sent\n");
30661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30671.1Skamil
30681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30701.1Skamil
30711.1Skamil	validate_status_exited(status, exitval);
30721.1Skamil
30731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30751.1Skamil}
30761.1Skamil
30771.1SkamilATF_TC(io_read_d_write_d_handshake1);
30781.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
30791.1Skamil{
30801.1Skamil	atf_tc_set_md_var(tc, "descr",
30811.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
30821.1Skamil}
30831.1Skamil
30841.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
30851.1Skamil{
30861.1Skamil	const int exitval = 5;
30871.1Skamil	const int sigval = SIGSTOP;
30881.1Skamil	pid_t child, wpid;
30891.1Skamil	uint8_t lookup_me_fromtracee = 0;
30901.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
30911.1Skamil	uint8_t lookup_me_totracee = 0;
30921.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
30931.1Skamil	struct ptrace_io_desc io_fromtracee = {
30941.1Skamil		.piod_op = PIOD_READ_D,
30951.1Skamil		.piod_offs = &lookup_me_fromtracee,
30961.1Skamil		.piod_addr = &lookup_me_fromtracee,
30971.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
30981.1Skamil	};
30991.1Skamil	struct ptrace_io_desc io_totracee = {
31001.1Skamil		.piod_op = PIOD_WRITE_D,
31011.1Skamil		.piod_offs = &lookup_me_totracee,
31021.1Skamil		.piod_addr = &lookup_me_totracee,
31031.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31041.1Skamil	};
31051.1Skamil#if defined(TWAIT_HAVE_STATUS)
31061.1Skamil	int status;
31071.1Skamil#endif
31081.1Skamil
31091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31111.1Skamil	if (child == 0) {
31121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31141.1Skamil
31151.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31161.1Skamil
31171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31191.1Skamil
31201.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31211.1Skamil
31221.13Schristos		DPRINTF("Before exiting of the child process\n");
31231.1Skamil		_exit(exitval);
31241.1Skamil	}
31251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31261.1Skamil
31271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31291.1Skamil
31301.1Skamil	validate_status_stopped(status, sigval);
31311.1Skamil
31321.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31331.1Skamil	    child, getpid());
31341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
31351.1Skamil
31361.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31371.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
31381.1Skamil	    magic_fromtracee);
31391.1Skamil
31401.1Skamil	lookup_me_totracee = magic_totracee;
31411.1Skamil
31421.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
31431.1Skamil	    child, getpid());
31441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
31451.1Skamil
31461.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
31471.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
31481.1Skamil	    magic_totracee);
31491.1Skamil
31501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31511.1Skamil	    "without signal to be sent\n");
31521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31531.1Skamil
31541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31561.1Skamil
31571.1Skamil	validate_status_exited(status, exitval);
31581.1Skamil
31591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31611.1Skamil}
31621.1Skamil
31631.1SkamilATF_TC(io_read_d_write_d_handshake2);
31641.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
31651.1Skamil{
31661.1Skamil	atf_tc_set_md_var(tc, "descr",
31671.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
31681.1Skamil}
31691.1Skamil
31701.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
31711.1Skamil{
31721.1Skamil	const int exitval = 5;
31731.1Skamil	const int sigval = SIGSTOP;
31741.1Skamil	pid_t child, wpid;
31751.1Skamil	uint8_t lookup_me_fromtracee = 0;
31761.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31771.1Skamil	uint8_t lookup_me_totracee = 0;
31781.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31791.1Skamil	struct ptrace_io_desc io_fromtracee = {
31801.1Skamil		.piod_op = PIOD_READ_D,
31811.1Skamil		.piod_offs = &lookup_me_fromtracee,
31821.1Skamil		.piod_addr = &lookup_me_fromtracee,
31831.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31841.1Skamil	};
31851.1Skamil	struct ptrace_io_desc io_totracee = {
31861.1Skamil		.piod_op = PIOD_WRITE_D,
31871.1Skamil		.piod_offs = &lookup_me_totracee,
31881.1Skamil		.piod_addr = &lookup_me_totracee,
31891.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31901.1Skamil	};
31911.1Skamil#if defined(TWAIT_HAVE_STATUS)
31921.1Skamil	int status;
31931.1Skamil#endif
31941.1Skamil
31951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31971.1Skamil	if (child == 0) {
31981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32001.1Skamil
32011.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32021.1Skamil
32031.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32041.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32051.1Skamil
32061.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32071.1Skamil
32081.13Schristos		DPRINTF("Before exiting of the child process\n");
32091.1Skamil		_exit(exitval);
32101.1Skamil	}
32111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32121.1Skamil
32131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32151.1Skamil
32161.1Skamil	validate_status_stopped(status, sigval);
32171.1Skamil
32181.1Skamil	lookup_me_totracee = magic_totracee;
32191.1Skamil
32201.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
32211.1Skamil	    child, getpid());
32221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
32231.1Skamil
32241.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
32251.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
32261.1Skamil	    magic_totracee);
32271.1Skamil
32281.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32291.1Skamil	    child, getpid());
32301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
32311.1Skamil
32321.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32331.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
32341.1Skamil	    magic_fromtracee);
32351.1Skamil
32361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32371.1Skamil	    "without signal to be sent\n");
32381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32391.1Skamil
32401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32421.1Skamil
32431.1Skamil	validate_status_exited(status, exitval);
32441.1Skamil
32451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32471.1Skamil}
32481.1Skamil
32491.1SkamilATF_TC(read_d_write_d_handshake1);
32501.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
32511.1Skamil{
32521.1Skamil	atf_tc_set_md_var(tc, "descr",
32531.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
32541.1Skamil}
32551.1Skamil
32561.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
32571.1Skamil{
32581.1Skamil	const int exitval = 5;
32591.1Skamil	const int sigval = SIGSTOP;
32601.1Skamil	pid_t child, wpid;
32611.1Skamil	int lookup_me_fromtracee = 0;
32621.1Skamil	const int magic_fromtracee = (int)random();
32631.1Skamil	int lookup_me_totracee = 0;
32641.1Skamil	const int magic_totracee = (int)random();
32651.1Skamil#if defined(TWAIT_HAVE_STATUS)
32661.1Skamil	int status;
32671.1Skamil#endif
32681.1Skamil
32691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32711.1Skamil	if (child == 0) {
32721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32741.1Skamil
32751.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32761.1Skamil
32771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32791.1Skamil
32801.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32811.1Skamil
32821.13Schristos		DPRINTF("Before exiting of the child process\n");
32831.1Skamil		_exit(exitval);
32841.1Skamil	}
32851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32861.1Skamil
32871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32891.1Skamil
32901.1Skamil	validate_status_stopped(status, sigval);
32911.1Skamil
32921.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32931.1Skamil	    child, getpid());
32941.1Skamil	errno = 0;
32951.1Skamil	lookup_me_fromtracee =
32961.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
32971.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
32981.1Skamil
32991.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33001.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33011.1Skamil	    magic_fromtracee);
33021.1Skamil
33031.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33041.1Skamil	    child, getpid());
33051.1Skamil	ATF_REQUIRE
33061.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33071.1Skamil	    != -1);
33081.1Skamil
33091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33101.1Skamil	    "without signal to be sent\n");
33111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33121.1Skamil
33131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33151.1Skamil
33161.1Skamil	validate_status_exited(status, exitval);
33171.1Skamil
33181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33201.1Skamil}
33211.1Skamil
33221.1SkamilATF_TC(read_d_write_d_handshake2);
33231.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
33241.1Skamil{
33251.1Skamil	atf_tc_set_md_var(tc, "descr",
33261.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
33271.1Skamil}
33281.1Skamil
33291.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
33301.1Skamil{
33311.1Skamil	const int exitval = 5;
33321.1Skamil	const int sigval = SIGSTOP;
33331.1Skamil	pid_t child, wpid;
33341.1Skamil	int lookup_me_fromtracee = 0;
33351.1Skamil	const int magic_fromtracee = (int)random();
33361.1Skamil	int lookup_me_totracee = 0;
33371.1Skamil	const int magic_totracee = (int)random();
33381.1Skamil#if defined(TWAIT_HAVE_STATUS)
33391.1Skamil	int status;
33401.1Skamil#endif
33411.1Skamil
33421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33441.1Skamil	if (child == 0) {
33451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33471.1Skamil
33481.1Skamil		lookup_me_fromtracee = magic_fromtracee;
33491.1Skamil
33501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33521.1Skamil
33531.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33541.1Skamil
33551.13Schristos		DPRINTF("Before exiting of the child process\n");
33561.1Skamil		_exit(exitval);
33571.1Skamil	}
33581.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33591.1Skamil
33601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33621.1Skamil
33631.1Skamil	validate_status_stopped(status, sigval);
33641.1Skamil
33651.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33661.1Skamil	    child, getpid());
33671.1Skamil	ATF_REQUIRE
33681.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33691.1Skamil	    != -1);
33701.1Skamil
33711.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33721.1Skamil	    child, getpid());
33731.1Skamil	errno = 0;
33741.1Skamil	lookup_me_fromtracee =
33751.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33761.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33771.1Skamil
33781.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33791.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33801.1Skamil	    magic_fromtracee);
33811.1Skamil
33821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33831.1Skamil	    "without signal to be sent\n");
33841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33851.1Skamil
33861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33881.1Skamil
33891.1Skamil	validate_status_exited(status, exitval);
33901.1Skamil
33911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33931.1Skamil}
33941.1Skamil
33951.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
33961.1Skamilstatic int __used
33971.1Skamildummy_fn1(int a, int b, int c, int d)
33981.1Skamil{
33991.1Skamil
34001.1Skamil	a *= 1;
34011.1Skamil	b += 2;
34021.1Skamil	c -= 3;
34031.1Skamil	d /= 4;
34041.1Skamil
34051.1Skamil	return a + b * c - d;
34061.1Skamil}
34071.1Skamil
34081.1Skamilstatic int __used
34091.1Skamildummy_fn2(int a, int b, int c, int d)
34101.1Skamil{
34111.1Skamil
34121.1Skamil	a *= 4;
34131.1Skamil	b += 3;
34141.1Skamil	c -= 2;
34151.1Skamil	d /= 1;
34161.1Skamil
34171.1Skamil	return a + b * c - d;
34181.1Skamil}
34191.1Skamil
34201.1Skamilstatic int __used
34211.1Skamildummy_fn3(int a, int b, int c, int d)
34221.1Skamil{
34231.1Skamil
34241.1Skamil	a *= 10;
34251.1Skamil	b += 20;
34261.1Skamil	c -= 30;
34271.1Skamil	d /= 40;
34281.1Skamil
34291.1Skamil	return a + b * c - d;
34301.1Skamil}
34311.1Skamil
34321.1Skamilstatic int __used
34331.1Skamildummy_fn4(int a, int b, int c, int d)
34341.1Skamil{
34351.1Skamil
34361.1Skamil	a *= 40;
34371.1Skamil	b += 30;
34381.1Skamil	c -= 20;
34391.1Skamil	d /= 10;
34401.1Skamil
34411.1Skamil	return a + b * c - d;
34421.1Skamil}
34431.1Skamil
34441.1SkamilATF_TC(io_read_i1);
34451.1SkamilATF_TC_HEAD(io_read_i1, tc)
34461.1Skamil{
34471.1Skamil	atf_tc_set_md_var(tc, "descr",
34481.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
34491.1Skamil}
34501.1Skamil
34511.1SkamilATF_TC_BODY(io_read_i1, tc)
34521.1Skamil{
34531.1Skamil	const int exitval = 5;
34541.1Skamil	const int sigval = SIGSTOP;
34551.1Skamil	pid_t child, wpid;
34561.1Skamil	uint8_t lookup_me = 0;
34571.1Skamil	uint8_t magic;
34581.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34591.1Skamil	struct ptrace_io_desc io = {
34601.1Skamil		.piod_op = PIOD_READ_I,
34611.1Skamil		.piod_offs = dummy_fn1,
34621.1Skamil		.piod_addr = &lookup_me,
34631.1Skamil		.piod_len = sizeof(lookup_me)
34641.1Skamil	};
34651.1Skamil#if defined(TWAIT_HAVE_STATUS)
34661.1Skamil	int status;
34671.1Skamil#endif
34681.1Skamil
34691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34711.1Skamil	if (child == 0) {
34721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34741.1Skamil
34751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34771.1Skamil
34781.13Schristos		DPRINTF("Before exiting of the child process\n");
34791.1Skamil		_exit(exitval);
34801.1Skamil	}
34811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34821.1Skamil
34831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34851.1Skamil
34861.1Skamil	validate_status_stopped(status, sigval);
34871.1Skamil
34881.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34891.1Skamil	    child, getpid());
34901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34911.1Skamil
34921.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34931.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
34941.1Skamil
34951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34961.1Skamil	    "without signal to be sent\n");
34971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34981.1Skamil
34991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35011.1Skamil
35021.1Skamil	validate_status_exited(status, exitval);
35031.1Skamil
35041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35061.1Skamil}
35071.1Skamil
35081.1SkamilATF_TC(io_read_i2);
35091.1SkamilATF_TC_HEAD(io_read_i2, tc)
35101.1Skamil{
35111.1Skamil	atf_tc_set_md_var(tc, "descr",
35121.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
35131.1Skamil}
35141.1Skamil
35151.1SkamilATF_TC_BODY(io_read_i2, tc)
35161.1Skamil{
35171.1Skamil	const int exitval = 5;
35181.1Skamil	const int sigval = SIGSTOP;
35191.1Skamil	pid_t child, wpid;
35201.1Skamil	uint16_t lookup_me = 0;
35211.1Skamil	uint16_t magic;
35221.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35231.1Skamil	struct ptrace_io_desc io = {
35241.1Skamil		.piod_op = PIOD_READ_I,
35251.1Skamil		.piod_offs = dummy_fn1,
35261.1Skamil		.piod_addr = &lookup_me,
35271.1Skamil		.piod_len = sizeof(lookup_me)
35281.1Skamil	};
35291.1Skamil#if defined(TWAIT_HAVE_STATUS)
35301.1Skamil	int status;
35311.1Skamil#endif
35321.1Skamil
35331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35351.1Skamil	if (child == 0) {
35361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35381.1Skamil
35391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35411.1Skamil
35421.13Schristos		DPRINTF("Before exiting of the child process\n");
35431.1Skamil		_exit(exitval);
35441.1Skamil	}
35451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35461.1Skamil
35471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35491.1Skamil
35501.1Skamil	validate_status_stopped(status, sigval);
35511.1Skamil
35521.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35531.1Skamil	    child, getpid());
35541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35551.1Skamil
35561.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35571.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
35581.1Skamil
35591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35601.1Skamil	    "without signal to be sent\n");
35611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35621.1Skamil
35631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35651.1Skamil
35661.1Skamil	validate_status_exited(status, exitval);
35671.1Skamil
35681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35701.1Skamil}
35711.1Skamil
35721.1SkamilATF_TC(io_read_i3);
35731.1SkamilATF_TC_HEAD(io_read_i3, tc)
35741.1Skamil{
35751.1Skamil	atf_tc_set_md_var(tc, "descr",
35761.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
35771.1Skamil}
35781.1Skamil
35791.1SkamilATF_TC_BODY(io_read_i3, tc)
35801.1Skamil{
35811.1Skamil	const int exitval = 5;
35821.1Skamil	const int sigval = SIGSTOP;
35831.1Skamil	pid_t child, wpid;
35841.1Skamil	uint32_t lookup_me = 0;
35851.1Skamil	uint32_t magic;
35861.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35871.1Skamil	struct ptrace_io_desc io = {
35881.1Skamil		.piod_op = PIOD_READ_I,
35891.1Skamil		.piod_offs = dummy_fn1,
35901.1Skamil		.piod_addr = &lookup_me,
35911.1Skamil		.piod_len = sizeof(lookup_me)
35921.1Skamil	};
35931.1Skamil#if defined(TWAIT_HAVE_STATUS)
35941.1Skamil	int status;
35951.1Skamil#endif
35961.1Skamil
35971.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35981.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35991.1Skamil	if (child == 0) {
36001.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36011.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36021.1Skamil
36031.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36041.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36051.1Skamil
36061.13Schristos		DPRINTF("Before exiting of the child process\n");
36071.1Skamil		_exit(exitval);
36081.1Skamil	}
36091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36101.1Skamil
36111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36131.1Skamil
36141.1Skamil	validate_status_stopped(status, sigval);
36151.1Skamil
36161.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36171.1Skamil	    child, getpid());
36181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36191.1Skamil
36201.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36211.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
36221.1Skamil
36231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36241.1Skamil	    "without signal to be sent\n");
36251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36261.1Skamil
36271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36291.1Skamil
36301.1Skamil	validate_status_exited(status, exitval);
36311.1Skamil
36321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36341.1Skamil}
36351.1Skamil
36361.1SkamilATF_TC(io_read_i4);
36371.1SkamilATF_TC_HEAD(io_read_i4, tc)
36381.1Skamil{
36391.1Skamil	atf_tc_set_md_var(tc, "descr",
36401.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
36411.1Skamil}
36421.1Skamil
36431.1SkamilATF_TC_BODY(io_read_i4, tc)
36441.1Skamil{
36451.1Skamil	const int exitval = 5;
36461.1Skamil	const int sigval = SIGSTOP;
36471.1Skamil	pid_t child, wpid;
36481.1Skamil	uint64_t lookup_me = 0;
36491.1Skamil	uint64_t magic;
36501.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36511.1Skamil	struct ptrace_io_desc io = {
36521.1Skamil		.piod_op = PIOD_READ_I,
36531.1Skamil		.piod_offs = dummy_fn1,
36541.1Skamil		.piod_addr = &lookup_me,
36551.1Skamil		.piod_len = sizeof(lookup_me)
36561.1Skamil	};
36571.1Skamil#if defined(TWAIT_HAVE_STATUS)
36581.1Skamil	int status;
36591.1Skamil#endif
36601.1Skamil
36611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36631.1Skamil	if (child == 0) {
36641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36661.1Skamil
36671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36691.1Skamil
36701.13Schristos		DPRINTF("Before exiting of the child process\n");
36711.1Skamil		_exit(exitval);
36721.1Skamil	}
36731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36741.1Skamil
36751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36771.1Skamil
36781.1Skamil	validate_status_stopped(status, sigval);
36791.1Skamil
36801.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36811.1Skamil	    child, getpid());
36821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36831.1Skamil
36841.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36851.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
36861.1Skamil
36871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36881.1Skamil	    "without signal to be sent\n");
36891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36901.1Skamil
36911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36931.1Skamil
36941.1Skamil	validate_status_exited(status, exitval);
36951.1Skamil
36961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36981.1Skamil}
36991.1Skamil
37001.1SkamilATF_TC(read_i1);
37011.1SkamilATF_TC_HEAD(read_i1, tc)
37021.1Skamil{
37031.1Skamil	atf_tc_set_md_var(tc, "descr",
37041.1Skamil	    "Verify PT_READ_I called once");
37051.1Skamil}
37061.1Skamil
37071.1SkamilATF_TC_BODY(read_i1, tc)
37081.1Skamil{
37091.1Skamil	const int exitval = 5;
37101.1Skamil	const int sigval = SIGSTOP;
37111.1Skamil	pid_t child, wpid;
37121.1Skamil	int lookup_me = 0;
37131.1Skamil	int magic;
37141.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
37151.1Skamil#if defined(TWAIT_HAVE_STATUS)
37161.1Skamil	int status;
37171.1Skamil#endif
37181.1Skamil
37191.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37201.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37211.1Skamil	if (child == 0) {
37221.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37231.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37241.1Skamil
37251.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37261.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37271.1Skamil
37281.13Schristos		DPRINTF("Before exiting of the child process\n");
37291.1Skamil		_exit(exitval);
37301.1Skamil	}
37311.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37321.1Skamil
37331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37351.1Skamil
37361.1Skamil	validate_status_stopped(status, sigval);
37371.1Skamil
37381.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37391.1Skamil	    child, getpid());
37401.1Skamil	errno = 0;
37411.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
37421.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37431.1Skamil
37441.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37451.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
37461.1Skamil
37471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37481.1Skamil	    "without signal to be sent\n");
37491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37501.1Skamil
37511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37531.1Skamil
37541.1Skamil	validate_status_exited(status, exitval);
37551.1Skamil
37561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37581.1Skamil}
37591.1Skamil
37601.1SkamilATF_TC(read_i2);
37611.1SkamilATF_TC_HEAD(read_i2, tc)
37621.1Skamil{
37631.1Skamil	atf_tc_set_md_var(tc, "descr",
37641.1Skamil	    "Verify PT_READ_I called twice");
37651.1Skamil}
37661.1Skamil
37671.1SkamilATF_TC_BODY(read_i2, tc)
37681.1Skamil{
37691.1Skamil	const int exitval = 5;
37701.1Skamil	const int sigval = SIGSTOP;
37711.1Skamil	pid_t child, wpid;
37721.1Skamil	int lookup_me1 = 0;
37731.1Skamil	int lookup_me2 = 0;
37741.1Skamil	int magic1;
37751.1Skamil	int magic2;
37761.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37771.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37781.1Skamil#if defined(TWAIT_HAVE_STATUS)
37791.1Skamil	int status;
37801.1Skamil#endif
37811.1Skamil
37821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37841.1Skamil	if (child == 0) {
37851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37871.1Skamil
37881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37901.1Skamil
37911.13Schristos		DPRINTF("Before exiting of the child process\n");
37921.1Skamil		_exit(exitval);
37931.1Skamil	}
37941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37951.1Skamil
37961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37981.1Skamil
37991.1Skamil	validate_status_stopped(status, sigval);
38001.1Skamil
38011.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38021.1Skamil	    child, getpid());
38031.1Skamil	errno = 0;
38041.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38051.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38061.1Skamil
38071.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38081.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38091.1Skamil
38101.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38111.1Skamil	    child, getpid());
38121.1Skamil	errno = 0;
38131.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38141.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38151.1Skamil
38161.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38171.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38181.1Skamil
38191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38201.1Skamil	    "without signal to be sent\n");
38211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38221.1Skamil
38231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38251.1Skamil
38261.1Skamil	validate_status_exited(status, exitval);
38271.1Skamil
38281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38301.1Skamil}
38311.1Skamil
38321.1SkamilATF_TC(read_i3);
38331.1SkamilATF_TC_HEAD(read_i3, tc)
38341.1Skamil{
38351.1Skamil	atf_tc_set_md_var(tc, "descr",
38361.1Skamil	    "Verify PT_READ_I called three times");
38371.1Skamil}
38381.1Skamil
38391.1SkamilATF_TC_BODY(read_i3, tc)
38401.1Skamil{
38411.1Skamil	const int exitval = 5;
38421.1Skamil	const int sigval = SIGSTOP;
38431.1Skamil	pid_t child, wpid;
38441.1Skamil	int lookup_me1 = 0;
38451.1Skamil	int lookup_me2 = 0;
38461.1Skamil	int lookup_me3 = 0;
38471.1Skamil	int magic1;
38481.1Skamil	int magic2;
38491.1Skamil	int magic3;
38501.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
38511.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
38521.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
38531.1Skamil#if defined(TWAIT_HAVE_STATUS)
38541.1Skamil	int status;
38551.1Skamil#endif
38561.1Skamil
38571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38591.1Skamil	if (child == 0) {
38601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38621.1Skamil
38631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38651.1Skamil
38661.13Schristos		DPRINTF("Before exiting of the child process\n");
38671.1Skamil		_exit(exitval);
38681.1Skamil	}
38691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38701.1Skamil
38711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38731.1Skamil
38741.1Skamil	validate_status_stopped(status, sigval);
38751.1Skamil
38761.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38771.1Skamil	    child, getpid());
38781.1Skamil	errno = 0;
38791.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38801.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38811.1Skamil
38821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38831.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38841.1Skamil
38851.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38861.1Skamil	    child, getpid());
38871.1Skamil	errno = 0;
38881.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38891.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38901.1Skamil
38911.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38921.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38931.1Skamil
38941.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
38951.1Skamil	    child, getpid());
38961.1Skamil	errno = 0;
38971.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
38981.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38991.1Skamil
39001.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39011.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39021.1Skamil
39031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39041.1Skamil	    "without signal to be sent\n");
39051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39061.1Skamil
39071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39091.1Skamil
39101.1Skamil	validate_status_exited(status, exitval);
39111.1Skamil
39121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39141.1Skamil}
39151.1Skamil
39161.1SkamilATF_TC(read_i4);
39171.1SkamilATF_TC_HEAD(read_i4, tc)
39181.1Skamil{
39191.1Skamil	atf_tc_set_md_var(tc, "descr",
39201.1Skamil	    "Verify PT_READ_I called four times");
39211.1Skamil}
39221.1Skamil
39231.1SkamilATF_TC_BODY(read_i4, tc)
39241.1Skamil{
39251.1Skamil	const int exitval = 5;
39261.1Skamil	const int sigval = SIGSTOP;
39271.1Skamil	pid_t child, wpid;
39281.1Skamil	int lookup_me1 = 0;
39291.1Skamil	int lookup_me2 = 0;
39301.1Skamil	int lookup_me3 = 0;
39311.1Skamil	int lookup_me4 = 0;
39321.1Skamil	int magic1;
39331.1Skamil	int magic2;
39341.1Skamil	int magic3;
39351.1Skamil	int magic4;
39361.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
39371.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
39381.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
39391.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
39401.1Skamil#if defined(TWAIT_HAVE_STATUS)
39411.1Skamil	int status;
39421.1Skamil#endif
39431.1Skamil
39441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39461.1Skamil	if (child == 0) {
39471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39491.1Skamil
39501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39521.1Skamil
39531.13Schristos		DPRINTF("Before exiting of the child process\n");
39541.1Skamil		_exit(exitval);
39551.1Skamil	}
39561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39571.1Skamil
39581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39601.1Skamil
39611.1Skamil	validate_status_stopped(status, sigval);
39621.1Skamil
39631.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
39641.1Skamil	    child, getpid());
39651.1Skamil	errno = 0;
39661.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39671.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39681.1Skamil
39691.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39701.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39711.1Skamil
39721.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39731.1Skamil	    child, getpid());
39741.1Skamil	errno = 0;
39751.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39761.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39771.1Skamil
39781.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39791.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39801.1Skamil
39811.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39821.1Skamil	    child, getpid());
39831.1Skamil	errno = 0;
39841.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39851.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39861.1Skamil
39871.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39881.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39891.1Skamil
39901.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
39911.1Skamil	    child, getpid());
39921.1Skamil	errno = 0;
39931.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
39941.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39951.1Skamil
39961.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
39971.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
39981.1Skamil
39991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40001.1Skamil	    "without signal to be sent\n");
40011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40021.1Skamil
40031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40051.1Skamil
40061.1Skamil	validate_status_exited(status, exitval);
40071.1Skamil
40081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40101.1Skamil}
40111.1Skamil
40121.1Skamil#if defined(HAVE_GPREGS)
40131.1SkamilATF_TC(regs1);
40141.1SkamilATF_TC_HEAD(regs1, tc)
40151.1Skamil{
40161.1Skamil	atf_tc_set_md_var(tc, "descr",
40171.1Skamil	    "Verify plain PT_GETREGS call without further steps");
40181.1Skamil}
40191.1Skamil
40201.1SkamilATF_TC_BODY(regs1, tc)
40211.1Skamil{
40221.1Skamil	const int exitval = 5;
40231.1Skamil	const int sigval = SIGSTOP;
40241.1Skamil	pid_t child, wpid;
40251.1Skamil#if defined(TWAIT_HAVE_STATUS)
40261.1Skamil	int status;
40271.1Skamil#endif
40281.1Skamil	struct reg r;
40291.1Skamil
40301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40321.1Skamil	if (child == 0) {
40331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40351.1Skamil
40361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40381.1Skamil
40391.13Schristos		DPRINTF("Before exiting of the child process\n");
40401.1Skamil		_exit(exitval);
40411.1Skamil	}
40421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40431.1Skamil
40441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40461.1Skamil
40471.1Skamil	validate_status_stopped(status, sigval);
40481.1Skamil
40491.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40511.1Skamil
40521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40531.1Skamil	    "without signal to be sent\n");
40541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40551.1Skamil
40561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40581.1Skamil
40591.1Skamil	validate_status_exited(status, exitval);
40601.1Skamil
40611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40631.1Skamil}
40641.1Skamil#endif
40651.1Skamil
40661.1Skamil#if defined(HAVE_GPREGS)
40671.1SkamilATF_TC(regs2);
40681.1SkamilATF_TC_HEAD(regs2, tc)
40691.1Skamil{
40701.1Skamil	atf_tc_set_md_var(tc, "descr",
40711.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
40721.1Skamil}
40731.1Skamil
40741.1SkamilATF_TC_BODY(regs2, tc)
40751.1Skamil{
40761.1Skamil	const int exitval = 5;
40771.1Skamil	const int sigval = SIGSTOP;
40781.1Skamil	pid_t child, wpid;
40791.1Skamil#if defined(TWAIT_HAVE_STATUS)
40801.1Skamil	int status;
40811.1Skamil#endif
40821.1Skamil	struct reg r;
40831.1Skamil
40841.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40851.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40861.1Skamil	if (child == 0) {
40871.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40881.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40891.1Skamil
40901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40921.1Skamil
40931.13Schristos		DPRINTF("Before exiting of the child process\n");
40941.1Skamil		_exit(exitval);
40951.1Skamil	}
40961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40971.1Skamil
40981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41001.1Skamil
41011.1Skamil	validate_status_stopped(status, sigval);
41021.1Skamil
41031.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41051.1Skamil
41061.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
41071.1Skamil
41081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41091.1Skamil	    "without signal to be sent\n");
41101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41111.1Skamil
41121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41141.1Skamil
41151.1Skamil	validate_status_exited(status, exitval);
41161.1Skamil
41171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41191.1Skamil}
41201.1Skamil#endif
41211.1Skamil
41221.1Skamil#if defined(HAVE_GPREGS)
41231.1SkamilATF_TC(regs3);
41241.1SkamilATF_TC_HEAD(regs3, tc)
41251.1Skamil{
41261.1Skamil	atf_tc_set_md_var(tc, "descr",
41271.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
41281.1Skamil}
41291.1Skamil
41301.1SkamilATF_TC_BODY(regs3, tc)
41311.1Skamil{
41321.1Skamil	const int exitval = 5;
41331.1Skamil	const int sigval = SIGSTOP;
41341.1Skamil	pid_t child, wpid;
41351.1Skamil#if defined(TWAIT_HAVE_STATUS)
41361.1Skamil	int status;
41371.1Skamil#endif
41381.1Skamil	struct reg r;
41391.1Skamil
41401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41421.1Skamil	if (child == 0) {
41431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41451.1Skamil
41461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41481.1Skamil
41491.13Schristos		DPRINTF("Before exiting of the child process\n");
41501.1Skamil		_exit(exitval);
41511.1Skamil	}
41521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41531.1Skamil
41541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41561.1Skamil
41571.1Skamil	validate_status_stopped(status, sigval);
41581.1Skamil
41591.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41611.1Skamil
41621.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
41631.1Skamil
41641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41651.1Skamil	    "without signal to be sent\n");
41661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41671.1Skamil
41681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41701.1Skamil
41711.1Skamil	validate_status_exited(status, exitval);
41721.1Skamil
41731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41751.1Skamil}
41761.1Skamil#endif
41771.1Skamil
41781.1Skamil#if defined(HAVE_GPREGS)
41791.1SkamilATF_TC(regs4);
41801.1SkamilATF_TC_HEAD(regs4, tc)
41811.1Skamil{
41821.1Skamil	atf_tc_set_md_var(tc, "descr",
41831.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
41841.1Skamil}
41851.1Skamil
41861.1SkamilATF_TC_BODY(regs4, tc)
41871.1Skamil{
41881.1Skamil	const int exitval = 5;
41891.1Skamil	const int sigval = SIGSTOP;
41901.1Skamil	pid_t child, wpid;
41911.1Skamil#if defined(TWAIT_HAVE_STATUS)
41921.1Skamil	int status;
41931.1Skamil#endif
41941.1Skamil	struct reg r;
41951.1Skamil
41961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41981.1Skamil	if (child == 0) {
41991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42011.1Skamil
42021.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42031.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42041.1Skamil
42051.13Schristos		DPRINTF("Before exiting of the child process\n");
42061.1Skamil		_exit(exitval);
42071.1Skamil	}
42081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42091.1Skamil
42101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42121.1Skamil
42131.1Skamil	validate_status_stopped(status, sigval);
42141.1Skamil
42151.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42171.1Skamil
42181.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
42191.1Skamil
42201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42211.1Skamil	    "without signal to be sent\n");
42221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42231.1Skamil
42241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42261.1Skamil
42271.1Skamil	validate_status_exited(status, exitval);
42281.1Skamil
42291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42311.1Skamil}
42321.1Skamil#endif
42331.1Skamil
42341.1Skamil#if defined(HAVE_GPREGS)
42351.1SkamilATF_TC(regs5);
42361.1SkamilATF_TC_HEAD(regs5, tc)
42371.1Skamil{
42381.1Skamil	atf_tc_set_md_var(tc, "descr",
42391.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
42401.1Skamil}
42411.1Skamil
42421.1SkamilATF_TC_BODY(regs5, tc)
42431.1Skamil{
42441.1Skamil	const int exitval = 5;
42451.1Skamil	const int sigval = SIGSTOP;
42461.1Skamil	pid_t child, wpid;
42471.1Skamil#if defined(TWAIT_HAVE_STATUS)
42481.1Skamil	int status;
42491.1Skamil#endif
42501.1Skamil	struct reg r;
42511.1Skamil
42521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42541.1Skamil	if (child == 0) {
42551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42571.1Skamil
42581.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42591.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42601.1Skamil
42611.13Schristos		DPRINTF("Before exiting of the child process\n");
42621.1Skamil		_exit(exitval);
42631.1Skamil	}
42641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42651.1Skamil
42661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42681.1Skamil
42691.1Skamil	validate_status_stopped(status, sigval);
42701.1Skamil
42711.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42731.1Skamil
42741.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
42751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42761.1Skamil
42771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42781.1Skamil	    "without signal to be sent\n");
42791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42801.1Skamil
42811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42831.1Skamil
42841.1Skamil	validate_status_exited(status, exitval);
42851.1Skamil
42861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42881.1Skamil}
42891.1Skamil#endif
42901.1Skamil
42911.1Skamil#if defined(HAVE_FPREGS)
42921.1SkamilATF_TC(fpregs1);
42931.1SkamilATF_TC_HEAD(fpregs1, tc)
42941.1Skamil{
42951.1Skamil	atf_tc_set_md_var(tc, "descr",
42961.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
42971.1Skamil}
42981.1Skamil
42991.1SkamilATF_TC_BODY(fpregs1, tc)
43001.1Skamil{
43011.1Skamil	const int exitval = 5;
43021.1Skamil	const int sigval = SIGSTOP;
43031.1Skamil	pid_t child, wpid;
43041.1Skamil#if defined(TWAIT_HAVE_STATUS)
43051.1Skamil	int status;
43061.1Skamil#endif
43071.1Skamil	struct fpreg r;
43081.1Skamil
43091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43111.1Skamil	if (child == 0) {
43121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43141.1Skamil
43151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43171.1Skamil
43181.13Schristos		DPRINTF("Before exiting of the child process\n");
43191.1Skamil		_exit(exitval);
43201.1Skamil	}
43211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43221.1Skamil
43231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43251.1Skamil
43261.1Skamil	validate_status_stopped(status, sigval);
43271.1Skamil
43281.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43301.1Skamil
43311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43321.1Skamil	    "without signal to be sent\n");
43331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43341.1Skamil
43351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43371.1Skamil
43381.1Skamil	validate_status_exited(status, exitval);
43391.1Skamil
43401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43421.1Skamil}
43431.1Skamil#endif
43441.1Skamil
43451.1Skamil#if defined(HAVE_FPREGS)
43461.1SkamilATF_TC(fpregs2);
43471.1SkamilATF_TC_HEAD(fpregs2, tc)
43481.1Skamil{
43491.1Skamil	atf_tc_set_md_var(tc, "descr",
43501.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
43511.1Skamil	    "regs");
43521.1Skamil}
43531.1Skamil
43541.1SkamilATF_TC_BODY(fpregs2, tc)
43551.1Skamil{
43561.1Skamil	const int exitval = 5;
43571.1Skamil	const int sigval = SIGSTOP;
43581.1Skamil	pid_t child, wpid;
43591.1Skamil#if defined(TWAIT_HAVE_STATUS)
43601.1Skamil	int status;
43611.1Skamil#endif
43621.1Skamil	struct fpreg r;
43631.1Skamil
43641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43661.1Skamil	if (child == 0) {
43671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43691.1Skamil
43701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43721.1Skamil
43731.13Schristos		DPRINTF("Before exiting of the child process\n");
43741.1Skamil		_exit(exitval);
43751.1Skamil	}
43761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43771.1Skamil
43781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43801.1Skamil
43811.1Skamil	validate_status_stopped(status, sigval);
43821.1Skamil
43831.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43851.1Skamil
43861.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
43871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
43881.1Skamil
43891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43901.1Skamil	    "without signal to be sent\n");
43911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43921.1Skamil
43931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43951.1Skamil
43961.1Skamil	validate_status_exited(status, exitval);
43971.1Skamil
43981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44001.1Skamil}
44011.1Skamil#endif
44021.1Skamil
44031.1Skamil#if defined(PT_STEP)
44041.1Skamilstatic void
44051.2Skamilptrace_step(int N, int setstep)
44061.1Skamil{
44071.1Skamil	const int exitval = 5;
44081.1Skamil	const int sigval = SIGSTOP;
44091.1Skamil	pid_t child, wpid;
44101.1Skamil#if defined(TWAIT_HAVE_STATUS)
44111.1Skamil	int status;
44121.1Skamil#endif
44131.1Skamil	int happy;
44141.1Skamil
44151.1Skamil#if defined(__arm__)
44161.1Skamil	/* PT_STEP not supported on arm 32-bit */
44171.1Skamil	atf_tc_expect_fail("PR kern/52119");
44181.1Skamil#endif
44191.1Skamil
44201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44221.1Skamil	if (child == 0) {
44231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44251.1Skamil
44261.1Skamil		happy = check_happy(999);
44271.1Skamil
44281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44301.1Skamil
44311.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
44321.1Skamil
44331.13Schristos		DPRINTF("Before exiting of the child process\n");
44341.1Skamil		_exit(exitval);
44351.1Skamil	}
44361.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44371.1Skamil
44381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44401.1Skamil
44411.1Skamil	validate_status_stopped(status, sigval);
44421.1Skamil
44431.1Skamil	while (N --> 0) {
44441.2Skamil		if (setstep) {
44451.13Schristos			DPRINTF("Before resuming the child process where it "
44461.2Skamil			    "left off and without signal to be sent (use "
44471.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
44481.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
44491.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
44501.2Skamil			    != -1);
44511.2Skamil		} else {
44521.13Schristos			DPRINTF("Before resuming the child process where it "
44531.2Skamil			    "left off and without signal to be sent (use "
44541.2Skamil			    "PT_STEP)\n");
44551.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
44561.2Skamil			    != -1);
44571.2Skamil		}
44581.1Skamil
44591.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44601.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
44611.1Skamil		    child);
44621.1Skamil
44631.1Skamil		validate_status_stopped(status, SIGTRAP);
44641.2Skamil
44651.2Skamil		if (setstep) {
44661.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
44671.2Skamil		}
44681.1Skamil	}
44691.1Skamil
44701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44711.1Skamil	    "without signal to be sent\n");
44721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44731.1Skamil
44741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44761.1Skamil
44771.1Skamil	validate_status_exited(status, exitval);
44781.1Skamil
44791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44811.1Skamil}
44821.1Skamil#endif
44831.1Skamil
44841.1Skamil#if defined(PT_STEP)
44851.1SkamilATF_TC(step1);
44861.1SkamilATF_TC_HEAD(step1, tc)
44871.1Skamil{
44881.1Skamil	atf_tc_set_md_var(tc, "descr",
44891.1Skamil	    "Verify single PT_STEP call");
44901.1Skamil}
44911.1Skamil
44921.1SkamilATF_TC_BODY(step1, tc)
44931.1Skamil{
44941.2Skamil	ptrace_step(1, 0);
44951.1Skamil}
44961.1Skamil#endif
44971.1Skamil
44981.1Skamil#if defined(PT_STEP)
44991.1SkamilATF_TC(step2);
45001.1SkamilATF_TC_HEAD(step2, tc)
45011.1Skamil{
45021.1Skamil	atf_tc_set_md_var(tc, "descr",
45031.1Skamil	    "Verify PT_STEP called twice");
45041.1Skamil}
45051.1Skamil
45061.1SkamilATF_TC_BODY(step2, tc)
45071.1Skamil{
45081.2Skamil	ptrace_step(2, 0);
45091.1Skamil}
45101.1Skamil#endif
45111.1Skamil
45121.1Skamil#if defined(PT_STEP)
45131.1SkamilATF_TC(step3);
45141.1SkamilATF_TC_HEAD(step3, tc)
45151.1Skamil{
45161.1Skamil	atf_tc_set_md_var(tc, "descr",
45171.1Skamil	    "Verify PT_STEP called three times");
45181.1Skamil}
45191.1Skamil
45201.1SkamilATF_TC_BODY(step3, tc)
45211.1Skamil{
45221.2Skamil	ptrace_step(3, 0);
45231.1Skamil}
45241.1Skamil#endif
45251.1Skamil
45261.1Skamil#if defined(PT_STEP)
45271.1SkamilATF_TC(step4);
45281.1SkamilATF_TC_HEAD(step4, tc)
45291.1Skamil{
45301.1Skamil	atf_tc_set_md_var(tc, "descr",
45311.1Skamil	    "Verify PT_STEP called four times");
45321.1Skamil}
45331.1Skamil
45341.1SkamilATF_TC_BODY(step4, tc)
45351.1Skamil{
45361.2Skamil	ptrace_step(4, 0);
45371.2Skamil}
45381.2Skamil#endif
45391.2Skamil
45401.2Skamil#if defined(PT_STEP)
45411.2SkamilATF_TC(setstep1);
45421.2SkamilATF_TC_HEAD(setstep1, tc)
45431.2Skamil{
45441.2Skamil	atf_tc_set_md_var(tc, "descr",
45451.2Skamil	    "Verify single PT_SETSTEP call");
45461.2Skamil}
45471.2Skamil
45481.2SkamilATF_TC_BODY(setstep1, tc)
45491.2Skamil{
45501.2Skamil	ptrace_step(1, 1);
45511.2Skamil}
45521.2Skamil#endif
45531.2Skamil
45541.2Skamil#if defined(PT_STEP)
45551.2SkamilATF_TC(setstep2);
45561.2SkamilATF_TC_HEAD(setstep2, tc)
45571.2Skamil{
45581.2Skamil	atf_tc_set_md_var(tc, "descr",
45591.2Skamil	    "Verify PT_SETSTEP called twice");
45601.2Skamil}
45611.2Skamil
45621.2SkamilATF_TC_BODY(setstep2, tc)
45631.2Skamil{
45641.2Skamil	ptrace_step(2, 1);
45651.2Skamil}
45661.2Skamil#endif
45671.2Skamil
45681.2Skamil#if defined(PT_STEP)
45691.2SkamilATF_TC(setstep3);
45701.2SkamilATF_TC_HEAD(setstep3, tc)
45711.2Skamil{
45721.2Skamil	atf_tc_set_md_var(tc, "descr",
45731.2Skamil	    "Verify PT_SETSTEP called three times");
45741.2Skamil}
45751.2Skamil
45761.2SkamilATF_TC_BODY(setstep3, tc)
45771.2Skamil{
45781.2Skamil	ptrace_step(3, 1);
45791.2Skamil}
45801.2Skamil#endif
45811.2Skamil
45821.2Skamil#if defined(PT_STEP)
45831.2SkamilATF_TC(setstep4);
45841.2SkamilATF_TC_HEAD(setstep4, tc)
45851.2Skamil{
45861.2Skamil	atf_tc_set_md_var(tc, "descr",
45871.2Skamil	    "Verify PT_SETSTEP called four times");
45881.2Skamil}
45891.2Skamil
45901.2SkamilATF_TC_BODY(setstep4, tc)
45911.2Skamil{
45921.2Skamil	ptrace_step(4, 1);
45931.1Skamil}
45941.1Skamil#endif
45951.1Skamil
45961.1SkamilATF_TC(kill1);
45971.1SkamilATF_TC_HEAD(kill1, tc)
45981.1Skamil{
45991.1Skamil	atf_tc_set_md_var(tc, "descr",
46001.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
46011.1Skamil}
46021.1Skamil
46031.1SkamilATF_TC_BODY(kill1, tc)
46041.1Skamil{
46051.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
46061.1Skamil	pid_t child, wpid;
46071.1Skamil#if defined(TWAIT_HAVE_STATUS)
46081.1Skamil	int status;
46091.1Skamil#endif
46101.1Skamil
46111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46131.1Skamil	if (child == 0) {
46141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46161.1Skamil
46171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46191.1Skamil
46201.1Skamil		/* NOTREACHED */
46211.1Skamil		FORKEE_ASSERTX(0 &&
46221.1Skamil		    "Child should be terminated by a signal from its parent");
46231.1Skamil	}
46241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46251.1Skamil
46261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46281.1Skamil
46291.1Skamil	validate_status_stopped(status, sigval);
46301.1Skamil
46311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46321.1Skamil	    "without signal to be sent\n");
46331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
46341.1Skamil
46351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46371.1Skamil
46381.1Skamil	validate_status_signaled(status, sigsent, 0);
46391.1Skamil
46401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46421.1Skamil}
46431.1Skamil
46441.1SkamilATF_TC(kill2);
46451.1SkamilATF_TC_HEAD(kill2, tc)
46461.1Skamil{
46471.1Skamil	atf_tc_set_md_var(tc, "descr",
46481.1Skamil	    "Verify that PT_KILL terminates child");
46491.1Skamil}
46501.1Skamil
46511.1SkamilATF_TC_BODY(kill2, tc)
46521.1Skamil{
46531.1Skamil	const int sigval = SIGSTOP;
46541.1Skamil	pid_t child, wpid;
46551.1Skamil#if defined(TWAIT_HAVE_STATUS)
46561.1Skamil	int status;
46571.1Skamil#endif
46581.1Skamil
46591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46611.1Skamil	if (child == 0) {
46621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46641.1Skamil
46651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46671.1Skamil
46681.1Skamil		/* NOTREACHED */
46691.1Skamil		FORKEE_ASSERTX(0 &&
46701.1Skamil		    "Child should be terminated by a signal from its parent");
46711.1Skamil	}
46721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46731.1Skamil
46741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46761.1Skamil
46771.1Skamil	validate_status_stopped(status, sigval);
46781.1Skamil
46791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46801.1Skamil	    "without signal to be sent\n");
46811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
46821.1Skamil
46831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46851.1Skamil
46861.1Skamil	validate_status_signaled(status, SIGKILL, 0);
46871.1Skamil
46881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46891.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46901.1Skamil}
46911.1Skamil
46921.1SkamilATF_TC(lwpinfo1);
46931.1SkamilATF_TC_HEAD(lwpinfo1, tc)
46941.1Skamil{
46951.1Skamil	atf_tc_set_md_var(tc, "descr",
46961.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
46971.1Skamil}
46981.1Skamil
46991.1SkamilATF_TC_BODY(lwpinfo1, tc)
47001.1Skamil{
47011.1Skamil	const int exitval = 5;
47021.1Skamil	const int sigval = SIGSTOP;
47031.1Skamil	pid_t child, wpid;
47041.1Skamil#if defined(TWAIT_HAVE_STATUS)
47051.1Skamil	int status;
47061.1Skamil#endif
47071.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47081.1Skamil
47091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47111.1Skamil	if (child == 0) {
47121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47141.1Skamil
47151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47171.1Skamil
47181.13Schristos		DPRINTF("Before exiting of the child process\n");
47191.1Skamil		_exit(exitval);
47201.1Skamil	}
47211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47221.1Skamil
47231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47251.1Skamil
47261.1Skamil	validate_status_stopped(status, sigval);
47271.1Skamil
47281.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47301.1Skamil
47311.13Schristos	DPRINTF("Assert that there exists a thread\n");
47321.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
47331.1Skamil
47341.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
47351.1Skamil	    info.pl_lwpid);
47361.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
47371.1Skamil	    "Received event %d != expected event %d",
47381.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
47391.1Skamil
47401.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47421.1Skamil
47431.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
47441.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
47451.1Skamil
47461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47471.1Skamil	    "without signal to be sent\n");
47481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47491.1Skamil
47501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47521.1Skamil
47531.1Skamil	validate_status_exited(status, exitval);
47541.1Skamil
47551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47561.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47571.1Skamil}
47581.1Skamil
47591.1Skamil#if defined(TWAIT_HAVE_PID)
47601.1SkamilATF_TC(lwpinfo2);
47611.1SkamilATF_TC_HEAD(lwpinfo2, tc)
47621.1Skamil{
47631.1Skamil	atf_tc_set_md_var(tc, "descr",
47641.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
47651.1Skamil	    "tracer)");
47661.1Skamil}
47671.1Skamil
47681.1SkamilATF_TC_BODY(lwpinfo2, tc)
47691.1Skamil{
47701.1Skamil	struct msg_fds parent_tracee, parent_tracer;
47711.1Skamil	const int exitval_tracee = 5;
47721.1Skamil	const int exitval_tracer = 10;
47731.1Skamil	pid_t tracee, tracer, wpid;
47741.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
47751.1Skamil#if defined(TWAIT_HAVE_STATUS)
47761.1Skamil	int status;
47771.1Skamil#endif
47781.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47791.1Skamil
47801.13Schristos	DPRINTF("Spawn tracee\n");
47811.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
47821.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
47831.1Skamil	tracee = atf_utils_fork();
47841.1Skamil	if (tracee == 0) {
47851.1Skamil
47861.1Skamil		/* Wait for message from the parent */
47871.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
47881.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
47891.1Skamil
47901.1Skamil		_exit(exitval_tracee);
47911.1Skamil	}
47921.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
47931.1Skamil
47941.13Schristos	DPRINTF("Spawn debugger\n");
47951.1Skamil	tracer = atf_utils_fork();
47961.1Skamil	if (tracer == 0) {
47971.1Skamil		/* No IPC to communicate with the child */
47981.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
47991.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
48001.1Skamil
48011.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
48021.1Skamil		FORKEE_REQUIRE_SUCCESS(
48031.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48041.1Skamil
48051.1Skamil		forkee_status_stopped(status, SIGSTOP);
48061.1Skamil
48071.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48081.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48091.1Skamil		    != -1);
48101.1Skamil
48111.13Schristos		DPRINTF("Assert that there exists a thread\n");
48121.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
48131.1Skamil
48141.13Schristos		DPRINTF("Assert that lwp thread %d received event "
48151.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
48161.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
48171.1Skamil
48181.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48191.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48201.1Skamil		    != -1);
48211.1Skamil
48221.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
48231.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
48241.1Skamil
48251.1Skamil		/* Resume tracee with PT_CONTINUE */
48261.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
48271.1Skamil
48281.1Skamil		/* Inform parent that tracer has attached to tracee */
48291.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
48301.1Skamil		/* Wait for parent */
48311.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
48321.1Skamil
48331.1Skamil		/* Wait for tracee and assert that it exited */
48341.1Skamil		FORKEE_REQUIRE_SUCCESS(
48351.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48361.1Skamil
48371.1Skamil		forkee_status_exited(status, exitval_tracee);
48381.1Skamil
48391.13Schristos		DPRINTF("Before exiting of the tracer process\n");
48401.1Skamil		_exit(exitval_tracer);
48411.1Skamil	}
48421.1Skamil
48431.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
48441.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
48451.1Skamil
48461.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
48471.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
48481.1Skamil
48491.13Schristos	DPRINTF("Detect that tracee is zombie\n");
48501.1Skamil	await_zombie(tracee);
48511.1Skamil
48521.13Schristos	DPRINTF("Assert that there is no status about tracee - "
48531.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
48541.1Skamil	TWAIT_REQUIRE_SUCCESS(
48551.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
48561.1Skamil
48571.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
48581.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
48591.1Skamil
48601.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
48611.1Skamil	    TWAIT_FNAME);
48621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
48631.1Skamil	    tracer);
48641.1Skamil
48651.1Skamil	validate_status_exited(status, exitval_tracer);
48661.1Skamil
48671.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
48681.1Skamil	    TWAIT_FNAME);
48691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
48701.1Skamil	    tracee);
48711.1Skamil
48721.1Skamil	validate_status_exited(status, exitval_tracee);
48731.1Skamil
48741.1Skamil	msg_close(&parent_tracer);
48751.1Skamil	msg_close(&parent_tracee);
48761.1Skamil}
48771.1Skamil#endif
48781.1Skamil
48791.1SkamilATF_TC(siginfo1);
48801.1SkamilATF_TC_HEAD(siginfo1, tc)
48811.1Skamil{
48821.1Skamil	atf_tc_set_md_var(tc, "descr",
48831.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
48841.1Skamil}
48851.1Skamil
48861.1SkamilATF_TC_BODY(siginfo1, tc)
48871.1Skamil{
48881.1Skamil	const int exitval = 5;
48891.1Skamil	const int sigval = SIGTRAP;
48901.1Skamil	pid_t child, wpid;
48911.1Skamil#if defined(TWAIT_HAVE_STATUS)
48921.1Skamil	int status;
48931.1Skamil#endif
48941.1Skamil	struct ptrace_siginfo info;
48951.1Skamil	memset(&info, 0, sizeof(info));
48961.1Skamil
48971.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48981.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48991.1Skamil	if (child == 0) {
49001.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49011.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49021.1Skamil
49031.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49041.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49051.1Skamil
49061.13Schristos		DPRINTF("Before exiting of the child process\n");
49071.1Skamil		_exit(exitval);
49081.1Skamil	}
49091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49101.1Skamil
49111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49131.1Skamil
49141.1Skamil	validate_status_stopped(status, sigval);
49151.1Skamil
49161.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49181.1Skamil
49191.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49201.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49211.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49221.1Skamil	    info.psi_siginfo.si_errno);
49231.1Skamil
49241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49251.1Skamil	    "without signal to be sent\n");
49261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49271.1Skamil
49281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49301.1Skamil
49311.1Skamil	validate_status_exited(status, exitval);
49321.1Skamil
49331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49351.1Skamil}
49361.1Skamil
49371.1SkamilATF_TC(siginfo2);
49381.1SkamilATF_TC_HEAD(siginfo2, tc)
49391.1Skamil{
49401.1Skamil	atf_tc_set_md_var(tc, "descr",
49411.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
49421.1Skamil	    "modification of SIGINT from tracee");
49431.1Skamil}
49441.1Skamil
49451.1Skamilstatic int siginfo2_caught = 0;
49461.1Skamil
49471.1Skamilstatic void
49481.1Skamilsiginfo2_sighandler(int sig)
49491.1Skamil{
49501.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
49511.1Skamil
49521.1Skamil	++siginfo2_caught;
49531.1Skamil}
49541.1Skamil
49551.1SkamilATF_TC_BODY(siginfo2, tc)
49561.1Skamil{
49571.1Skamil	const int exitval = 5;
49581.1Skamil	const int sigval = SIGINT;
49591.1Skamil	pid_t child, wpid;
49601.1Skamil	struct sigaction sa;
49611.1Skamil#if defined(TWAIT_HAVE_STATUS)
49621.1Skamil	int status;
49631.1Skamil#endif
49641.1Skamil	struct ptrace_siginfo info;
49651.1Skamil	memset(&info, 0, sizeof(info));
49661.1Skamil
49671.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49681.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49691.1Skamil	if (child == 0) {
49701.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49711.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49721.1Skamil
49731.1Skamil		sa.sa_handler = siginfo2_sighandler;
49741.1Skamil		sa.sa_flags = SA_SIGINFO;
49751.1Skamil		sigemptyset(&sa.sa_mask);
49761.1Skamil
49771.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
49781.1Skamil
49791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49811.1Skamil
49821.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
49831.1Skamil
49841.13Schristos		DPRINTF("Before exiting of the child process\n");
49851.1Skamil		_exit(exitval);
49861.1Skamil	}
49871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49881.1Skamil
49891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49911.1Skamil
49921.1Skamil	validate_status_stopped(status, sigval);
49931.1Skamil
49941.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49961.1Skamil
49971.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49981.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49991.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50001.1Skamil	    info.psi_siginfo.si_errno);
50011.1Skamil
50021.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50041.1Skamil
50051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50061.1Skamil	    "without signal to be sent\n");
50071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
50081.1Skamil
50091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50111.1Skamil
50121.1Skamil	validate_status_exited(status, exitval);
50131.1Skamil
50141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50161.1Skamil}
50171.1Skamil
50181.1SkamilATF_TC(siginfo3);
50191.1SkamilATF_TC_HEAD(siginfo3, tc)
50201.1Skamil{
50211.1Skamil	atf_tc_set_md_var(tc, "descr",
50221.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
50231.1Skamil	    "setting signal to new value");
50241.1Skamil}
50251.1Skamil
50261.1Skamilstatic int siginfo3_caught = 0;
50271.1Skamil
50281.1Skamilstatic void
50291.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
50301.1Skamil{
50311.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
50321.1Skamil
50331.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
50341.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
50351.1Skamil
50361.1Skamil	++siginfo3_caught;
50371.1Skamil}
50381.1Skamil
50391.1SkamilATF_TC_BODY(siginfo3, tc)
50401.1Skamil{
50411.1Skamil	const int exitval = 5;
50421.1Skamil	const int sigval = SIGINT;
50431.1Skamil	const int sigfaked = SIGTRAP;
50441.1Skamil	const int sicodefaked = TRAP_BRKPT;
50451.1Skamil	pid_t child, wpid;
50461.1Skamil	struct sigaction sa;
50471.1Skamil#if defined(TWAIT_HAVE_STATUS)
50481.1Skamil	int status;
50491.1Skamil#endif
50501.1Skamil	struct ptrace_siginfo info;
50511.1Skamil	memset(&info, 0, sizeof(info));
50521.1Skamil
50531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50551.1Skamil	if (child == 0) {
50561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50581.1Skamil
50591.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
50601.1Skamil		sa.sa_flags = SA_SIGINFO;
50611.1Skamil		sigemptyset(&sa.sa_mask);
50621.1Skamil
50631.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
50641.1Skamil
50651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50671.1Skamil
50681.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
50691.1Skamil
50701.13Schristos		DPRINTF("Before exiting of the child process\n");
50711.1Skamil		_exit(exitval);
50721.1Skamil	}
50731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50741.1Skamil
50751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50771.1Skamil
50781.1Skamil	validate_status_stopped(status, sigval);
50791.1Skamil
50801.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50821.1Skamil
50831.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50841.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50851.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50861.1Skamil	    info.psi_siginfo.si_errno);
50871.1Skamil
50881.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
50891.1Skamil	    sigfaked, sicodefaked);
50901.1Skamil	info.psi_siginfo.si_signo = sigfaked;
50911.1Skamil	info.psi_siginfo.si_code = sicodefaked;
50921.1Skamil
50931.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50951.1Skamil
50961.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50981.1Skamil
50991.13Schristos	DPRINTF("Before checking siginfo_t\n");
51001.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
51011.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
51021.1Skamil
51031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51041.1Skamil	    "without signal to be sent\n");
51051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
51061.1Skamil
51071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51091.1Skamil
51101.1Skamil	validate_status_exited(status, exitval);
51111.1Skamil
51121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51141.1Skamil}
51151.1Skamil
51161.1SkamilATF_TC(siginfo4);
51171.1SkamilATF_TC_HEAD(siginfo4, tc)
51181.1Skamil{
51191.1Skamil	atf_tc_set_md_var(tc, "descr",
51201.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
51211.1Skamil}
51221.1Skamil
51231.1SkamilATF_TC_BODY(siginfo4, tc)
51241.1Skamil{
51251.1Skamil	const int sigval = SIGTRAP;
51261.1Skamil	pid_t child, wpid;
51271.1Skamil#if defined(TWAIT_HAVE_STATUS)
51281.1Skamil	int status;
51291.1Skamil#endif
51301.1Skamil
51311.1Skamil	struct ptrace_siginfo info;
51321.1Skamil	memset(&info, 0, sizeof(info));
51331.1Skamil
51341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51361.1Skamil	if (child == 0) {
51371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51391.1Skamil
51401.13Schristos		DPRINTF("Before calling execve(2) from child\n");
51411.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
51421.1Skamil
51431.1Skamil		FORKEE_ASSERT(0 && "Not reached");
51441.1Skamil	}
51451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51461.1Skamil
51471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51491.1Skamil
51501.1Skamil	validate_status_stopped(status, sigval);
51511.1Skamil
51521.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51541.1Skamil
51551.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51561.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51571.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51581.1Skamil	    info.psi_siginfo.si_errno);
51591.1Skamil
51601.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51611.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
51621.1Skamil
51631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51641.1Skamil	    "without signal to be sent\n");
51651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51661.1Skamil
51671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51691.1Skamil
51701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51721.1Skamil}
51731.1Skamil
51741.1Skamil#if defined(TWAIT_HAVE_PID)
51751.1SkamilATF_TC(siginfo5);
51761.1SkamilATF_TC_HEAD(siginfo5, tc)
51771.1Skamil{
51781.1Skamil	atf_tc_set_md_var(tc, "descr",
51791.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
51801.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
51811.1Skamil}
51821.1Skamil
51831.1SkamilATF_TC_BODY(siginfo5, tc)
51841.1Skamil{
51851.1Skamil	const int exitval = 5;
51861.1Skamil	const int exitval2 = 15;
51871.1Skamil	const int sigval = SIGSTOP;
51881.1Skamil	pid_t child, child2, wpid;
51891.1Skamil#if defined(TWAIT_HAVE_STATUS)
51901.1Skamil	int status;
51911.1Skamil#endif
51921.1Skamil	ptrace_state_t state;
51931.1Skamil	const int slen = sizeof(state);
51941.1Skamil	ptrace_event_t event;
51951.1Skamil	const int elen = sizeof(event);
51961.1Skamil	struct ptrace_siginfo info;
51971.1Skamil
51981.1Skamil	memset(&info, 0, sizeof(info));
51991.1Skamil
52001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52021.1Skamil	if (child == 0) {
52031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52051.1Skamil
52061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52081.1Skamil
52091.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
52101.1Skamil
52111.1Skamil		if (child2 == 0)
52121.1Skamil			_exit(exitval2);
52131.1Skamil
52141.1Skamil		FORKEE_REQUIRE_SUCCESS
52151.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
52161.1Skamil
52171.1Skamil		forkee_status_exited(status, exitval2);
52181.1Skamil
52191.13Schristos		DPRINTF("Before exiting of the child process\n");
52201.1Skamil		_exit(exitval);
52211.1Skamil	}
52221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52231.1Skamil
52241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52261.1Skamil
52271.1Skamil	validate_status_stopped(status, sigval);
52281.1Skamil
52291.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52311.1Skamil
52321.13Schristos	DPRINTF("Before checking siginfo_t\n");
52331.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
52341.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
52351.1Skamil
52361.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
52371.1Skamil	event.pe_set_event = PTRACE_FORK;
52381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52391.1Skamil
52401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52411.1Skamil	    "without signal to be sent\n");
52421.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
52431.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
52441.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
52451.1Skamil                "state.pe_other_pid=child)\n", child);
52461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52471.1Skamil
52481.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
52491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52501.1Skamil
52511.1Skamil	validate_status_stopped(status, SIGTRAP);
52521.1Skamil
52531.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52551.1Skamil
52561.13Schristos	DPRINTF("Before checking siginfo_t\n");
52571.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52581.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52591.1Skamil
52601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52611.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52621.1Skamil
52631.1Skamil	child2 = state.pe_other_pid;
52641.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
52651.1Skamil
52661.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
52671.1Skamil	    TWAIT_FNAME, child2, child);
52681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52691.1Skamil	    child2);
52701.1Skamil
52711.1Skamil	validate_status_stopped(status, SIGTRAP);
52721.1Skamil
52731.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52751.1Skamil
52761.13Schristos	DPRINTF("Before checking siginfo_t\n");
52771.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52781.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52791.1Skamil
52801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
52811.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52821.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
52831.1Skamil
52841.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
52851.1Skamil	    "without signal to be sent\n");
52861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
52871.1Skamil
52881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52891.1Skamil	    "without signal to be sent\n");
52901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52911.1Skamil
52921.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
52931.1Skamil	    TWAIT_FNAME);
52941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52951.1Skamil	    child2);
52961.1Skamil
52971.1Skamil	validate_status_exited(status, exitval2);
52981.1Skamil
52991.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
53001.1Skamil	    TWAIT_FNAME);
53011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
53021.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
53031.1Skamil
53041.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53051.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
53061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53071.1Skamil
53081.1Skamil	validate_status_stopped(status, SIGCHLD);
53091.1Skamil
53101.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53121.1Skamil
53131.13Schristos	DPRINTF("Before checking siginfo_t\n");
53141.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
53151.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
53161.1Skamil
53171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53181.1Skamil	    "without signal to be sent\n");
53191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53201.1Skamil
53211.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53221.1Skamil	    TWAIT_FNAME);
53231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53241.1Skamil
53251.1Skamil	validate_status_exited(status, exitval);
53261.1Skamil
53271.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53281.1Skamil	    TWAIT_FNAME);
53291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53301.1Skamil}
53311.1Skamil#endif
53321.1Skamil
53331.1Skamil#if defined(PT_STEP)
53341.1SkamilATF_TC(siginfo6);
53351.1SkamilATF_TC_HEAD(siginfo6, tc)
53361.1Skamil{
53371.1Skamil	atf_tc_set_md_var(tc, "descr",
53381.1Skamil	    "Verify single PT_STEP call with signal information check");
53391.1Skamil}
53401.1Skamil
53411.1SkamilATF_TC_BODY(siginfo6, tc)
53421.1Skamil{
53431.1Skamil	const int exitval = 5;
53441.1Skamil	const int sigval = SIGSTOP;
53451.1Skamil	pid_t child, wpid;
53461.1Skamil#if defined(TWAIT_HAVE_STATUS)
53471.1Skamil	int status;
53481.1Skamil#endif
53491.1Skamil	int happy;
53501.1Skamil	struct ptrace_siginfo info;
53511.1Skamil
53521.1Skamil#if defined(__arm__)
53531.1Skamil	/* PT_STEP not supported on arm 32-bit */
53541.1Skamil	atf_tc_expect_fail("PR kern/52119");
53551.1Skamil#endif
53561.1Skamil
53571.1Skamil	memset(&info, 0, sizeof(info));
53581.1Skamil
53591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53611.1Skamil	if (child == 0) {
53621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53641.1Skamil
53651.1Skamil		happy = check_happy(100);
53661.1Skamil
53671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53691.1Skamil
53701.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
53711.1Skamil
53721.13Schristos		DPRINTF("Before exiting of the child process\n");
53731.1Skamil		_exit(exitval);
53741.1Skamil	}
53751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53761.1Skamil
53771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53791.1Skamil
53801.1Skamil	validate_status_stopped(status, sigval);
53811.1Skamil
53821.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53841.1Skamil
53851.13Schristos	DPRINTF("Before checking siginfo_t\n");
53861.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
53871.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
53881.1Skamil
53891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53901.1Skamil	    "without signal to be sent (use PT_STEP)\n");
53911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
53921.1Skamil
53931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53951.1Skamil
53961.1Skamil	validate_status_stopped(status, SIGTRAP);
53971.1Skamil
53981.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
54001.1Skamil
54011.13Schristos	DPRINTF("Before checking siginfo_t\n");
54021.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
54031.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
54041.1Skamil
54051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54061.1Skamil	    "without signal to be sent\n");
54071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54081.1Skamil
54091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54111.1Skamil
54121.1Skamil	validate_status_exited(status, exitval);
54131.1Skamil
54141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54161.1Skamil}
54171.1Skamil#endif
54181.1Skamil
54191.1Skamilvolatile lwpid_t the_lwp_id = 0;
54201.1Skamil
54211.1Skamilstatic void
54221.1Skamillwp_main_func(void *arg)
54231.1Skamil{
54241.1Skamil	the_lwp_id = _lwp_self();
54251.1Skamil	_lwp_exit();
54261.1Skamil}
54271.1Skamil
54281.1SkamilATF_TC(lwp_create1);
54291.1SkamilATF_TC_HEAD(lwp_create1, tc)
54301.1Skamil{
54311.1Skamil	atf_tc_set_md_var(tc, "descr",
54321.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
54331.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
54341.1Skamil}
54351.1Skamil
54361.1SkamilATF_TC_BODY(lwp_create1, tc)
54371.1Skamil{
54381.1Skamil	const int exitval = 5;
54391.1Skamil	const int sigval = SIGSTOP;
54401.1Skamil	pid_t child, wpid;
54411.1Skamil#if defined(TWAIT_HAVE_STATUS)
54421.1Skamil	int status;
54431.1Skamil#endif
54441.1Skamil	ptrace_state_t state;
54451.1Skamil	const int slen = sizeof(state);
54461.1Skamil	ptrace_event_t event;
54471.1Skamil	const int elen = sizeof(event);
54481.1Skamil	ucontext_t uc;
54491.1Skamil	lwpid_t lid;
54501.1Skamil	static const size_t ssize = 16*1024;
54511.1Skamil	void *stack;
54521.1Skamil
54531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54551.1Skamil	if (child == 0) {
54561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54581.1Skamil
54591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54611.1Skamil
54621.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
54631.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
54641.1Skamil
54651.13Schristos		DPRINTF("Before making context for new lwp in child\n");
54661.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
54671.1Skamil
54681.13Schristos		DPRINTF("Before creating new in child\n");
54691.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
54701.1Skamil
54711.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
54721.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
54731.1Skamil
54741.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
54751.1Skamil		    "are the same\n", lid, the_lwp_id);
54761.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
54771.1Skamil
54781.13Schristos		DPRINTF("Before exiting of the child process\n");
54791.1Skamil		_exit(exitval);
54801.1Skamil	}
54811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54821.1Skamil
54831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54851.1Skamil
54861.1Skamil	validate_status_stopped(status, sigval);
54871.1Skamil
54881.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
54891.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
54901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
54911.1Skamil
54921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54931.1Skamil	    "without signal to be sent\n");
54941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54951.1Skamil
54961.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
54971.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
54981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54991.1Skamil
55001.1Skamil	validate_status_stopped(status, SIGTRAP);
55011.1Skamil
55021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55031.1Skamil
55041.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
55051.1Skamil
55061.1Skamil	lid = state.pe_lwp;
55071.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
55081.1Skamil
55091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55101.1Skamil	    "without signal to be sent\n");
55111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55121.1Skamil
55131.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
55141.1Skamil	    TWAIT_FNAME);
55151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55161.1Skamil
55171.1Skamil	validate_status_exited(status, exitval);
55181.1Skamil
55191.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
55201.1Skamil	    TWAIT_FNAME);
55211.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55221.1Skamil}
55231.1Skamil
55241.1SkamilATF_TC(lwp_exit1);
55251.1SkamilATF_TC_HEAD(lwp_exit1, tc)
55261.1Skamil{
55271.1Skamil	atf_tc_set_md_var(tc, "descr",
55281.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
55291.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
55301.1Skamil}
55311.1Skamil
55321.1SkamilATF_TC_BODY(lwp_exit1, tc)
55331.1Skamil{
55341.1Skamil	const int exitval = 5;
55351.1Skamil	const int sigval = SIGSTOP;
55361.1Skamil	pid_t child, wpid;
55371.1Skamil#if defined(TWAIT_HAVE_STATUS)
55381.1Skamil	int status;
55391.1Skamil#endif
55401.1Skamil	ptrace_state_t state;
55411.1Skamil	const int slen = sizeof(state);
55421.1Skamil	ptrace_event_t event;
55431.1Skamil	const int elen = sizeof(event);
55441.1Skamil	ucontext_t uc;
55451.1Skamil	lwpid_t lid;
55461.1Skamil	static const size_t ssize = 16*1024;
55471.1Skamil	void *stack;
55481.1Skamil
55491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55511.1Skamil	if (child == 0) {
55521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55541.1Skamil
55551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55571.1Skamil
55581.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
55591.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
55601.1Skamil
55611.13Schristos		DPRINTF("Before making context for new lwp in child\n");
55621.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
55631.1Skamil
55641.13Schristos		DPRINTF("Before creating new in child\n");
55651.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
55661.1Skamil
55671.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
55681.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
55691.1Skamil
55701.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
55711.1Skamil		    "are the same\n", lid, the_lwp_id);
55721.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
55731.1Skamil
55741.13Schristos		DPRINTF("Before exiting of the child process\n");
55751.1Skamil		_exit(exitval);
55761.1Skamil	}
55771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55781.1Skamil
55791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55811.1Skamil
55821.1Skamil	validate_status_stopped(status, sigval);
55831.1Skamil
55841.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55851.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
55861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55871.1Skamil
55881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55891.1Skamil	    "without signal to be sent\n");
55901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55911.1Skamil
55921.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55931.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55951.1Skamil
55961.1Skamil	validate_status_stopped(status, SIGTRAP);
55971.1Skamil
55981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55991.1Skamil
56001.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
56011.1Skamil
56021.1Skamil	lid = state.pe_lwp;
56031.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
56041.1Skamil
56051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56061.1Skamil	    "without signal to be sent\n");
56071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56081.1Skamil
56091.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
56101.1Skamil	    TWAIT_FNAME);
56111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56121.1Skamil
56131.1Skamil	validate_status_exited(status, exitval);
56141.1Skamil
56151.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
56161.1Skamil	    TWAIT_FNAME);
56171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56181.1Skamil}
56191.1Skamil
56201.1SkamilATF_TC(signal1);
56211.1SkamilATF_TC_HEAD(signal1, tc)
56221.1Skamil{
56231.1Skamil	atf_tc_set_md_var(tc, "descr",
56241.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
56251.1Skamil	    "from catching other signals");
56261.1Skamil}
56271.1Skamil
56281.1SkamilATF_TC_BODY(signal1, tc)
56291.1Skamil{
56301.1Skamil	const int exitval = 5;
56311.1Skamil	const int sigval = SIGSTOP;
56321.1Skamil	const int sigmasked = SIGTRAP;
56331.1Skamil	const int signotmasked = SIGINT;
56341.1Skamil	pid_t child, wpid;
56351.1Skamil#if defined(TWAIT_HAVE_STATUS)
56361.1Skamil	int status;
56371.1Skamil#endif
56381.1Skamil	sigset_t intmask;
56391.1Skamil
56401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56421.1Skamil	if (child == 0) {
56431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56451.1Skamil
56461.1Skamil		sigemptyset(&intmask);
56471.1Skamil		sigaddset(&intmask, sigmasked);
56481.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56491.1Skamil
56501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56521.1Skamil
56531.13Schristos		DPRINTF("Before raising %s from child\n",
56541.1Skamil		    strsignal(signotmasked));
56551.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
56561.1Skamil
56571.13Schristos		DPRINTF("Before exiting of the child process\n");
56581.1Skamil		_exit(exitval);
56591.1Skamil	}
56601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56611.1Skamil
56621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56641.1Skamil
56651.1Skamil	validate_status_stopped(status, sigval);
56661.1Skamil
56671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56681.1Skamil	    "without signal to be sent\n");
56691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56701.1Skamil
56711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56731.1Skamil
56741.1Skamil	validate_status_stopped(status, signotmasked);
56751.1Skamil
56761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56771.1Skamil	    "without signal to be sent\n");
56781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56791.1Skamil
56801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56821.1Skamil
56831.1Skamil	validate_status_exited(status, exitval);
56841.1Skamil
56851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56861.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56871.1Skamil}
56881.1Skamil
56891.1SkamilATF_TC(signal2);
56901.1SkamilATF_TC_HEAD(signal2, tc)
56911.1Skamil{
56921.1Skamil	atf_tc_set_md_var(tc, "descr",
56931.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
56941.1Skamil	    "catching this raised signal");
56951.1Skamil}
56961.1Skamil
56971.1SkamilATF_TC_BODY(signal2, tc)
56981.1Skamil{
56991.1Skamil	const int exitval = 5;
57001.1Skamil	const int sigval = SIGSTOP;
57011.1Skamil	const int sigmasked = SIGTRAP;
57021.1Skamil	pid_t child, wpid;
57031.1Skamil#if defined(TWAIT_HAVE_STATUS)
57041.1Skamil	int status;
57051.1Skamil#endif
57061.1Skamil	sigset_t intmask;
57071.1Skamil
57081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57101.1Skamil	if (child == 0) {
57111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57131.1Skamil
57141.1Skamil		sigemptyset(&intmask);
57151.1Skamil		sigaddset(&intmask, sigmasked);
57161.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57171.1Skamil
57181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57201.1Skamil
57211.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
57221.1Skamil		    strsignal(sigmasked));
57231.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
57241.1Skamil
57251.13Schristos		DPRINTF("Before exiting of the child process\n");
57261.1Skamil		_exit(exitval);
57271.1Skamil	}
57281.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57291.1Skamil
57301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57321.1Skamil
57331.1Skamil	validate_status_stopped(status, sigval);
57341.1Skamil
57351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57361.1Skamil	    "without signal to be sent\n");
57371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57381.1Skamil
57391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57411.1Skamil
57421.1Skamil	validate_status_exited(status, exitval);
57431.1Skamil
57441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57461.1Skamil}
57471.1Skamil
57481.1SkamilATF_TC(signal3);
57491.1SkamilATF_TC_HEAD(signal3, tc)
57501.1Skamil{
57511.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57521.1Skamil	atf_tc_set_md_var(tc, "descr",
57531.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57541.1Skamil	    "catching software breakpoints");
57551.1Skamil}
57561.1Skamil
57571.1SkamilATF_TC_BODY(signal3, tc)
57581.1Skamil{
57591.1Skamil	const int exitval = 5;
57601.1Skamil	const int sigval = SIGSTOP;
57611.1Skamil	const int sigmasked = SIGTRAP;
57621.1Skamil	pid_t child, wpid;
57631.1Skamil#if defined(TWAIT_HAVE_STATUS)
57641.1Skamil	int status;
57651.1Skamil#endif
57661.1Skamil	sigset_t intmask;
57671.1Skamil
57681.10Smartin#if defined(__sparc__)
57691.7Skamil	atf_tc_expect_timeout("PR kern/52167");
57701.7Skamil
57711.7Skamil	// timeout wins, failure still valid
57721.7Skamil	// atf_tc_expect_fail("PR kern/51918");
57731.7Skamil#endif
57741.1Skamil
57751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57771.1Skamil	if (child == 0) {
57781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57801.1Skamil
57811.1Skamil		sigemptyset(&intmask);
57821.1Skamil		sigaddset(&intmask, sigmasked);
57831.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57841.1Skamil
57851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57871.1Skamil
57881.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
57891.4Skamil
57901.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
57911.4Skamil		PTRACE_BREAKPOINT_ASM;
57921.1Skamil#else
57931.4Skamil		/* port me */
57941.1Skamil#endif
57951.1Skamil
57961.13Schristos		DPRINTF("Before exiting of the child process\n");
57971.1Skamil		_exit(exitval);
57981.1Skamil	}
57991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58001.1Skamil
58011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58031.1Skamil
58041.1Skamil	validate_status_stopped(status, sigval);
58051.1Skamil
58061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58071.1Skamil	    "without signal to be sent\n");
58081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58091.1Skamil
58101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58121.1Skamil
58131.1Skamil	validate_status_stopped(status, sigmasked);
58141.1Skamil
58151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58161.1Skamil	    "without signal to be sent\n");
58171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58181.1Skamil
58191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58211.1Skamil
58221.1Skamil	validate_status_exited(status, exitval);
58231.1Skamil
58241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58261.1Skamil}
58271.1Skamil
58281.1Skamil#if defined(PT_STEP)
58291.1SkamilATF_TC(signal4);
58301.1SkamilATF_TC_HEAD(signal4, tc)
58311.1Skamil{
58321.1Skamil	atf_tc_set_md_var(tc, "descr",
58331.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58341.1Skamil	    "catching single step trap");
58351.1Skamil}
58361.1Skamil
58371.1SkamilATF_TC_BODY(signal4, tc)
58381.1Skamil{
58391.1Skamil	const int exitval = 5;
58401.1Skamil	const int sigval = SIGSTOP;
58411.1Skamil	const int sigmasked = SIGTRAP;
58421.1Skamil	pid_t child, wpid;
58431.1Skamil#if defined(TWAIT_HAVE_STATUS)
58441.1Skamil	int status;
58451.1Skamil#endif
58461.1Skamil	sigset_t intmask;
58471.1Skamil	int happy;
58481.1Skamil
58491.1Skamil#if defined(__arm__)
58501.5Skamil	/* PT_STEP not supported on arm 32-bit */
58511.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
58521.1Skamil#endif
58531.1Skamil
58541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58561.1Skamil	if (child == 0) {
58571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58591.1Skamil
58601.1Skamil		happy = check_happy(100);
58611.1Skamil
58621.1Skamil		sigemptyset(&intmask);
58631.1Skamil		sigaddset(&intmask, sigmasked);
58641.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58651.1Skamil
58661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58681.1Skamil
58691.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
58701.1Skamil
58711.13Schristos		DPRINTF("Before exiting of the child process\n");
58721.1Skamil		_exit(exitval);
58731.1Skamil	}
58741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58751.1Skamil
58761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58781.1Skamil
58791.1Skamil	validate_status_stopped(status, sigval);
58801.1Skamil
58811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58821.1Skamil	    "without signal to be sent\n");
58831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
58841.1Skamil
58851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58871.1Skamil
58881.1Skamil	validate_status_stopped(status, sigmasked);
58891.1Skamil
58901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58911.1Skamil	    "without signal to be sent\n");
58921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58931.1Skamil
58941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58961.1Skamil
58971.1Skamil	validate_status_exited(status, exitval);
58981.1Skamil
58991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59011.1Skamil}
59021.1Skamil#endif
59031.1Skamil
59041.1SkamilATF_TC(signal5);
59051.1SkamilATF_TC_HEAD(signal5, tc)
59061.1Skamil{
59071.1Skamil	atf_tc_set_md_var(tc, "descr",
59081.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59091.1Skamil	    "catching exec() breakpoint");
59101.1Skamil}
59111.1Skamil
59121.1SkamilATF_TC_BODY(signal5, tc)
59131.1Skamil{
59141.1Skamil	const int exitval = 5;
59151.1Skamil	const int sigval = SIGSTOP;
59161.1Skamil	const int sigmasked = SIGTRAP;
59171.1Skamil	pid_t child, wpid;
59181.1Skamil#if defined(TWAIT_HAVE_STATUS)
59191.1Skamil	int status;
59201.1Skamil#endif
59211.1Skamil	sigset_t intmask;
59221.1Skamil
59231.14Schristos	atf_tc_expect_fail("wrong signal");
59241.14Schristos
59251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59271.1Skamil	if (child == 0) {
59281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59301.1Skamil
59311.1Skamil		sigemptyset(&intmask);
59321.1Skamil		sigaddset(&intmask, sigmasked);
59331.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59341.1Skamil
59351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59371.1Skamil
59381.13Schristos		DPRINTF("Before calling execve(2) from child\n");
59391.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
59401.1Skamil
59411.13Schristos		DPRINTF("Before exiting of the child process\n");
59421.1Skamil		_exit(exitval);
59431.1Skamil	}
59441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59451.1Skamil
59461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59481.1Skamil
59491.1Skamil	validate_status_stopped(status, sigval);
59501.1Skamil
59511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59521.1Skamil	    "without signal to be sent\n");
59531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59541.1Skamil
59551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59571.1Skamil
59581.1Skamil	validate_status_stopped(status, sigmasked);
59591.1Skamil
59601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59611.1Skamil	    "without signal to be sent\n");
59621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59631.1Skamil
59641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59661.1Skamil
59671.1Skamil	validate_status_exited(status, exitval);
59681.1Skamil
59691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59711.1Skamil}
59721.1Skamil
59731.1Skamil#if defined(TWAIT_HAVE_PID)
59741.1SkamilATF_TC(signal6);
59751.1SkamilATF_TC_HEAD(signal6, tc)
59761.1Skamil{
59771.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
59781.1Skamil	atf_tc_set_md_var(tc, "descr",
59791.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59801.1Skamil	    "catching PTRACE_FORK breakpoint");
59811.1Skamil}
59821.1Skamil
59831.1SkamilATF_TC_BODY(signal6, tc)
59841.1Skamil{
59851.1Skamil	const int exitval = 5;
59861.1Skamil	const int exitval2 = 15;
59871.1Skamil	const int sigval = SIGSTOP;
59881.1Skamil	const int sigmasked = SIGTRAP;
59891.1Skamil	pid_t child, child2, wpid;
59901.1Skamil#if defined(TWAIT_HAVE_STATUS)
59911.1Skamil	int status;
59921.1Skamil#endif
59931.1Skamil	sigset_t intmask;
59941.1Skamil	ptrace_state_t state;
59951.1Skamil	const int slen = sizeof(state);
59961.1Skamil	ptrace_event_t event;
59971.1Skamil	const int elen = sizeof(event);
59981.1Skamil
59991.14Schristos	atf_tc_expect_timeout("PR kern/51918");
60001.14Schristos
60011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60031.1Skamil	if (child == 0) {
60041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60061.1Skamil
60071.1Skamil		sigemptyset(&intmask);
60081.1Skamil		sigaddset(&intmask, sigmasked);
60091.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60101.1Skamil
60111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60131.1Skamil
60141.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
60151.1Skamil
60161.1Skamil		if (child2 == 0)
60171.1Skamil			_exit(exitval2);
60181.1Skamil
60191.1Skamil		FORKEE_REQUIRE_SUCCESS
60201.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60211.1Skamil
60221.1Skamil		forkee_status_exited(status, exitval2);
60231.1Skamil
60241.13Schristos		DPRINTF("Before exiting of the child process\n");
60251.1Skamil		_exit(exitval);
60261.1Skamil	}
60271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60281.1Skamil
60291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60311.1Skamil
60321.1Skamil	validate_status_stopped(status, sigval);
60331.1Skamil
60341.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
60351.1Skamil	event.pe_set_event = PTRACE_FORK;
60361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60371.1Skamil
60381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60391.1Skamil	    "without signal to be sent\n");
60401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60411.1Skamil
60421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60441.1Skamil
60451.1Skamil	validate_status_stopped(status, sigmasked);
60461.1Skamil
60471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60481.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60491.1Skamil
60501.1Skamil	child2 = state.pe_other_pid;
60511.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
60521.1Skamil
60531.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
60541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60551.1Skamil	    child2);
60561.1Skamil
60571.1Skamil	validate_status_stopped(status, SIGTRAP);
60581.1Skamil
60591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
60601.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60611.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
60621.1Skamil
60631.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
60641.1Skamil	    "without signal to be sent\n");
60651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
60661.1Skamil
60671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60681.1Skamil	    "without signal to be sent\n");
60691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60701.1Skamil
60711.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60721.1Skamil	    TWAIT_FNAME);
60731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60741.1Skamil	    child2);
60751.1Skamil
60761.1Skamil	validate_status_exited(status, exitval2);
60771.1Skamil
60781.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
60791.1Skamil	    TWAIT_FNAME);
60801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
60811.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
60821.1Skamil
60831.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60841.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
60851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60861.1Skamil
60871.1Skamil	validate_status_stopped(status, SIGCHLD);
60881.1Skamil
60891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60901.1Skamil	    "without signal to be sent\n");
60911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60921.1Skamil
60931.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60941.1Skamil	    TWAIT_FNAME);
60951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60961.1Skamil
60971.1Skamil	validate_status_exited(status, exitval);
60981.1Skamil
60991.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61001.1Skamil	    TWAIT_FNAME);
61011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61021.1Skamil}
61031.1Skamil#endif
61041.1Skamil
61051.1Skamil#if defined(TWAIT_HAVE_PID)
61061.1SkamilATF_TC(signal7);
61071.1SkamilATF_TC_HEAD(signal7, tc)
61081.1Skamil{
61091.1Skamil	atf_tc_set_md_var(tc, "descr",
61101.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61111.1Skamil	    "catching PTRACE_VFORK breakpoint");
61121.1Skamil}
61131.1Skamil
61141.1SkamilATF_TC_BODY(signal7, tc)
61151.1Skamil{
61161.1Skamil	const int exitval = 5;
61171.1Skamil	const int exitval2 = 15;
61181.1Skamil	const int sigval = SIGSTOP;
61191.1Skamil	const int sigmasked = SIGTRAP;
61201.1Skamil	pid_t child, child2, wpid;
61211.1Skamil#if defined(TWAIT_HAVE_STATUS)
61221.1Skamil	int status;
61231.1Skamil#endif
61241.1Skamil	sigset_t intmask;
61251.1Skamil	ptrace_state_t state;
61261.1Skamil	const int slen = sizeof(state);
61271.1Skamil	ptrace_event_t event;
61281.1Skamil	const int elen = sizeof(event);
61291.1Skamil
61301.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
61311.14Schristos
61321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61341.1Skamil	if (child == 0) {
61351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61371.1Skamil
61381.1Skamil		sigemptyset(&intmask);
61391.1Skamil		sigaddset(&intmask, sigmasked);
61401.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61411.1Skamil
61421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61441.1Skamil
61451.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
61461.1Skamil
61471.1Skamil		if (child2 == 0)
61481.1Skamil			_exit(exitval2);
61491.1Skamil
61501.1Skamil		FORKEE_REQUIRE_SUCCESS
61511.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
61521.1Skamil
61531.1Skamil		forkee_status_exited(status, exitval2);
61541.1Skamil
61551.13Schristos		DPRINTF("Before exiting of the child process\n");
61561.1Skamil		_exit(exitval);
61571.1Skamil	}
61581.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61591.1Skamil
61601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61621.1Skamil
61631.1Skamil	validate_status_stopped(status, sigval);
61641.1Skamil
61651.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
61661.1Skamil	event.pe_set_event = PTRACE_VFORK;
61671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
61681.1Skamil
61691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61701.1Skamil	    "without signal to be sent\n");
61711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61721.1Skamil
61731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61751.1Skamil
61761.1Skamil	validate_status_stopped(status, sigmasked);
61771.1Skamil
61781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61791.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61801.1Skamil
61811.1Skamil	child2 = state.pe_other_pid;
61821.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
61831.1Skamil
61841.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
61851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
61861.1Skamil	    child2);
61871.1Skamil
61881.1Skamil	validate_status_stopped(status, SIGTRAP);
61891.1Skamil
61901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
61911.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61921.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
61931.1Skamil
61941.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
61951.1Skamil	    "without signal to be sent\n");
61961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
61971.1Skamil
61981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61991.1Skamil	    "without signal to be sent\n");
62001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62011.1Skamil
62021.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
62031.1Skamil	    TWAIT_FNAME);
62041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62051.1Skamil	    child2);
62061.1Skamil
62071.1Skamil	validate_status_exited(status, exitval2);
62081.1Skamil
62091.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
62101.1Skamil	    TWAIT_FNAME);
62111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
62121.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
62131.1Skamil
62141.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62151.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
62161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62171.1Skamil
62181.1Skamil	validate_status_stopped(status, SIGCHLD);
62191.1Skamil
62201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62211.1Skamil	    "without signal to be sent\n");
62221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62231.1Skamil
62241.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62251.1Skamil	    TWAIT_FNAME);
62261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62271.1Skamil
62281.1Skamil	validate_status_exited(status, exitval);
62291.1Skamil
62301.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62311.1Skamil	    TWAIT_FNAME);
62321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62331.1Skamil}
62341.1Skamil#endif
62351.1Skamil
62361.1SkamilATF_TC(signal8);
62371.1SkamilATF_TC_HEAD(signal8, tc)
62381.1Skamil{
62391.1Skamil	atf_tc_set_md_var(tc, "descr",
62401.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62411.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
62421.1Skamil}
62431.1Skamil
62441.1SkamilATF_TC_BODY(signal8, tc)
62451.1Skamil{
62461.1Skamil	const int exitval = 5;
62471.1Skamil	const int exitval2 = 15;
62481.1Skamil	const int sigval = SIGSTOP;
62491.1Skamil	const int sigmasked = SIGTRAP;
62501.1Skamil	pid_t child, child2, wpid;
62511.1Skamil#if defined(TWAIT_HAVE_STATUS)
62521.1Skamil	int status;
62531.1Skamil#endif
62541.1Skamil	sigset_t intmask;
62551.1Skamil	ptrace_state_t state;
62561.1Skamil	const int slen = sizeof(state);
62571.1Skamil	ptrace_event_t event;
62581.1Skamil	const int elen = sizeof(event);
62591.1Skamil
62601.14Schristos	atf_tc_expect_fail("PR kern/51918");
62611.14Schristos
62621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62641.1Skamil	if (child == 0) {
62651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62671.1Skamil
62681.1Skamil		sigemptyset(&intmask);
62691.1Skamil		sigaddset(&intmask, sigmasked);
62701.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62711.1Skamil
62721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62741.1Skamil
62751.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
62761.1Skamil
62771.1Skamil		if (child2 == 0)
62781.1Skamil			_exit(exitval2);
62791.1Skamil
62801.1Skamil		FORKEE_REQUIRE_SUCCESS
62811.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
62821.1Skamil
62831.1Skamil		forkee_status_exited(status, exitval2);
62841.1Skamil
62851.13Schristos		DPRINTF("Before exiting of the child process\n");
62861.1Skamil		_exit(exitval);
62871.1Skamil	}
62881.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62891.1Skamil
62901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62921.1Skamil
62931.1Skamil	validate_status_stopped(status, sigval);
62941.1Skamil
62951.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
62961.1Skamil	    child);
62971.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
62981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
62991.1Skamil
63001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63011.1Skamil	    "without signal to be sent\n");
63021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63031.1Skamil
63041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63061.1Skamil
63071.1Skamil	validate_status_stopped(status, sigmasked);
63081.1Skamil
63091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63101.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
63111.1Skamil
63121.1Skamil	child2 = state.pe_other_pid;
63131.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
63141.1Skamil
63151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63161.1Skamil	    "without signal to be sent\n");
63171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63181.1Skamil
63191.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63201.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
63211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63221.1Skamil
63231.1Skamil	validate_status_stopped(status, SIGCHLD);
63241.1Skamil
63251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63261.1Skamil	    "without signal to be sent\n");
63271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63281.1Skamil
63291.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63301.1Skamil	    TWAIT_FNAME);
63311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63321.1Skamil
63331.1Skamil	validate_status_exited(status, exitval);
63341.1Skamil
63351.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63361.1Skamil	    TWAIT_FNAME);
63371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63381.1Skamil}
63391.1Skamil
63401.1SkamilATF_TC(signal9);
63411.1SkamilATF_TC_HEAD(signal9, tc)
63421.1Skamil{
63431.1Skamil	atf_tc_set_md_var(tc, "descr",
63441.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
63451.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
63461.1Skamil}
63471.1Skamil
63481.1SkamilATF_TC_BODY(signal9, tc)
63491.1Skamil{
63501.1Skamil	const int exitval = 5;
63511.1Skamil	const int sigval = SIGSTOP;
63521.1Skamil	const int sigmasked = SIGTRAP;
63531.1Skamil	pid_t child, wpid;
63541.1Skamil#if defined(TWAIT_HAVE_STATUS)
63551.1Skamil	int status;
63561.1Skamil#endif
63571.1Skamil	sigset_t intmask;
63581.1Skamil	ptrace_state_t state;
63591.1Skamil	const int slen = sizeof(state);
63601.1Skamil	ptrace_event_t event;
63611.1Skamil	const int elen = sizeof(event);
63621.1Skamil	ucontext_t uc;
63631.1Skamil	lwpid_t lid;
63641.1Skamil	static const size_t ssize = 16*1024;
63651.1Skamil	void *stack;
63661.1Skamil
63671.14Schristos	atf_tc_expect_fail("PR kern/51918");
63681.14Schristos
63691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63711.1Skamil	if (child == 0) {
63721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63741.1Skamil
63751.1Skamil		sigemptyset(&intmask);
63761.1Skamil		sigaddset(&intmask, sigmasked);
63771.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
63781.1Skamil
63791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63811.1Skamil
63821.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63831.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
63841.1Skamil
63851.13Schristos		DPRINTF("Before making context for new lwp in child\n");
63861.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
63871.1Skamil
63881.13Schristos		DPRINTF("Before creating new in child\n");
63891.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
63901.1Skamil
63911.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
63921.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
63931.1Skamil
63941.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
63951.1Skamil		    "are the same\n", lid, the_lwp_id);
63961.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
63971.1Skamil
63981.13Schristos		DPRINTF("Before exiting of the child process\n");
63991.1Skamil		_exit(exitval);
64001.1Skamil	}
64011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64021.1Skamil
64031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64051.1Skamil
64061.1Skamil	validate_status_stopped(status, sigval);
64071.1Skamil
64081.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
64091.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
64101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
64111.1Skamil
64121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64131.1Skamil	    "without signal to be sent\n");
64141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64151.1Skamil
64161.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64171.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64191.1Skamil
64201.1Skamil	validate_status_stopped(status, sigmasked);
64211.1Skamil
64221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
64231.1Skamil
64241.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
64251.1Skamil
64261.1Skamil	lid = state.pe_lwp;
64271.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
64281.1Skamil
64291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64301.1Skamil	    "without signal to be sent\n");
64311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64321.1Skamil
64331.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64341.1Skamil	    TWAIT_FNAME);
64351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64361.1Skamil
64371.1Skamil	validate_status_exited(status, exitval);
64381.1Skamil
64391.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64401.1Skamil	    TWAIT_FNAME);
64411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64421.1Skamil}
64431.1Skamil
64441.1SkamilATF_TC(signal10);
64451.1SkamilATF_TC_HEAD(signal10, tc)
64461.1Skamil{
64471.1Skamil	atf_tc_set_md_var(tc, "descr",
64481.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
64491.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
64501.1Skamil}
64511.1Skamil
64521.1SkamilATF_TC_BODY(signal10, tc)
64531.1Skamil{
64541.1Skamil	const int exitval = 5;
64551.1Skamil	const int sigval = SIGSTOP;
64561.1Skamil	const int sigmasked = SIGTRAP;
64571.1Skamil	pid_t child, wpid;
64581.1Skamil#if defined(TWAIT_HAVE_STATUS)
64591.1Skamil	int status;
64601.1Skamil#endif
64611.1Skamil	sigset_t intmask;
64621.1Skamil	ptrace_state_t state;
64631.1Skamil	const int slen = sizeof(state);
64641.1Skamil	ptrace_event_t event;
64651.1Skamil	const int elen = sizeof(event);
64661.1Skamil	ucontext_t uc;
64671.1Skamil	lwpid_t lid;
64681.1Skamil	static const size_t ssize = 16*1024;
64691.1Skamil	void *stack;
64701.1Skamil
64711.14Schristos	atf_tc_expect_fail("PR kern/51918");
64721.14Schristos
64731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64751.1Skamil	if (child == 0) {
64761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64781.1Skamil
64791.1Skamil		sigemptyset(&intmask);
64801.1Skamil		sigaddset(&intmask, sigmasked);
64811.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
64821.1Skamil
64831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64851.1Skamil
64861.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64871.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64881.1Skamil
64891.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64901.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
64911.1Skamil
64921.13Schristos		DPRINTF("Before creating new in child\n");
64931.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64941.1Skamil
64951.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64961.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64971.1Skamil
64981.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64991.1Skamil		    "are the same\n", lid, the_lwp_id);
65001.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
65011.1Skamil
65021.13Schristos		DPRINTF("Before exiting of the child process\n");
65031.1Skamil		_exit(exitval);
65041.1Skamil	}
65051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65061.1Skamil
65071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65091.1Skamil
65101.1Skamil	validate_status_stopped(status, sigval);
65111.1Skamil
65121.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
65131.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
65141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
65151.1Skamil
65161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65171.1Skamil	    "without signal to be sent\n");
65181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65191.1Skamil
65201.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65211.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65231.1Skamil
65241.1Skamil	validate_status_stopped(status, sigmasked);
65251.1Skamil
65261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
65271.1Skamil
65281.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
65291.1Skamil
65301.1Skamil	lid = state.pe_lwp;
65311.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
65321.1Skamil
65331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65341.1Skamil	    "without signal to be sent\n");
65351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65361.1Skamil
65371.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65381.1Skamil	    TWAIT_FNAME);
65391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65401.1Skamil
65411.1Skamil	validate_status_exited(status, exitval);
65421.1Skamil
65431.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65441.1Skamil	    TWAIT_FNAME);
65451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65461.1Skamil}
65471.1Skamil
65481.1SkamilATF_TC(getsigmask1);
65491.1SkamilATF_TC_HEAD(getsigmask1, tc)
65501.1Skamil{
65511.1Skamil	atf_tc_set_md_var(tc, "descr",
65521.1Skamil	    "Verify that plain PT_SET_SIGMASK can be called");
65531.1Skamil}
65541.1Skamil
65551.1SkamilATF_TC_BODY(getsigmask1, tc)
65561.1Skamil{
65571.1Skamil	const int exitval = 5;
65581.1Skamil	const int sigval = SIGSTOP;
65591.1Skamil	pid_t child, wpid;
65601.1Skamil#if defined(TWAIT_HAVE_STATUS)
65611.1Skamil	int status;
65621.1Skamil#endif
65631.1Skamil	sigset_t mask;
65641.1Skamil
65651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65671.1Skamil	if (child == 0) {
65681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65701.1Skamil
65711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65731.1Skamil
65741.13Schristos		DPRINTF("Before exiting of the child process\n");
65751.1Skamil		_exit(exitval);
65761.1Skamil	}
65771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65781.1Skamil
65791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65811.1Skamil
65821.1Skamil	validate_status_stopped(status, sigval);
65831.1Skamil
65841.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK\n");
65851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &mask, 0) != -1);
65861.1Skamil
65871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65881.1Skamil	    "without signal to be sent\n");
65891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65901.1Skamil
65911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65931.1Skamil
65941.1Skamil	validate_status_exited(status, exitval);
65951.1Skamil
65961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65981.1Skamil}
65991.1Skamil
66001.1SkamilATF_TC(getsigmask2);
66011.1SkamilATF_TC_HEAD(getsigmask2, tc)
66021.1Skamil{
66031.1Skamil	atf_tc_set_md_var(tc, "descr",
66041.1Skamil	    "Verify that PT_SET_SIGMASK reports correct mask from tracee");
66051.1Skamil}
66061.1Skamil
66071.1SkamilATF_TC_BODY(getsigmask2, tc)
66081.1Skamil{
66091.1Skamil	const int exitval = 5;
66101.1Skamil	const int sigval = SIGSTOP;
66111.1Skamil	const int sigmasked = SIGTRAP;
66121.1Skamil	pid_t child, wpid;
66131.1Skamil#if defined(TWAIT_HAVE_STATUS)
66141.1Skamil	int status;
66151.1Skamil#endif
66161.1Skamil	sigset_t mask;
66171.1Skamil	sigset_t expected_mask;
66181.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
66191.1Skamil	ATF_REQUIRE(sigemptyset(&expected_mask) == 0);
66201.1Skamil	ATF_REQUIRE(sigaddset(&expected_mask, sigmasked) == 0);
66211.1Skamil
66221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66241.1Skamil	if (child == 0) {
66251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66271.1Skamil
66281.1Skamil		sigaddset(&mask, sigmasked);
66291.1Skamil		sigprocmask(SIG_BLOCK, &mask, NULL);
66301.1Skamil
66311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66331.1Skamil
66341.13Schristos		DPRINTF("Before exiting of the child process\n");
66351.1Skamil		_exit(exitval);
66361.1Skamil	}
66371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66381.1Skamil
66391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66411.1Skamil
66421.1Skamil	validate_status_stopped(status, sigval);
66431.1Skamil
66441.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK\n");
66451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &mask, 0) != -1);
66461.1Skamil
66471.1Skamil	ATF_REQUIRE(memcmp(&mask, &expected_mask, sizeof(sigset_t)) == 0);
66481.1Skamil
66491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66501.1Skamil	    "without signal to be sent\n");
66511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66521.1Skamil
66531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66551.1Skamil
66561.1Skamil	validate_status_exited(status, exitval);
66571.1Skamil
66581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66601.1Skamil}
66611.1Skamil
66621.1SkamilATF_TC(setsigmask1);
66631.1SkamilATF_TC_HEAD(setsigmask1, tc)
66641.1Skamil{
66651.1Skamil	atf_tc_set_md_var(tc, "descr",
66661.1Skamil	    "Verify that plain PT_SET_SIGMASK can be called with empty mask");
66671.1Skamil}
66681.1Skamil
66691.1SkamilATF_TC_BODY(setsigmask1, tc)
66701.1Skamil{
66711.1Skamil	const int exitval = 5;
66721.1Skamil	const int sigval = SIGSTOP;
66731.1Skamil	pid_t child, wpid;
66741.1Skamil#if defined(TWAIT_HAVE_STATUS)
66751.1Skamil	int status;
66761.1Skamil#endif
66771.1Skamil	sigset_t mask;
66781.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
66791.1Skamil
66801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66821.1Skamil	if (child == 0) {
66831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66851.1Skamil
66861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66881.1Skamil
66891.13Schristos		DPRINTF("Before exiting of the child process\n");
66901.1Skamil		_exit(exitval);
66911.1Skamil	}
66921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66931.1Skamil
66941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66961.1Skamil
66971.1Skamil	validate_status_stopped(status, sigval);
66981.1Skamil
66991.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for empty mask\n");
67001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
67011.1Skamil
67021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67031.1Skamil	    "without signal to be sent\n");
67041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67051.1Skamil
67061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67081.1Skamil
67091.1Skamil	validate_status_exited(status, exitval);
67101.1Skamil
67111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67131.1Skamil}
67141.1Skamil
67151.1SkamilATF_TC(setsigmask2);
67161.1SkamilATF_TC_HEAD(setsigmask2, tc)
67171.1Skamil{
67181.1Skamil	atf_tc_set_md_var(tc, "descr",
67191.1Skamil	    "Verify that sigmask is preserved between PT_GET_SIGMASK and "
67201.1Skamil	    "PT_SET_SIGMASK");
67211.1Skamil}
67221.1Skamil
67231.1SkamilATF_TC_BODY(setsigmask2, tc)
67241.1Skamil{
67251.1Skamil	const int exitval = 5;
67261.1Skamil	const int sigval = SIGSTOP;
67271.1Skamil	pid_t child, wpid;
67281.1Skamil#if defined(TWAIT_HAVE_STATUS)
67291.1Skamil	int status;
67301.1Skamil#endif
67311.1Skamil	sigset_t new_mask;
67321.1Skamil	sigset_t mask;
67331.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
67341.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
67351.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGINT) == 0);
67361.1Skamil
67371.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67381.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67391.1Skamil	if (child == 0) {
67401.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67411.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67421.1Skamil
67431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67451.1Skamil
67461.13Schristos		DPRINTF("Before exiting of the child process\n");
67471.1Skamil		_exit(exitval);
67481.1Skamil	}
67491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67501.1Skamil
67511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67531.1Skamil
67541.1Skamil	validate_status_stopped(status, sigval);
67551.1Skamil
67561.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
67571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
67581.1Skamil
67591.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
67601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
67611.1Skamil
67621.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) == 0);
67631.1Skamil
67641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67651.1Skamil	    "without signal to be sent\n");
67661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67671.1Skamil
67681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67701.1Skamil
67711.1Skamil	validate_status_exited(status, exitval);
67721.1Skamil
67731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67751.1Skamil}
67761.1Skamil
67771.1SkamilATF_TC(setsigmask3);
67781.1SkamilATF_TC_HEAD(setsigmask3, tc)
67791.1Skamil{
67801.1Skamil	atf_tc_set_md_var(tc, "descr",
67811.1Skamil	    "Verify that sigmask is preserved between PT_GET_SIGMASK, process "
67821.1Skamil	    "resumed and PT_SET_SIGMASK");
67831.1Skamil}
67841.1Skamil
67851.1SkamilATF_TC_BODY(setsigmask3, tc)
67861.1Skamil{
67871.1Skamil	const int exitval = 5;
67881.1Skamil	const int sigval = SIGSTOP;
67891.1Skamil	pid_t child, wpid;
67901.1Skamil#if defined(TWAIT_HAVE_STATUS)
67911.1Skamil	int status;
67921.1Skamil#endif
67931.1Skamil	sigset_t new_mask;
67941.1Skamil	sigset_t mask;
67951.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
67961.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
67971.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGINT) == 0);
67981.1Skamil
67991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
68001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
68011.1Skamil	if (child == 0) {
68021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68041.1Skamil
68051.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68061.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68071.1Skamil
68081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68101.1Skamil
68111.13Schristos		DPRINTF("Before exiting of the child process\n");
68121.1Skamil		_exit(exitval);
68131.1Skamil	}
68141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68151.1Skamil
68161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68181.1Skamil
68191.1Skamil	validate_status_stopped(status, sigval);
68201.1Skamil
68211.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
68221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
68231.1Skamil
68241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68251.1Skamil	    "without signal to be sent\n");
68261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68271.1Skamil
68281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68301.1Skamil
68311.1Skamil	validate_status_stopped(status, sigval);
68321.1Skamil
68331.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
68341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
68351.1Skamil
68361.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) == 0);
68371.1Skamil
68381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68391.1Skamil	    "without signal to be sent\n");
68401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68411.1Skamil
68421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68441.1Skamil
68451.1Skamil	validate_status_exited(status, exitval);
68461.1Skamil
68471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68481.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
68491.1Skamil}
68501.1Skamil
68511.1SkamilATF_TC(setsigmask4);
68521.1SkamilATF_TC_HEAD(setsigmask4, tc)
68531.1Skamil{
68541.1Skamil	atf_tc_set_md_var(tc, "descr",
68551.1Skamil	    "Verify that new sigmask is visible in tracee");
68561.1Skamil}
68571.1Skamil
68581.1SkamilATF_TC_BODY(setsigmask4, tc)
68591.1Skamil{
68601.1Skamil	const int exitval = 5;
68611.1Skamil	const int sigval = SIGSTOP;
68621.1Skamil	pid_t child, wpid;
68631.1Skamil#if defined(TWAIT_HAVE_STATUS)
68641.1Skamil	int status;
68651.1Skamil#endif
68661.1Skamil	sigset_t mask;
68671.1Skamil	sigset_t expected_mask;
68681.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
68691.1Skamil	ATF_REQUIRE(sigemptyset(&expected_mask) == 0);
68701.1Skamil	ATF_REQUIRE(sigaddset(&expected_mask, SIGINT) == 0);
68711.1Skamil
68721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
68731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
68741.1Skamil	if (child == 0) {
68751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68771.1Skamil
68781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68801.1Skamil
68811.1Skamil		sigprocmask(0, NULL, &mask);
68821.1Skamil
68831.1Skamil		FORKEE_ASSERT
68841.1Skamil		    (memcmp(&mask, &expected_mask, sizeof(sigset_t)) == 0);
68851.1Skamil
68861.13Schristos		DPRINTF("Before exiting of the child process\n");
68871.1Skamil		_exit(exitval);
68881.1Skamil	}
68891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68901.1Skamil
68911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68931.1Skamil
68941.1Skamil	validate_status_stopped(status, sigval);
68951.1Skamil
68961.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
68971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &expected_mask, 0) != -1);
68981.1Skamil
68991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69001.1Skamil	    "without signal to be sent\n");
69011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69021.1Skamil
69031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69051.1Skamil
69061.1Skamil	validate_status_exited(status, exitval);
69071.1Skamil
69081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69101.1Skamil}
69111.1Skamil
69121.1SkamilATF_TC(setsigmask5);
69131.1SkamilATF_TC_HEAD(setsigmask5, tc)
69141.1Skamil{
69151.1Skamil	atf_tc_set_md_var(tc, "descr",
69161.1Skamil	    "Verify that sigmask cannot be set to SIGKILL");
69171.1Skamil}
69181.1Skamil
69191.1SkamilATF_TC_BODY(setsigmask5, tc)
69201.1Skamil{
69211.1Skamil	const int exitval = 5;
69221.1Skamil	const int sigval = SIGSTOP;
69231.1Skamil	pid_t child, wpid;
69241.1Skamil#if defined(TWAIT_HAVE_STATUS)
69251.1Skamil	int status;
69261.1Skamil#endif
69271.1Skamil	sigset_t new_mask;
69281.1Skamil	sigset_t mask;
69291.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
69301.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
69311.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGKILL) == 0);
69321.1Skamil
69331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69351.1Skamil	if (child == 0) {
69361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69381.1Skamil
69391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
69411.1Skamil
69421.13Schristos		DPRINTF("Before exiting of the child process\n");
69431.1Skamil		_exit(exitval);
69441.1Skamil	}
69451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
69461.1Skamil
69471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69491.1Skamil
69501.1Skamil	validate_status_stopped(status, sigval);
69511.1Skamil
69521.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
69531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
69541.1Skamil
69551.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
69561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
69571.1Skamil
69581.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) != 0);
69591.1Skamil
69601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69611.1Skamil	    "without signal to be sent\n");
69621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69631.1Skamil
69641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69661.1Skamil
69671.1Skamil	validate_status_exited(status, exitval);
69681.1Skamil
69691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69711.1Skamil}
69721.1Skamil
69731.1SkamilATF_TC(setsigmask6);
69741.1SkamilATF_TC_HEAD(setsigmask6, tc)
69751.1Skamil{
69761.1Skamil	atf_tc_set_md_var(tc, "descr",
69771.1Skamil	    "Verify that sigmask cannot be set to SIGSTOP");
69781.1Skamil}
69791.1Skamil
69801.1SkamilATF_TC_BODY(setsigmask6, tc)
69811.1Skamil{
69821.1Skamil	const int exitval = 5;
69831.1Skamil	const int sigval = SIGSTOP;
69841.1Skamil	pid_t child, wpid;
69851.1Skamil#if defined(TWAIT_HAVE_STATUS)
69861.1Skamil	int status;
69871.1Skamil#endif
69881.1Skamil	sigset_t new_mask;
69891.1Skamil	sigset_t mask;
69901.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
69911.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
69921.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGSTOP) == 0);
69931.1Skamil
69941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69961.1Skamil	if (child == 0) {
69971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69991.1Skamil
70001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70021.1Skamil
70031.13Schristos		DPRINTF("Before exiting of the child process\n");
70041.1Skamil		_exit(exitval);
70051.1Skamil	}
70061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70071.1Skamil
70081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70101.1Skamil
70111.1Skamil	validate_status_stopped(status, sigval);
70121.1Skamil
70131.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
70141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
70151.1Skamil
70161.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
70171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
70181.1Skamil
70191.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) != 0);
70201.1Skamil
70211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70221.1Skamil	    "without signal to be sent\n");
70231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70241.1Skamil
70251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70271.1Skamil
70281.1Skamil	validate_status_exited(status, exitval);
70291.1Skamil
70301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70321.1Skamil}
70331.1Skamil
70341.1Skamilstatic void
70351.1Skamillwp_main_stop(void *arg)
70361.1Skamil{
70371.1Skamil	the_lwp_id = _lwp_self();
70381.1Skamil
70391.1Skamil	raise(SIGTRAP);
70401.1Skamil
70411.1Skamil	_lwp_exit();
70421.1Skamil}
70431.1Skamil
70441.1SkamilATF_TC(suspend1);
70451.1SkamilATF_TC_HEAD(suspend1, tc)
70461.1Skamil{
70471.1Skamil	atf_tc_set_md_var(tc, "descr",
70481.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
70491.1Skamil	    "resumed by a tracee");
70501.1Skamil}
70511.1Skamil
70521.1SkamilATF_TC_BODY(suspend1, tc)
70531.1Skamil{
70541.1Skamil	const int exitval = 5;
70551.1Skamil	const int sigval = SIGSTOP;
70561.1Skamil	pid_t child, wpid;
70571.1Skamil#if defined(TWAIT_HAVE_STATUS)
70581.1Skamil	int status;
70591.1Skamil#endif
70601.1Skamil	ucontext_t uc;
70611.1Skamil	lwpid_t lid;
70621.1Skamil	static const size_t ssize = 16*1024;
70631.1Skamil	void *stack;
70641.1Skamil	struct ptrace_lwpinfo pl;
70651.1Skamil	struct ptrace_siginfo psi;
70661.1Skamil	volatile int go = 0;
70671.1Skamil
70681.17Skamil	// Feature pending for refactoring
70691.17Skamil	atf_tc_expect_fail("PR kern/51995");
70701.17Skamil
70711.16Skamil	// Hangs with qemu
70721.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
70731.16Skamil
70741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
70751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
70761.1Skamil	if (child == 0) {
70771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
70781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
70791.1Skamil
70801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70821.1Skamil
70831.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
70841.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
70851.1Skamil
70861.13Schristos		DPRINTF("Before making context for new lwp in child\n");
70871.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
70881.1Skamil
70891.13Schristos		DPRINTF("Before creating new in child\n");
70901.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
70911.1Skamil
70921.1Skamil		while (go == 0)
70931.1Skamil			continue;
70941.1Skamil
70951.1Skamil		raise(SIGINT);
70961.1Skamil
70971.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
70981.1Skamil
70991.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
71001.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
71011.1Skamil
71021.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
71031.1Skamil		    "are the same\n", lid, the_lwp_id);
71041.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
71051.1Skamil
71061.13Schristos		DPRINTF("Before exiting of the child process\n");
71071.1Skamil		_exit(exitval);
71081.1Skamil	}
71091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
71101.1Skamil
71111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
71121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71131.1Skamil
71141.1Skamil	validate_status_stopped(status, sigval);
71151.1Skamil
71161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
71171.1Skamil	    "without signal to be sent\n");
71181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
71191.1Skamil
71201.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
71211.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
71221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71231.1Skamil
71241.1Skamil	validate_status_stopped(status, SIGTRAP);
71251.1Skamil
71261.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
71271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
71281.1Skamil
71291.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
71301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
71311.1Skamil
71321.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
71331.1Skamil	    child, getpid());
71341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
71351.1Skamil
71361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
71371.1Skamil	    "without signal to be sent\n");
71381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
71391.1Skamil
71401.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
71411.1Skamil	    "SIGINT\n", TWAIT_FNAME);
71421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71431.1Skamil
71441.1Skamil	validate_status_stopped(status, SIGINT);
71451.1Skamil
71461.1Skamil	pl.pl_lwpid = 0;
71471.1Skamil
71481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
71491.1Skamil	while (pl.pl_lwpid != 0) {
71501.1Skamil
71511.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
71521.1Skamil		switch (pl.pl_lwpid) {
71531.1Skamil		case 1:
71541.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
71551.1Skamil			break;
71561.1Skamil		case 2:
71571.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
71581.1Skamil			break;
71591.1Skamil		}
71601.1Skamil	}
71611.1Skamil
71621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
71631.1Skamil	    "without signal to be sent\n");
71641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
71651.1Skamil
71661.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
71671.1Skamil	    TWAIT_FNAME);
71681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71691.1Skamil
71701.1Skamil	validate_status_exited(status, exitval);
71711.1Skamil
71721.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
71731.1Skamil	    TWAIT_FNAME);
71741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
71751.1Skamil}
71761.1Skamil
71771.1SkamilATF_TC(suspend2);
71781.1SkamilATF_TC_HEAD(suspend2, tc)
71791.1Skamil{
71801.1Skamil	atf_tc_set_md_var(tc, "descr",
71811.1Skamil	    "Verify that the while the only thread within a process is "
71821.1Skamil	    "suspended, the whole process cannot be unstopped");
71831.1Skamil}
71841.1Skamil
71851.1SkamilATF_TC_BODY(suspend2, tc)
71861.1Skamil{
71871.1Skamil	const int exitval = 5;
71881.1Skamil	const int sigval = SIGSTOP;
71891.1Skamil	pid_t child, wpid;
71901.1Skamil#if defined(TWAIT_HAVE_STATUS)
71911.1Skamil	int status;
71921.1Skamil#endif
71931.1Skamil	struct ptrace_siginfo psi;
71941.1Skamil
71951.17Skamil	// Feature pending for refactoring
71961.17Skamil	atf_tc_expect_fail("PR kern/51995");
71971.17Skamil
71981.16Skamil	// Hangs with qemu
71991.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
72001.16Skamil
72011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
72021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
72031.1Skamil	if (child == 0) {
72041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
72051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
72061.1Skamil
72071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
72081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
72091.1Skamil
72101.13Schristos		DPRINTF("Before exiting of the child process\n");
72111.1Skamil		_exit(exitval);
72121.1Skamil	}
72131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
72141.1Skamil
72151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
72161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
72171.1Skamil
72181.1Skamil	validate_status_stopped(status, sigval);
72191.1Skamil
72201.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
72211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
72221.1Skamil
72231.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
72241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
72251.1Skamil
72261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
72271.1Skamil	    "without signal to be sent\n");
72281.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
72291.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
72301.1Skamil
72311.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
72321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
72331.1Skamil
72341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
72351.1Skamil	    "without signal to be sent\n");
72361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
72371.1Skamil
72381.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
72391.1Skamil	    TWAIT_FNAME);
72401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
72411.1Skamil
72421.1Skamil	validate_status_exited(status, exitval);
72431.1Skamil
72441.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
72451.1Skamil	    TWAIT_FNAME);
72461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
72471.1Skamil}
72481.1Skamil
72491.1SkamilATF_TC(resume1);
72501.1SkamilATF_TC_HEAD(resume1, tc)
72511.1Skamil{
72521.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
72531.1Skamil	atf_tc_set_md_var(tc, "descr",
72541.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
72551.1Skamil	    "resumed by the debugger");
72561.1Skamil}
72571.1Skamil
72581.1SkamilATF_TC_BODY(resume1, tc)
72591.1Skamil{
72601.1Skamil	struct msg_fds fds;
72611.1Skamil	const int exitval = 5;
72621.1Skamil	const int sigval = SIGSTOP;
72631.1Skamil	pid_t child, wpid;
72641.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
72651.1Skamil#if defined(TWAIT_HAVE_STATUS)
72661.1Skamil	int status;
72671.1Skamil#endif
72681.1Skamil	ucontext_t uc;
72691.1Skamil	lwpid_t lid;
72701.1Skamil	static const size_t ssize = 16*1024;
72711.1Skamil	void *stack;
72721.1Skamil	struct ptrace_lwpinfo pl;
72731.1Skamil	struct ptrace_siginfo psi;
72741.1Skamil
72751.17Skamil	// Feature pending for refactoring
72761.17Skamil	atf_tc_expect_fail("PR kern/51995");
72771.17Skamil
72781.15Schristos	// Hangs with qemu
72791.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
72801.1Skamil
72811.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
72821.1Skamil
72831.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
72841.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
72851.1Skamil	if (child == 0) {
72861.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
72871.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
72881.1Skamil
72891.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
72901.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
72911.1Skamil
72921.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
72931.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
72941.1Skamil
72951.13Schristos		DPRINTF("Before making context for new lwp in child\n");
72961.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
72971.1Skamil
72981.13Schristos		DPRINTF("Before creating new in child\n");
72991.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
73001.1Skamil
73011.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
73021.1Skamil
73031.1Skamil		raise(SIGINT);
73041.1Skamil
73051.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
73061.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
73071.1Skamil
73081.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
73091.1Skamil		    "are the same\n", lid, the_lwp_id);
73101.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
73111.1Skamil
73121.13Schristos		DPRINTF("Before exiting of the child process\n");
73131.1Skamil		_exit(exitval);
73141.1Skamil	}
73151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
73161.1Skamil
73171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
73181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73191.1Skamil
73201.1Skamil	validate_status_stopped(status, sigval);
73211.1Skamil
73221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
73231.1Skamil	    "without signal to be sent\n");
73241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
73251.1Skamil
73261.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
73271.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
73281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73291.1Skamil
73301.1Skamil	validate_status_stopped(status, SIGTRAP);
73311.1Skamil
73321.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
73331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
73341.1Skamil
73351.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
73361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
73371.1Skamil
73381.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
73391.1Skamil
73401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
73411.1Skamil	    "without signal to be sent\n");
73421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
73431.1Skamil
73441.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
73451.1Skamil	    "SIGINT\n", TWAIT_FNAME);
73461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73471.1Skamil
73481.1Skamil	validate_status_stopped(status, SIGINT);
73491.1Skamil
73501.1Skamil	pl.pl_lwpid = 0;
73511.1Skamil
73521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
73531.1Skamil	while (pl.pl_lwpid != 0) {
73541.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
73551.1Skamil		switch (pl.pl_lwpid) {
73561.1Skamil		case 1:
73571.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
73581.1Skamil			break;
73591.1Skamil		case 2:
73601.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
73611.1Skamil			break;
73621.1Skamil		}
73631.1Skamil	}
73641.1Skamil
73651.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
73661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
73671.1Skamil
73681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
73691.1Skamil	    "without signal to be sent\n");
73701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
73711.1Skamil
73721.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
73731.1Skamil	    TWAIT_FNAME);
73741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73751.1Skamil
73761.1Skamil	validate_status_exited(status, exitval);
73771.1Skamil
73781.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
73791.1Skamil	    TWAIT_FNAME);
73801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
73811.1Skamil
73821.1Skamil	msg_close(&fds);
73831.1Skamil
73841.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
73851.1Skamil	sleep(10);
73861.1Skamil}
73871.1Skamil
73881.1SkamilATF_TC(syscall1);
73891.1SkamilATF_TC_HEAD(syscall1, tc)
73901.1Skamil{
73911.1Skamil	atf_tc_set_md_var(tc, "descr",
73921.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
73931.1Skamil}
73941.1Skamil
73951.1SkamilATF_TC_BODY(syscall1, tc)
73961.1Skamil{
73971.1Skamil	const int exitval = 5;
73981.1Skamil	const int sigval = SIGSTOP;
73991.1Skamil	pid_t child, wpid;
74001.1Skamil#if defined(TWAIT_HAVE_STATUS)
74011.1Skamil	int status;
74021.1Skamil#endif
74031.1Skamil	struct ptrace_siginfo info;
74041.1Skamil	memset(&info, 0, sizeof(info));
74051.1Skamil
74061.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
74071.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
74081.1Skamil	if (child == 0) {
74091.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
74101.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
74111.1Skamil
74121.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
74131.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
74141.1Skamil
74151.1Skamil		syscall(SYS_getpid);
74161.1Skamil
74171.13Schristos		DPRINTF("Before exiting of the child process\n");
74181.1Skamil		_exit(exitval);
74191.1Skamil	}
74201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
74211.1Skamil
74221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74241.1Skamil
74251.1Skamil	validate_status_stopped(status, sigval);
74261.1Skamil
74271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
74281.1Skamil	    "without signal to be sent\n");
74291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
74301.1Skamil
74311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74331.1Skamil
74341.1Skamil	validate_status_stopped(status, SIGTRAP);
74351.1Skamil
74361.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
74371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
74381.1Skamil
74391.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
74401.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
74411.1Skamil
74421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
74431.1Skamil	    "without signal to be sent\n");
74441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
74451.1Skamil
74461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74481.1Skamil
74491.1Skamil	validate_status_stopped(status, SIGTRAP);
74501.1Skamil
74511.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
74521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
74531.1Skamil
74541.13Schristos	DPRINTF("Before checking siginfo_t\n");
74551.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
74561.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
74571.1Skamil
74581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
74591.1Skamil	    "without signal to be sent\n");
74601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
74611.1Skamil
74621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74641.1Skamil
74651.1Skamil	validate_status_exited(status, exitval);
74661.1Skamil
74671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
74691.1Skamil}
74701.1Skamil
74711.1SkamilATF_TC(syscallemu1);
74721.1SkamilATF_TC_HEAD(syscallemu1, tc)
74731.1Skamil{
74741.1Skamil	atf_tc_set_md_var(tc, "descr",
74751.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
74761.1Skamil}
74771.1Skamil
74781.1SkamilATF_TC_BODY(syscallemu1, tc)
74791.1Skamil{
74801.1Skamil	const int exitval = 5;
74811.1Skamil	const int sigval = SIGSTOP;
74821.1Skamil	pid_t child, wpid;
74831.1Skamil#if defined(TWAIT_HAVE_STATUS)
74841.1Skamil	int status;
74851.1Skamil#endif
74861.1Skamil
74871.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
74881.6Skamil	/* syscallemu does not work on sparc (32-bit) */
74891.6Skamil	atf_tc_expect_fail("PR kern/52166");
74901.6Skamil#endif
74911.6Skamil
74921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
74931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
74941.1Skamil	if (child == 0) {
74951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
74961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
74971.1Skamil
74981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
74991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
75001.1Skamil
75011.1Skamil		syscall(SYS_exit, 100);
75021.1Skamil
75031.13Schristos		DPRINTF("Before exiting of the child process\n");
75041.1Skamil		_exit(exitval);
75051.1Skamil	}
75061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
75071.1Skamil
75081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
75101.1Skamil
75111.1Skamil	validate_status_stopped(status, sigval);
75121.1Skamil
75131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
75141.1Skamil	    "without signal to be sent\n");
75151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
75161.1Skamil
75171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
75191.1Skamil
75201.1Skamil	validate_status_stopped(status, SIGTRAP);
75211.1Skamil
75221.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
75231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
75241.1Skamil
75251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
75261.1Skamil	    "without signal to be sent\n");
75271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
75281.1Skamil
75291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
75311.1Skamil
75321.1Skamil	validate_status_stopped(status, SIGTRAP);
75331.1Skamil
75341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
75351.1Skamil	    "without signal to be sent\n");
75361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
75371.1Skamil
75381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
75401.1Skamil
75411.1Skamil	validate_status_exited(status, exitval);
75421.1Skamil
75431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
75451.1Skamil}
75461.1Skamil
75471.1Skamil#include "t_ptrace_amd64_wait.h"
75481.1Skamil#include "t_ptrace_i386_wait.h"
75491.1Skamil#include "t_ptrace_x86_wait.h"
75501.1Skamil
75511.1SkamilATF_TP_ADD_TCS(tp)
75521.1Skamil{
75531.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
75541.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
75551.1Skamil	ATF_TP_ADD_TC(tp, traceme1);
75561.1Skamil	ATF_TP_ADD_TC(tp, traceme2);
75571.1Skamil	ATF_TP_ADD_TC(tp, traceme3);
75581.1Skamil	ATF_TP_ADD_TC(tp, traceme4);
75591.1Skamil
75601.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
75611.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
75621.1Skamil	ATF_TP_ADD_TC(tp, attach3);
75631.1Skamil	ATF_TP_ADD_TC(tp, attach4);
75641.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
75651.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
75661.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
75671.1Skamil
75681.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
75691.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
75701.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
75711.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
75721.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
75731.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
75741.1Skamil
75751.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork1);
75761.1Skamil	ATF_TP_ADD_TC(tp, fork2);
75771.1Skamil
75781.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork1);
75791.1Skamil	ATF_TP_ADD_TC(tp, vfork2);
75801.1Skamil
75811.1Skamil	ATF_TP_ADD_TC(tp, vforkdone1);
75821.1Skamil	ATF_TP_ADD_TC(tp, vforkdone2);
75831.1Skamil
75841.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
75851.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
75861.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
75871.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
75881.1Skamil
75891.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
75901.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
75911.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
75921.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
75931.1Skamil
75941.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
75951.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
75961.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
75971.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
75981.1Skamil
75991.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
76001.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
76011.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
76021.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
76031.1Skamil
76041.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
76051.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
76061.1Skamil
76071.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
76081.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
76091.1Skamil
76101.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
76111.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
76121.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
76131.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
76141.1Skamil
76151.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
76161.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
76171.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
76181.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
76191.1Skamil
76201.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
76211.1Skamil
76221.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
76231.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
76241.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
76251.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
76261.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
76271.1Skamil
76281.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
76291.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
76301.1Skamil
76311.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
76321.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
76331.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
76341.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
76351.1Skamil
76361.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
76371.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
76381.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
76391.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
76401.2Skamil
76411.1Skamil	ATF_TP_ADD_TC(tp, kill1);
76421.1Skamil	ATF_TP_ADD_TC(tp, kill2);
76431.1Skamil
76441.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
76451.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
76461.1Skamil
76471.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
76481.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
76491.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
76501.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
76511.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
76521.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
76531.1Skamil
76541.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
76551.1Skamil
76561.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
76571.1Skamil
76581.1Skamil	ATF_TP_ADD_TC(tp, signal1);
76591.1Skamil	ATF_TP_ADD_TC(tp, signal2);
76601.1Skamil	ATF_TP_ADD_TC(tp, signal3);
76611.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
76621.1Skamil	ATF_TP_ADD_TC(tp, signal5);
76631.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
76641.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
76651.1Skamil	ATF_TP_ADD_TC(tp, signal8);
76661.1Skamil	ATF_TP_ADD_TC(tp, signal9);
76671.1Skamil	ATF_TP_ADD_TC(tp, signal10);
76681.1Skamil
76691.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
76701.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
76711.1Skamil
76721.1Skamil	ATF_TP_ADD_TC(tp, resume1);
76731.1Skamil
76741.1Skamil	ATF_TP_ADD_TC(tp, getsigmask1);
76751.1Skamil	ATF_TP_ADD_TC(tp, getsigmask2);
76761.1Skamil
76771.1Skamil	ATF_TP_ADD_TC(tp, setsigmask1);
76781.1Skamil	ATF_TP_ADD_TC(tp, setsigmask2);
76791.1Skamil	ATF_TP_ADD_TC(tp, setsigmask3);
76801.1Skamil	ATF_TP_ADD_TC(tp, setsigmask4);
76811.1Skamil	ATF_TP_ADD_TC(tp, setsigmask5);
76821.1Skamil	ATF_TP_ADD_TC(tp, setsigmask6);
76831.1Skamil
76841.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
76851.1Skamil
76861.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
76871.1Skamil
76881.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
76891.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
76901.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
76911.1Skamil
76921.1Skamil	return atf_no_error();
76931.1Skamil}
7694