t_ptrace_wait.c revision 1.26
11.26Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.26 2018/03/13 14:54:13 kamil Exp $	*/
21.1Skamil
31.1Skamil/*-
41.1Skamil * Copyright (c) 2016 The NetBSD Foundation, Inc.
51.1Skamil * All rights reserved.
61.1Skamil *
71.1Skamil * Redistribution and use in source and binary forms, with or without
81.1Skamil * modification, are permitted provided that the following conditions
91.1Skamil * are met:
101.1Skamil * 1. Redistributions of source code must retain the above copyright
111.1Skamil *    notice, this list of conditions and the following disclaimer.
121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright
131.1Skamil *    notice, this list of conditions and the following disclaimer in the
141.1Skamil *    documentation and/or other materials provided with the distribution.
151.1Skamil *
161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Skamil * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Skamil * POSSIBILITY OF SUCH DAMAGE.
271.1Skamil */
281.1Skamil
291.1Skamil#include <sys/cdefs.h>
301.26Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.26 2018/03/13 14:54:13 kamil Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/types.h>
341.1Skamil#include <sys/ptrace.h>
351.1Skamil#include <sys/resource.h>
361.1Skamil#include <sys/stat.h>
371.1Skamil#include <sys/syscall.h>
381.1Skamil#include <sys/sysctl.h>
391.1Skamil#include <sys/wait.h>
401.1Skamil#include <machine/reg.h>
411.1Skamil#include <elf.h>
421.1Skamil#include <err.h>
431.1Skamil#include <errno.h>
441.1Skamil#include <lwp.h>
451.1Skamil#include <sched.h>
461.1Skamil#include <signal.h>
471.1Skamil#include <stdint.h>
481.1Skamil#include <stdio.h>
491.1Skamil#include <stdlib.h>
501.1Skamil#include <strings.h>
511.26Skamil#include <time.h>
521.1Skamil#include <unistd.h>
531.1Skamil
541.1Skamil#include <atf-c.h>
551.1Skamil
561.1Skamil#include "h_macros.h"
571.1Skamil
581.1Skamil#include "t_ptrace_wait.h"
591.1Skamil#include "msg.h"
601.1Skamil
611.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
621.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
631.1Skamil
641.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
651.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
661.1Skamil
671.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
681.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
691.1Skamil
701.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
711.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
721.13Schristos
731.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
741.13Schristos    strerror(errno))
751.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
761.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
771.13Schristos
781.13Schristosstatic int debug = 0;
791.13Schristos
801.13Schristos#define DPRINTF(a, ...)	do  \
811.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
821.13Schristos    while (/*CONSTCOND*/0)
831.1Skamil
841.1Skamil
851.1SkamilATF_TC(traceme1);
861.1SkamilATF_TC_HEAD(traceme1, tc)
871.1Skamil{
881.1Skamil	atf_tc_set_md_var(tc, "descr",
891.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
901.1Skamil}
911.1Skamil
921.1SkamilATF_TC_BODY(traceme1, tc)
931.1Skamil{
941.1Skamil	const int exitval = 5;
951.1Skamil	const int sigval = SIGSTOP;
961.1Skamil	pid_t child, wpid;
971.1Skamil#if defined(TWAIT_HAVE_STATUS)
981.1Skamil	int status;
991.1Skamil#endif
1001.1Skamil
1011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1031.1Skamil	if (child == 0) {
1041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1061.1Skamil
1071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1091.1Skamil
1101.13Schristos		DPRINTF("Before exiting of the child process\n");
1111.1Skamil		_exit(exitval);
1121.1Skamil	}
1131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1141.1Skamil
1151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1171.1Skamil
1181.1Skamil	validate_status_stopped(status, sigval);
1191.1Skamil
1201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
1211.1Skamil	    "without signal to be sent\n");
1221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1231.1Skamil
1241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1261.1Skamil
1271.1Skamil	validate_status_exited(status, exitval);
1281.1Skamil
1291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1311.1Skamil}
1321.1Skamil
1331.1SkamilATF_TC(traceme2);
1341.1SkamilATF_TC_HEAD(traceme2, tc)
1351.1Skamil{
1361.1Skamil	atf_tc_set_md_var(tc, "descr",
1371.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
1381.1Skamil}
1391.1Skamil
1401.1Skamilstatic int traceme2_caught = 0;
1411.1Skamil
1421.1Skamilstatic void
1431.1Skamiltraceme2_sighandler(int sig)
1441.1Skamil{
1451.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
1461.1Skamil
1471.1Skamil	++traceme2_caught;
1481.1Skamil}
1491.1Skamil
1501.1SkamilATF_TC_BODY(traceme2, tc)
1511.1Skamil{
1521.1Skamil	const int exitval = 5;
1531.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT;
1541.1Skamil	pid_t child, wpid;
1551.1Skamil	struct sigaction sa;
1561.1Skamil#if defined(TWAIT_HAVE_STATUS)
1571.1Skamil	int status;
1581.1Skamil#endif
1591.1Skamil
1601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1621.1Skamil	if (child == 0) {
1631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1651.1Skamil
1661.1Skamil		sa.sa_handler = traceme2_sighandler;
1671.1Skamil		sa.sa_flags = SA_SIGINFO;
1681.1Skamil		sigemptyset(&sa.sa_mask);
1691.1Skamil
1701.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1711.1Skamil
1721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1741.1Skamil
1751.1Skamil		FORKEE_ASSERT_EQ(traceme2_caught, 1);
1761.1Skamil
1771.13Schristos		DPRINTF("Before exiting of the child process\n");
1781.1Skamil		_exit(exitval);
1791.1Skamil	}
1801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1811.1Skamil
1821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1841.1Skamil
1851.1Skamil	validate_status_stopped(status, sigval);
1861.1Skamil
1871.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
1881.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
1891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1901.1Skamil
1911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1931.1Skamil
1941.1Skamil	validate_status_exited(status, exitval);
1951.1Skamil
1961.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1981.1Skamil}
1991.1Skamil
2001.1SkamilATF_TC(traceme3);
2011.1SkamilATF_TC_HEAD(traceme3, tc)
2021.1Skamil{
2031.1Skamil	atf_tc_set_md_var(tc, "descr",
2041.1Skamil	    "Verify SIGSTOP followed by termination by a signal in a child");
2051.1Skamil}
2061.1Skamil
2071.1SkamilATF_TC_BODY(traceme3, tc)
2081.1Skamil{
2091.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
2101.1Skamil	pid_t child, wpid;
2111.1Skamil#if defined(TWAIT_HAVE_STATUS)
2121.1Skamil	int status;
2131.1Skamil#endif
2141.1Skamil
2151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2171.1Skamil	if (child == 0) {
2181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2201.1Skamil
2211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2231.1Skamil
2241.1Skamil		/* NOTREACHED */
2251.1Skamil		FORKEE_ASSERTX(0 &&
2261.1Skamil		    "Child should be terminated by a signal from its parent");
2271.1Skamil	}
2281.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2291.1Skamil
2301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2321.1Skamil
2331.1Skamil	validate_status_stopped(status, sigval);
2341.1Skamil
2351.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2361.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2381.1Skamil
2391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2411.1Skamil
2421.1Skamil	validate_status_signaled(status, sigsent, 0);
2431.1Skamil
2441.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2461.1Skamil}
2471.1Skamil
2481.1SkamilATF_TC(traceme4);
2491.1SkamilATF_TC_HEAD(traceme4, tc)
2501.1Skamil{
2511.1Skamil	atf_tc_set_md_var(tc, "descr",
2521.1Skamil	    "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child");
2531.1Skamil}
2541.1Skamil
2551.1SkamilATF_TC_BODY(traceme4, tc)
2561.1Skamil{
2571.1Skamil	const int exitval = 5;
2581.1Skamil	const int sigval = SIGSTOP, sigsent = SIGCONT;
2591.1Skamil	pid_t child, wpid;
2601.1Skamil#if defined(TWAIT_HAVE_STATUS)
2611.1Skamil	int status;
2621.1Skamil#endif
2631.1Skamil
2641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2661.1Skamil	if (child == 0) {
2671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2691.1Skamil
2701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2721.1Skamil
2731.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigsent));
2741.1Skamil		FORKEE_ASSERT(raise(sigsent) == 0);
2751.1Skamil
2761.13Schristos		DPRINTF("Before exiting of the child process\n");
2771.1Skamil		_exit(exitval);
2781.1Skamil	}
2791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),child);
2801.1Skamil
2811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2831.1Skamil
2841.1Skamil	validate_status_stopped(status, sigval);
2851.1Skamil
2861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2871.1Skamil	    "without signal to be sent\n");
2881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2891.1Skamil
2901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2921.1Skamil
2931.1Skamil	validate_status_stopped(status, sigsent);
2941.1Skamil
2951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2961.1Skamil	    "without signal to be sent\n");
2971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2981.1Skamil
2991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3011.1Skamil
3021.1Skamil	validate_status_exited(status, exitval);
3031.1Skamil
3041.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
3051.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3061.1Skamil}
3071.1Skamil
3081.1Skamil#if defined(TWAIT_HAVE_PID)
3091.1SkamilATF_TC(attach1);
3101.1SkamilATF_TC_HEAD(attach1, tc)
3111.1Skamil{
3121.1Skamil	atf_tc_set_md_var(tc, "descr",
3131.1Skamil	    "Assert that tracer sees process termination before the parent");
3141.1Skamil}
3151.1Skamil
3161.26Skamilstatic void
3171.26Skamilattach1_raw(bool raw)
3181.1Skamil{
3191.1Skamil	struct msg_fds parent_tracee, parent_tracer;
3201.1Skamil	const int exitval_tracee = 5;
3211.1Skamil	const int exitval_tracer = 10;
3221.1Skamil	pid_t tracee, tracer, wpid;
3231.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3241.1Skamil#if defined(TWAIT_HAVE_STATUS)
3251.1Skamil	int status;
3261.1Skamil#endif
3271.1Skamil
3281.13Schristos	DPRINTF("Spawn tracee\n");
3291.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3301.1Skamil	tracee = atf_utils_fork();
3311.1Skamil	if (tracee == 0) {
3321.1Skamil		// Wait for parent to let us exit
3331.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3341.1Skamil		_exit(exitval_tracee);
3351.1Skamil	}
3361.1Skamil
3371.13Schristos	DPRINTF("Spawn debugger\n");
3381.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3391.1Skamil	tracer = atf_utils_fork();
3401.1Skamil	if (tracer == 0) {
3411.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3421.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3431.1Skamil
3441.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3451.1Skamil		FORKEE_REQUIRE_SUCCESS(
3461.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3471.1Skamil
3481.1Skamil		forkee_status_stopped(status, SIGSTOP);
3491.1Skamil
3501.1Skamil		/* Resume tracee with PT_CONTINUE */
3511.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3521.1Skamil
3531.1Skamil		/* Inform parent that tracer has attached to tracee */
3541.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3551.1Skamil
3561.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3571.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3581.1Skamil
3591.1Skamil		/* Wait for tracee and assert that it exited */
3601.1Skamil		FORKEE_REQUIRE_SUCCESS(
3611.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3621.1Skamil
3631.1Skamil		forkee_status_exited(status, exitval_tracee);
3641.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3651.1Skamil
3661.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3671.1Skamil		_exit(exitval_tracer);
3681.1Skamil	}
3691.1Skamil
3701.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3711.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3721.1Skamil
3731.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3741.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3751.1Skamil
3761.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3771.26Skamil	if (raw)
3781.26Skamil		await_zombie_raw(tracee, 0);
3791.26Skamil	else
3801.26Skamil		await_zombie(tracee);
3811.1Skamil
3821.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3831.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3841.1Skamil	    TWAIT_FNAME);
3851.1Skamil	TWAIT_REQUIRE_SUCCESS(
3861.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
3871.1Skamil
3881.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
3891.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
3901.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3911.1Skamil	    TWAIT_FNAME);
3921.1Skamil
3931.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
3941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3951.1Skamil	    tracer);
3961.1Skamil
3971.1Skamil	validate_status_exited(status, exitval_tracer);
3981.1Skamil
3991.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4001.1Skamil	    TWAIT_FNAME);
4011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4021.1Skamil	    tracee);
4031.1Skamil
4041.1Skamil	validate_status_exited(status, exitval_tracee);
4051.1Skamil
4061.1Skamil	msg_close(&parent_tracer);
4071.1Skamil	msg_close(&parent_tracee);
4081.1Skamil}
4091.26Skamil
4101.26SkamilATF_TC_BODY(attach1, tc)
4111.26Skamil{
4121.26Skamil
4131.26Skamil	/* Reuse this test with race1 */
4141.26Skamil	attach1_raw(false);
4151.26Skamil}
4161.26Skamil
4171.1Skamil#endif
4181.1Skamil
4191.1Skamil#if defined(TWAIT_HAVE_PID)
4201.1SkamilATF_TC(attach2);
4211.1SkamilATF_TC_HEAD(attach2, tc)
4221.1Skamil{
4231.1Skamil	atf_tc_set_md_var(tc, "descr",
4241.1Skamil	    "Assert that any tracer sees process termination before its "
4251.1Skamil	    "parent");
4261.1Skamil}
4271.1Skamil
4281.1SkamilATF_TC_BODY(attach2, tc)
4291.1Skamil{
4301.1Skamil	struct msg_fds parent_tracer, parent_tracee;
4311.1Skamil	const int exitval_tracee = 5;
4321.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
4331.1Skamil	pid_t tracee, tracer, wpid;
4341.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4351.1Skamil#if defined(TWAIT_HAVE_STATUS)
4361.1Skamil	int status;
4371.1Skamil#endif
4381.1Skamil
4391.13Schristos	DPRINTF("Spawn tracee\n");
4401.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4411.1Skamil	tracee = atf_utils_fork();
4421.1Skamil	if (tracee == 0) {
4431.1Skamil		/* Wait for message from the parent */
4441.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4451.1Skamil		_exit(exitval_tracee);
4461.1Skamil	}
4471.1Skamil
4481.13Schristos	DPRINTF("Spawn debugger\n");
4491.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4501.1Skamil	tracer = atf_utils_fork();
4511.1Skamil	if (tracer == 0) {
4521.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4531.1Skamil		tracer = atf_utils_fork();
4541.1Skamil		if (tracer != 0)
4551.1Skamil			_exit(exitval_tracer1);
4561.1Skamil
4571.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4581.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4591.1Skamil
4601.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4611.1Skamil		FORKEE_REQUIRE_SUCCESS(
4621.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4631.1Skamil
4641.1Skamil		forkee_status_stopped(status, SIGSTOP);
4651.1Skamil
4661.1Skamil		/* Resume tracee with PT_CONTINUE */
4671.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4681.1Skamil
4691.1Skamil		/* Inform parent that tracer has attached to tracee */
4701.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4711.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4721.1Skamil
4731.1Skamil		/* Wait for tracee and assert that it exited */
4741.1Skamil		FORKEE_REQUIRE_SUCCESS(
4751.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4761.1Skamil
4771.1Skamil		forkee_status_exited(status, exitval_tracee);
4781.1Skamil
4791.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4801.1Skamil		_exit(exitval_tracer2);
4811.1Skamil	}
4821.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4831.1Skamil	    "%s()\n", TWAIT_FNAME);
4841.1Skamil	TWAIT_REQUIRE_SUCCESS(
4851.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4861.1Skamil
4871.1Skamil	validate_status_exited(status, exitval_tracer1);
4881.1Skamil
4891.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4901.1Skamil	    TWAIT_FNAME);
4911.1Skamil	TWAIT_REQUIRE_SUCCESS(
4921.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4931.1Skamil
4941.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4951.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
4961.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4971.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
4981.1Skamil
4991.13Schristos	DPRINTF("Detect that tracee is zombie\n");
5001.1Skamil	await_zombie(tracee);
5011.1Skamil
5021.13Schristos	DPRINTF("Assert that there is no status about tracee - "
5031.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
5041.1Skamil	TWAIT_REQUIRE_SUCCESS(
5051.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
5061.1Skamil
5071.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
5081.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
5091.1Skamil
5101.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5111.1Skamil	    TWAIT_FNAME);
5121.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
5131.1Skamil	    tracee);
5141.1Skamil
5151.1Skamil	validate_status_exited(status, exitval_tracee);
5161.1Skamil
5171.1Skamil	msg_close(&parent_tracer);
5181.1Skamil	msg_close(&parent_tracee);
5191.1Skamil}
5201.1Skamil#endif
5211.1Skamil
5221.1SkamilATF_TC(attach3);
5231.1SkamilATF_TC_HEAD(attach3, tc)
5241.1Skamil{
5251.1Skamil	atf_tc_set_md_var(tc, "descr",
5261.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
5271.1Skamil}
5281.1Skamil
5291.1SkamilATF_TC_BODY(attach3, tc)
5301.1Skamil{
5311.1Skamil	struct msg_fds parent_tracee;
5321.1Skamil	const int exitval_tracee = 5;
5331.1Skamil	pid_t tracee, wpid;
5341.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5351.1Skamil#if defined(TWAIT_HAVE_STATUS)
5361.1Skamil	int status;
5371.1Skamil#endif
5381.1Skamil
5391.13Schristos	DPRINTF("Spawn tracee\n");
5401.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5411.1Skamil	tracee = atf_utils_fork();
5421.1Skamil	if (tracee == 0) {
5431.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5441.13Schristos		DPRINTF("Parent should now attach to tracee\n");
5451.1Skamil
5461.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5471.1Skamil		/* Wait for message from the parent */
5481.1Skamil		_exit(exitval_tracee);
5491.1Skamil	}
5501.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5511.1Skamil
5521.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5541.1Skamil
5551.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5561.1Skamil	    TWAIT_FNAME);
5571.1Skamil	TWAIT_REQUIRE_SUCCESS(
5581.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5591.1Skamil
5601.1Skamil	validate_status_stopped(status, SIGSTOP);
5611.1Skamil
5621.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5641.1Skamil
5651.13Schristos	DPRINTF("Let the tracee exit now\n");
5661.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5671.1Skamil
5681.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5691.1Skamil	TWAIT_REQUIRE_SUCCESS(
5701.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5711.1Skamil
5721.1Skamil	validate_status_exited(status, exitval_tracee);
5731.1Skamil
5741.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5761.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5771.1Skamil
5781.1Skamil	msg_close(&parent_tracee);
5791.1Skamil}
5801.1Skamil
5811.1SkamilATF_TC(attach4);
5821.1SkamilATF_TC_HEAD(attach4, tc)
5831.1Skamil{
5841.1Skamil	atf_tc_set_md_var(tc, "descr",
5851.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
5861.1Skamil}
5871.1Skamil
5881.1SkamilATF_TC_BODY(attach4, tc)
5891.1Skamil{
5901.1Skamil	struct msg_fds parent_tracee;
5911.1Skamil	const int exitval_tracer = 5;
5921.1Skamil	pid_t tracer, wpid;
5931.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5941.1Skamil#if defined(TWAIT_HAVE_STATUS)
5951.1Skamil	int status;
5961.1Skamil#endif
5971.1Skamil
5981.13Schristos	DPRINTF("Spawn tracer\n");
5991.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6001.1Skamil	tracer = atf_utils_fork();
6011.1Skamil	if (tracer == 0) {
6021.1Skamil
6031.1Skamil		/* Wait for message from the parent */
6041.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
6051.1Skamil
6061.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
6071.1Skamil		    getppid());
6081.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
6091.1Skamil
6101.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
6111.1Skamil		    TWAIT_FNAME);
6121.1Skamil		FORKEE_REQUIRE_SUCCESS(
6131.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
6141.1Skamil
6151.1Skamil		forkee_status_stopped(status, SIGSTOP);
6161.1Skamil
6171.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
6181.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
6191.1Skamil		    != -1);
6201.1Skamil
6211.1Skamil		/* Tell parent we are ready */
6221.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
6231.1Skamil
6241.1Skamil		_exit(exitval_tracer);
6251.1Skamil	}
6261.1Skamil
6271.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
6281.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6291.13Schristos	DPRINTF("Allow the tracer to exit now\n");
6301.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
6311.1Skamil
6321.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
6331.1Skamil	TWAIT_REQUIRE_SUCCESS(
6341.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6351.1Skamil
6361.1Skamil	validate_status_exited(status, exitval_tracer);
6371.1Skamil
6381.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
6391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6401.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
6411.1Skamil
6421.1Skamil	msg_close(&parent_tracee);
6431.1Skamil}
6441.1Skamil
6451.1Skamil#if defined(TWAIT_HAVE_PID)
6461.1SkamilATF_TC(attach5);
6471.1SkamilATF_TC_HEAD(attach5, tc)
6481.1Skamil{
6491.1Skamil	atf_tc_set_md_var(tc, "descr",
6501.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6511.1Skamil	    "(check getppid(2))");
6521.1Skamil}
6531.1Skamil
6541.1SkamilATF_TC_BODY(attach5, tc)
6551.1Skamil{
6561.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6571.1Skamil	const int exitval_tracee = 5;
6581.1Skamil	const int exitval_tracer = 10;
6591.1Skamil	pid_t parent, tracee, tracer, wpid;
6601.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6611.1Skamil#if defined(TWAIT_HAVE_STATUS)
6621.1Skamil	int status;
6631.1Skamil#endif
6641.1Skamil
6651.13Schristos	DPRINTF("Spawn tracee\n");
6661.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6671.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6681.1Skamil	tracee = atf_utils_fork();
6691.1Skamil	if (tracee == 0) {
6701.1Skamil		parent = getppid();
6711.1Skamil
6721.1Skamil		/* Emit message to the parent */
6731.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6741.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6751.1Skamil
6761.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6771.1Skamil
6781.1Skamil		_exit(exitval_tracee);
6791.1Skamil	}
6801.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6811.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6821.1Skamil
6831.13Schristos	DPRINTF("Spawn debugger\n");
6841.1Skamil	tracer = atf_utils_fork();
6851.1Skamil	if (tracer == 0) {
6861.1Skamil		/* No IPC to communicate with the child */
6871.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6881.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6891.1Skamil
6901.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6911.1Skamil		FORKEE_REQUIRE_SUCCESS(
6921.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6931.1Skamil
6941.1Skamil		forkee_status_stopped(status, SIGSTOP);
6951.1Skamil
6961.1Skamil		/* Resume tracee with PT_CONTINUE */
6971.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6981.1Skamil
6991.1Skamil		/* Inform parent that tracer has attached to tracee */
7001.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
7011.1Skamil
7021.1Skamil		/* Wait for parent to tell use that tracee should have exited */
7031.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
7041.1Skamil
7051.1Skamil		/* Wait for tracee and assert that it exited */
7061.1Skamil		FORKEE_REQUIRE_SUCCESS(
7071.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7081.1Skamil
7091.1Skamil		forkee_status_exited(status, exitval_tracee);
7101.1Skamil
7111.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7121.1Skamil		_exit(exitval_tracer);
7131.1Skamil	}
7141.1Skamil
7151.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7161.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
7171.1Skamil
7181.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7191.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
7201.1Skamil
7211.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7221.1Skamil	await_zombie(tracee);
7231.1Skamil
7241.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7251.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7261.1Skamil	TWAIT_REQUIRE_SUCCESS(
7271.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7281.1Skamil
7291.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7301.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
7311.1Skamil
7321.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7341.1Skamil	    tracer);
7351.1Skamil
7361.1Skamil	validate_status_exited(status, exitval_tracer);
7371.1Skamil
7381.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7391.1Skamil	    TWAIT_FNAME);
7401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7411.1Skamil	    tracee);
7421.1Skamil
7431.1Skamil	validate_status_exited(status, exitval_tracee);
7441.1Skamil
7451.1Skamil	msg_close(&parent_tracer);
7461.1Skamil	msg_close(&parent_tracee);
7471.1Skamil}
7481.1Skamil#endif
7491.1Skamil
7501.1Skamil#if defined(TWAIT_HAVE_PID)
7511.1SkamilATF_TC(attach6);
7521.1SkamilATF_TC_HEAD(attach6, tc)
7531.1Skamil{
7541.1Skamil	atf_tc_set_md_var(tc, "descr",
7551.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7561.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7571.1Skamil}
7581.1Skamil
7591.1SkamilATF_TC_BODY(attach6, tc)
7601.1Skamil{
7611.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7621.1Skamil	const int exitval_tracee = 5;
7631.1Skamil	const int exitval_tracer = 10;
7641.1Skamil	pid_t parent, tracee, tracer, wpid;
7651.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7661.1Skamil#if defined(TWAIT_HAVE_STATUS)
7671.1Skamil	int status;
7681.1Skamil#endif
7691.1Skamil	int name[CTL_MAXNAME];
7701.1Skamil	struct kinfo_proc2 kp;
7711.1Skamil	size_t len = sizeof(kp);
7721.1Skamil	unsigned int namelen;
7731.1Skamil
7741.13Schristos	DPRINTF("Spawn tracee\n");
7751.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7761.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7771.1Skamil	tracee = atf_utils_fork();
7781.1Skamil	if (tracee == 0) {
7791.1Skamil		parent = getppid();
7801.1Skamil
7811.1Skamil		/* Emit message to the parent */
7821.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7831.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7841.1Skamil
7851.1Skamil		namelen = 0;
7861.1Skamil		name[namelen++] = CTL_KERN;
7871.1Skamil		name[namelen++] = KERN_PROC2;
7881.1Skamil		name[namelen++] = KERN_PROC_PID;
7891.1Skamil		name[namelen++] = getpid();
7901.1Skamil		name[namelen++] = len;
7911.1Skamil		name[namelen++] = 1;
7921.1Skamil
7931.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
7941.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
7951.1Skamil
7961.1Skamil		_exit(exitval_tracee);
7971.1Skamil	}
7981.1Skamil
7991.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
8001.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
8011.1Skamil
8021.13Schristos	DPRINTF("Spawn debugger\n");
8031.1Skamil	tracer = atf_utils_fork();
8041.1Skamil	if (tracer == 0) {
8051.1Skamil		/* No IPC to communicate with the child */
8061.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8071.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8081.1Skamil
8091.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8101.1Skamil		FORKEE_REQUIRE_SUCCESS(
8111.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8121.1Skamil
8131.1Skamil		forkee_status_stopped(status, SIGSTOP);
8141.1Skamil
8151.1Skamil		/* Resume tracee with PT_CONTINUE */
8161.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8171.1Skamil
8181.1Skamil		/* Inform parent that tracer has attached to tracee */
8191.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8201.1Skamil
8211.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8221.1Skamil
8231.1Skamil		/* Wait for tracee and assert that it exited */
8241.1Skamil		FORKEE_REQUIRE_SUCCESS(
8251.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8261.1Skamil
8271.1Skamil		forkee_status_exited(status, exitval_tracee);
8281.1Skamil
8291.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8301.1Skamil		_exit(exitval_tracer);
8311.1Skamil	}
8321.1Skamil
8331.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8341.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8351.1Skamil
8361.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8371.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8381.1Skamil
8391.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8401.1Skamil	await_zombie(tracee);
8411.1Skamil
8421.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8431.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8441.1Skamil	TWAIT_REQUIRE_SUCCESS(
8451.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8461.1Skamil
8471.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8481.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8491.1Skamil
8501.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8511.1Skamil	    TWAIT_FNAME);
8521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8531.1Skamil	    tracer);
8541.1Skamil
8551.1Skamil	validate_status_exited(status, exitval_tracer);
8561.1Skamil
8571.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8581.1Skamil	    TWAIT_FNAME);
8591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8601.1Skamil	    tracee);
8611.1Skamil
8621.1Skamil	validate_status_exited(status, exitval_tracee);
8631.1Skamil
8641.1Skamil	msg_close(&parent_tracee);
8651.1Skamil	msg_close(&parent_tracer);
8661.1Skamil}
8671.1Skamil#endif
8681.1Skamil
8691.1Skamil#if defined(TWAIT_HAVE_PID)
8701.1SkamilATF_TC(attach7);
8711.1SkamilATF_TC_HEAD(attach7, tc)
8721.1Skamil{
8731.1Skamil	atf_tc_set_md_var(tc, "descr",
8741.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8751.1Skamil	    "(check /proc/curproc/status 3rd column)");
8761.1Skamil}
8771.1Skamil
8781.1SkamilATF_TC_BODY(attach7, tc)
8791.1Skamil{
8801.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8811.1Skamil	int rv;
8821.1Skamil	const int exitval_tracee = 5;
8831.1Skamil	const int exitval_tracer = 10;
8841.1Skamil	pid_t parent, tracee, tracer, wpid;
8851.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8861.1Skamil#if defined(TWAIT_HAVE_STATUS)
8871.1Skamil	int status;
8881.1Skamil#endif
8891.1Skamil	FILE *fp;
8901.1Skamil	struct stat st;
8911.1Skamil	const char *fname = "/proc/curproc/status";
8921.1Skamil	char s_executable[MAXPATHLEN];
8931.1Skamil	int s_pid, s_ppid;
8941.1Skamil	/*
8951.1Skamil	 * Format:
8961.1Skamil	 *  EXECUTABLE PID PPID ...
8971.1Skamil	 */
8981.1Skamil
8991.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
9001.1Skamil	if (rv != 0) {
9011.1Skamil		atf_tc_skip("/proc/curproc/status not found");
9021.1Skamil	}
9031.1Skamil
9041.13Schristos	DPRINTF("Spawn tracee\n");
9051.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9061.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
9071.1Skamil	tracee = atf_utils_fork();
9081.1Skamil	if (tracee == 0) {
9091.1Skamil		parent = getppid();
9101.1Skamil
9111.1Skamil		// Wait for parent to let us exit
9121.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
9131.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
9141.1Skamil
9151.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
9161.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
9171.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
9181.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
9191.1Skamil
9201.1Skamil		_exit(exitval_tracee);
9211.1Skamil	}
9221.1Skamil
9231.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9241.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
9251.1Skamil
9261.13Schristos	DPRINTF("Spawn debugger\n");
9271.1Skamil	tracer = atf_utils_fork();
9281.1Skamil	if (tracer == 0) {
9291.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9301.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9311.1Skamil
9321.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9331.1Skamil		FORKEE_REQUIRE_SUCCESS(
9341.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9351.1Skamil
9361.1Skamil		forkee_status_stopped(status, SIGSTOP);
9371.1Skamil
9381.1Skamil		/* Resume tracee with PT_CONTINUE */
9391.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9401.1Skamil
9411.1Skamil		/* Inform parent that tracer has attached to tracee */
9421.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9431.1Skamil
9441.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9451.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9461.1Skamil
9471.1Skamil		/* Wait for tracee and assert that it exited */
9481.1Skamil		FORKEE_REQUIRE_SUCCESS(
9491.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9501.1Skamil
9511.1Skamil		forkee_status_exited(status, exitval_tracee);
9521.1Skamil
9531.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9541.1Skamil		_exit(exitval_tracer);
9551.1Skamil	}
9561.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9571.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9581.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9591.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9601.1Skamil
9611.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9621.1Skamil	await_zombie(tracee);
9631.1Skamil
9641.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9651.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9661.1Skamil	TWAIT_REQUIRE_SUCCESS(
9671.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9681.1Skamil
9691.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9701.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9711.1Skamil
9721.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9731.1Skamil	    TWAIT_FNAME);
9741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9751.1Skamil	    tracer);
9761.1Skamil
9771.1Skamil	validate_status_exited(status, exitval_tracer);
9781.1Skamil
9791.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9801.1Skamil	    TWAIT_FNAME);
9811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9821.1Skamil	    tracee);
9831.1Skamil
9841.1Skamil	validate_status_exited(status, exitval_tracee);
9851.1Skamil
9861.1Skamil	msg_close(&parent_tracee);
9871.1Skamil	msg_close(&parent_tracer);
9881.1Skamil}
9891.1Skamil#endif
9901.1Skamil
9911.1SkamilATF_TC(eventmask1);
9921.1SkamilATF_TC_HEAD(eventmask1, tc)
9931.1Skamil{
9941.1Skamil	atf_tc_set_md_var(tc, "descr",
9951.1Skamil	    "Verify that empty EVENT_MASK is preserved");
9961.1Skamil}
9971.1Skamil
9981.1SkamilATF_TC_BODY(eventmask1, tc)
9991.1Skamil{
10001.1Skamil	const int exitval = 5;
10011.1Skamil	const int sigval = SIGSTOP;
10021.1Skamil	pid_t child, wpid;
10031.1Skamil#if defined(TWAIT_HAVE_STATUS)
10041.1Skamil	int status;
10051.1Skamil#endif
10061.1Skamil	ptrace_event_t set_event, get_event;
10071.1Skamil	const int len = sizeof(ptrace_event_t);
10081.1Skamil
10091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10111.1Skamil	if (child == 0) {
10121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10141.1Skamil
10151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10171.1Skamil
10181.13Schristos		DPRINTF("Before exiting of the child process\n");
10191.1Skamil		_exit(exitval);
10201.1Skamil	}
10211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10221.1Skamil
10231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10251.1Skamil
10261.1Skamil	validate_status_stopped(status, sigval);
10271.1Skamil
10281.1Skamil	set_event.pe_set_event = 0;
10291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10311.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10321.1Skamil
10331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10341.1Skamil	    "without signal to be sent\n");
10351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10361.1Skamil
10371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10391.1Skamil
10401.1Skamil	validate_status_exited(status, exitval);
10411.1Skamil
10421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10441.1Skamil}
10451.1Skamil
10461.1SkamilATF_TC(eventmask2);
10471.1SkamilATF_TC_HEAD(eventmask2, tc)
10481.1Skamil{
10491.1Skamil	atf_tc_set_md_var(tc, "descr",
10501.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10511.1Skamil}
10521.1Skamil
10531.1SkamilATF_TC_BODY(eventmask2, tc)
10541.1Skamil{
10551.1Skamil	const int exitval = 5;
10561.1Skamil	const int sigval = SIGSTOP;
10571.1Skamil	pid_t child, wpid;
10581.1Skamil#if defined(TWAIT_HAVE_STATUS)
10591.1Skamil	int status;
10601.1Skamil#endif
10611.1Skamil	ptrace_event_t set_event, get_event;
10621.1Skamil	const int len = sizeof(ptrace_event_t);
10631.1Skamil
10641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10661.1Skamil	if (child == 0) {
10671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10691.1Skamil
10701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10721.1Skamil
10731.13Schristos		DPRINTF("Before exiting of the child process\n");
10741.1Skamil		_exit(exitval);
10751.1Skamil	}
10761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10771.1Skamil
10781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10801.1Skamil
10811.1Skamil	validate_status_stopped(status, sigval);
10821.1Skamil
10831.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10861.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10871.1Skamil
10881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10891.1Skamil	    "without signal to be sent\n");
10901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10911.1Skamil
10921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10941.1Skamil
10951.1Skamil	validate_status_exited(status, exitval);
10961.1Skamil
10971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10991.1Skamil}
11001.1Skamil
11011.1SkamilATF_TC(eventmask3);
11021.1SkamilATF_TC_HEAD(eventmask3, tc)
11031.1Skamil{
11041.1Skamil	atf_tc_set_md_var(tc, "descr",
11051.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
11061.1Skamil}
11071.1Skamil
11081.1SkamilATF_TC_BODY(eventmask3, tc)
11091.1Skamil{
11101.1Skamil	const int exitval = 5;
11111.1Skamil	const int sigval = SIGSTOP;
11121.1Skamil	pid_t child, wpid;
11131.1Skamil#if defined(TWAIT_HAVE_STATUS)
11141.1Skamil	int status;
11151.1Skamil#endif
11161.1Skamil	ptrace_event_t set_event, get_event;
11171.1Skamil	const int len = sizeof(ptrace_event_t);
11181.1Skamil
11191.14Schristos	atf_tc_expect_fail("PR kern/51630");
11201.14Schristos
11211.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11221.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11231.1Skamil	if (child == 0) {
11241.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11251.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11261.1Skamil
11271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11291.1Skamil
11301.13Schristos		DPRINTF("Before exiting of the child process\n");
11311.1Skamil		_exit(exitval);
11321.1Skamil	}
11331.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11341.1Skamil
11351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11371.1Skamil
11381.1Skamil	validate_status_stopped(status, sigval);
11391.1Skamil
11401.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
11411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
11421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11431.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11441.1Skamil
11451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11461.1Skamil	    "without signal to be sent\n");
11471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11481.1Skamil
11491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11511.1Skamil
11521.1Skamil	validate_status_exited(status, exitval);
11531.1Skamil
11541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11561.1Skamil}
11571.1Skamil
11581.1SkamilATF_TC(eventmask4);
11591.1SkamilATF_TC_HEAD(eventmask4, tc)
11601.1Skamil{
11611.1Skamil	atf_tc_set_md_var(tc, "descr",
11621.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11631.1Skamil}
11641.1Skamil
11651.1SkamilATF_TC_BODY(eventmask4, tc)
11661.1Skamil{
11671.1Skamil	const int exitval = 5;
11681.1Skamil	const int sigval = SIGSTOP;
11691.1Skamil	pid_t child, wpid;
11701.1Skamil#if defined(TWAIT_HAVE_STATUS)
11711.1Skamil	int status;
11721.1Skamil#endif
11731.1Skamil	ptrace_event_t set_event, get_event;
11741.1Skamil	const int len = sizeof(ptrace_event_t);
11751.1Skamil
11761.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11771.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11781.1Skamil	if (child == 0) {
11791.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11801.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11811.1Skamil
11821.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11831.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11841.1Skamil
11851.13Schristos		DPRINTF("Before exiting of the child process\n");
11861.1Skamil		_exit(exitval);
11871.1Skamil	}
11881.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11891.1Skamil
11901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11921.1Skamil
11931.1Skamil	validate_status_stopped(status, sigval);
11941.1Skamil
11951.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
11961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11981.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11991.1Skamil
12001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12011.1Skamil	    "without signal to be sent\n");
12021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12031.1Skamil
12041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12061.1Skamil
12071.1Skamil	validate_status_exited(status, exitval);
12081.1Skamil
12091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12111.1Skamil}
12121.1Skamil
12131.1SkamilATF_TC(eventmask5);
12141.1SkamilATF_TC_HEAD(eventmask5, tc)
12151.1Skamil{
12161.1Skamil	atf_tc_set_md_var(tc, "descr",
12171.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
12181.1Skamil}
12191.1Skamil
12201.1SkamilATF_TC_BODY(eventmask5, tc)
12211.1Skamil{
12221.1Skamil	const int exitval = 5;
12231.1Skamil	const int sigval = SIGSTOP;
12241.1Skamil	pid_t child, wpid;
12251.1Skamil#if defined(TWAIT_HAVE_STATUS)
12261.1Skamil	int status;
12271.1Skamil#endif
12281.1Skamil	ptrace_event_t set_event, get_event;
12291.1Skamil	const int len = sizeof(ptrace_event_t);
12301.1Skamil
12311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12331.1Skamil	if (child == 0) {
12341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12361.1Skamil
12371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12391.1Skamil
12401.13Schristos		DPRINTF("Before exiting of the child process\n");
12411.1Skamil		_exit(exitval);
12421.1Skamil	}
12431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12441.1Skamil
12451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12471.1Skamil
12481.1Skamil	validate_status_stopped(status, sigval);
12491.1Skamil
12501.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12531.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12541.1Skamil
12551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12561.1Skamil	    "without signal to be sent\n");
12571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12581.1Skamil
12591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12611.1Skamil
12621.1Skamil	validate_status_exited(status, exitval);
12631.1Skamil
12641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12661.1Skamil}
12671.1Skamil
12681.1SkamilATF_TC(eventmask6);
12691.1SkamilATF_TC_HEAD(eventmask6, tc)
12701.1Skamil{
12711.1Skamil	atf_tc_set_md_var(tc, "descr",
12721.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12731.1Skamil}
12741.1Skamil
12751.1SkamilATF_TC_BODY(eventmask6, tc)
12761.1Skamil{
12771.1Skamil	const int exitval = 5;
12781.1Skamil	const int sigval = SIGSTOP;
12791.1Skamil	pid_t child, wpid;
12801.1Skamil#if defined(TWAIT_HAVE_STATUS)
12811.1Skamil	int status;
12821.1Skamil#endif
12831.1Skamil	ptrace_event_t set_event, get_event;
12841.1Skamil	const int len = sizeof(ptrace_event_t);
12851.1Skamil
12861.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12871.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12881.1Skamil	if (child == 0) {
12891.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12901.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12911.1Skamil
12921.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12931.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12941.1Skamil
12951.13Schristos		DPRINTF("Before exiting of the child process\n");
12961.1Skamil		_exit(exitval);
12971.1Skamil	}
12981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12991.1Skamil
13001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13021.1Skamil
13031.1Skamil	validate_status_stopped(status, sigval);
13041.1Skamil
13051.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
13061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13081.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13091.1Skamil
13101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13111.1Skamil	    "without signal to be sent\n");
13121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13131.1Skamil
13141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13161.1Skamil
13171.1Skamil	validate_status_exited(status, exitval);
13181.1Skamil
13191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13211.1Skamil}
13221.1Skamil
13231.1Skamil#if defined(TWAIT_HAVE_PID)
13241.1SkamilATF_TC(fork1);
13251.1SkamilATF_TC_HEAD(fork1, tc)
13261.1Skamil{
13271.1Skamil	atf_tc_set_md_var(tc, "descr",
13281.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
13291.1Skamil	    "set to PTRACE_FORK");
13301.1Skamil}
13311.1Skamil
13321.1SkamilATF_TC_BODY(fork1, tc)
13331.1Skamil{
13341.1Skamil	const int exitval = 5;
13351.1Skamil	const int exitval2 = 15;
13361.1Skamil	const int sigval = SIGSTOP;
13371.1Skamil	pid_t child, child2, wpid;
13381.1Skamil#if defined(TWAIT_HAVE_STATUS)
13391.1Skamil	int status;
13401.1Skamil#endif
13411.1Skamil	ptrace_state_t state;
13421.1Skamil	const int slen = sizeof(state);
13431.1Skamil	ptrace_event_t event;
13441.1Skamil	const int elen = sizeof(event);
13451.1Skamil
13461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13481.1Skamil	if (child == 0) {
13491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13511.1Skamil
13521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13541.1Skamil
13551.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
13561.1Skamil
13571.1Skamil		if (child2 == 0)
13581.1Skamil			_exit(exitval2);
13591.1Skamil
13601.1Skamil		FORKEE_REQUIRE_SUCCESS
13611.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13621.1Skamil
13631.1Skamil		forkee_status_exited(status, exitval2);
13641.1Skamil
13651.13Schristos		DPRINTF("Before exiting of the child process\n");
13661.1Skamil		_exit(exitval);
13671.1Skamil	}
13681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13691.1Skamil
13701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13721.1Skamil
13731.1Skamil	validate_status_stopped(status, sigval);
13741.1Skamil
13751.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
13761.1Skamil	event.pe_set_event = PTRACE_FORK;
13771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13781.1Skamil
13791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13801.1Skamil	    "without signal to be sent\n");
13811.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
13821.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
13831.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
13841.1Skamil                "state.pe_other_pid=child)\n", child);
13851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13861.1Skamil
13871.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
13881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13891.1Skamil
13901.1Skamil	validate_status_stopped(status, SIGTRAP);
13911.1Skamil
13921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
13931.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
13941.1Skamil
13951.1Skamil	child2 = state.pe_other_pid;
13961.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
13971.1Skamil
13981.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
13991.1Skamil	    TWAIT_FNAME, child2, child);
14001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14011.1Skamil	    child2);
14021.1Skamil
14031.1Skamil	validate_status_stopped(status, SIGTRAP);
14041.1Skamil
14051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
14061.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
14071.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
14081.1Skamil
14091.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
14101.1Skamil	    "without signal to be sent\n");
14111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
14121.1Skamil
14131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14141.1Skamil	    "without signal to be sent\n");
14151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14161.1Skamil
14171.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
14181.1Skamil	    TWAIT_FNAME);
14191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14201.1Skamil	    child2);
14211.1Skamil
14221.1Skamil	validate_status_exited(status, exitval2);
14231.1Skamil
14241.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
14251.1Skamil	    TWAIT_FNAME);
14261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
14271.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
14281.1Skamil
14291.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14301.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14321.1Skamil
14331.1Skamil	validate_status_stopped(status, SIGCHLD);
14341.1Skamil
14351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14361.1Skamil	    "without signal to be sent\n");
14371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14381.1Skamil
14391.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
14401.1Skamil	    TWAIT_FNAME);
14411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14421.1Skamil
14431.1Skamil	validate_status_exited(status, exitval);
14441.1Skamil
14451.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
14461.1Skamil	    TWAIT_FNAME);
14471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14481.1Skamil}
14491.1Skamil#endif
14501.1Skamil
14511.1SkamilATF_TC(fork2);
14521.1SkamilATF_TC_HEAD(fork2, tc)
14531.1Skamil{
14541.1Skamil	atf_tc_set_md_var(tc, "descr",
14551.1Skamil	    "Verify that fork(2) is not intercepted by ptrace(2) with empty "
14561.1Skamil	    "EVENT_MASK");
14571.1Skamil}
14581.1Skamil
14591.1SkamilATF_TC_BODY(fork2, tc)
14601.1Skamil{
14611.1Skamil	const int exitval = 5;
14621.1Skamil	const int exitval2 = 15;
14631.1Skamil	const int sigval = SIGSTOP;
14641.1Skamil	pid_t child, child2, wpid;
14651.1Skamil#if defined(TWAIT_HAVE_STATUS)
14661.1Skamil	int status;
14671.1Skamil#endif
14681.1Skamil	ptrace_event_t event;
14691.1Skamil	const int elen = sizeof(event);
14701.1Skamil
14711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14731.1Skamil	if (child == 0) {
14741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14761.1Skamil
14771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14791.1Skamil
14801.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
14811.1Skamil
14821.1Skamil		if (child2 == 0)
14831.1Skamil			_exit(exitval2);
14841.1Skamil
14851.1Skamil		FORKEE_REQUIRE_SUCCESS
14861.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
14871.1Skamil
14881.1Skamil		forkee_status_exited(status, exitval2);
14891.1Skamil
14901.13Schristos		DPRINTF("Before exiting of the child process\n");
14911.1Skamil		_exit(exitval);
14921.1Skamil	}
14931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14941.1Skamil
14951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14971.1Skamil
14981.1Skamil	validate_status_stopped(status, sigval);
14991.1Skamil
15001.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
15011.1Skamil	event.pe_set_event = 0;
15021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
15031.1Skamil
15041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15051.1Skamil	    "without signal to be sent\n");
15061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15071.1Skamil
15081.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
15091.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
15101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15111.1Skamil
15121.1Skamil	validate_status_stopped(status, SIGCHLD);
15131.1Skamil
15141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15151.1Skamil	    "without signal to be sent\n");
15161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15171.1Skamil
15181.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
15191.1Skamil	    TWAIT_FNAME);
15201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15211.1Skamil
15221.1Skamil	validate_status_exited(status, exitval);
15231.1Skamil
15241.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
15251.1Skamil	    TWAIT_FNAME);
15261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15271.1Skamil}
15281.1Skamil
15291.1Skamil#if defined(TWAIT_HAVE_PID)
15301.1SkamilATF_TC(vfork1);
15311.1SkamilATF_TC_HEAD(vfork1, tc)
15321.1Skamil{
15331.1Skamil	atf_tc_set_md_var(tc, "descr",
15341.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
15351.1Skamil	    "set to PTRACE_VFORK");
15361.1Skamil}
15371.1Skamil
15381.1SkamilATF_TC_BODY(vfork1, tc)
15391.1Skamil{
15401.1Skamil	const int exitval = 5;
15411.1Skamil	const int exitval2 = 15;
15421.1Skamil	const int sigval = SIGSTOP;
15431.1Skamil	pid_t child, child2, wpid;
15441.1Skamil#if defined(TWAIT_HAVE_STATUS)
15451.1Skamil	int status;
15461.1Skamil#endif
15471.1Skamil	ptrace_state_t state;
15481.1Skamil	const int slen = sizeof(state);
15491.1Skamil	ptrace_event_t event;
15501.1Skamil	const int elen = sizeof(event);
15511.1Skamil
15521.1Skamil	atf_tc_expect_fail("PR kern/51630");
15531.1Skamil
15541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15561.1Skamil	if (child == 0) {
15571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15591.1Skamil
15601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15621.1Skamil
15631.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
15641.1Skamil
15651.1Skamil		if (child2 == 0)
15661.1Skamil			_exit(exitval2);
15671.1Skamil
15681.1Skamil		FORKEE_REQUIRE_SUCCESS
15691.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
15701.1Skamil
15711.1Skamil		forkee_status_exited(status, exitval2);
15721.1Skamil
15731.13Schristos		DPRINTF("Before exiting of the child process\n");
15741.1Skamil		_exit(exitval);
15751.1Skamil	}
15761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15771.1Skamil
15781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15801.1Skamil
15811.1Skamil	validate_status_stopped(status, sigval);
15821.1Skamil
15831.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
15841.1Skamil	event.pe_set_event = PTRACE_VFORK;
15851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
15861.1Skamil
15871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15881.1Skamil	    "without signal to be sent\n");
15891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15901.1Skamil
15911.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
15921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15931.1Skamil
15941.1Skamil	validate_status_stopped(status, SIGTRAP);
15951.1Skamil
15961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
15971.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
15981.1Skamil
15991.1Skamil	child2 = state.pe_other_pid;
16001.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
16011.1Skamil
16021.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
16031.1Skamil	    TWAIT_FNAME, child2, child);
16041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
16051.1Skamil	    child2);
16061.1Skamil
16071.1Skamil	validate_status_stopped(status, SIGTRAP);
16081.1Skamil
16091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
16101.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
16111.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
16121.1Skamil
16131.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
16141.1Skamil	    "without signal to be sent\n");
16151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
16161.1Skamil
16171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16181.1Skamil	    "without signal to be sent\n");
16191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16201.1Skamil
16211.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
16221.1Skamil	    TWAIT_FNAME);
16231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
16241.1Skamil	    child2);
16251.1Skamil
16261.1Skamil	validate_status_exited(status, exitval2);
16271.1Skamil
16281.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
16291.1Skamil	    TWAIT_FNAME);
16301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
16311.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
16321.1Skamil
16331.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
16341.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
16351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16361.1Skamil
16371.1Skamil	validate_status_stopped(status, SIGCHLD);
16381.1Skamil
16391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16401.1Skamil	    "without signal to be sent\n");
16411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16421.1Skamil
16431.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
16441.1Skamil	    TWAIT_FNAME);
16451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16461.1Skamil
16471.1Skamil	validate_status_exited(status, exitval);
16481.1Skamil
16491.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
16501.1Skamil	    TWAIT_FNAME);
16511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16521.1Skamil}
16531.1Skamil#endif
16541.1Skamil
16551.1SkamilATF_TC(vfork2);
16561.1SkamilATF_TC_HEAD(vfork2, tc)
16571.1Skamil{
16581.1Skamil	atf_tc_set_md_var(tc, "descr",
16591.1Skamil	    "Verify that vfork(2) is not intercepted by ptrace(2) with empty "
16601.1Skamil	    "EVENT_MASK");
16611.1Skamil}
16621.1Skamil
16631.1SkamilATF_TC_BODY(vfork2, tc)
16641.1Skamil{
16651.1Skamil	const int exitval = 5;
16661.1Skamil	const int exitval2 = 15;
16671.1Skamil	const int sigval = SIGSTOP;
16681.1Skamil	pid_t child, child2, wpid;
16691.1Skamil#if defined(TWAIT_HAVE_STATUS)
16701.1Skamil	int status;
16711.1Skamil#endif
16721.1Skamil	ptrace_event_t event;
16731.1Skamil	const int elen = sizeof(event);
16741.1Skamil
16751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16771.1Skamil	if (child == 0) {
16781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16801.1Skamil
16811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16831.1Skamil
16841.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
16851.1Skamil
16861.1Skamil		if (child2 == 0)
16871.1Skamil			_exit(exitval2);
16881.1Skamil
16891.1Skamil		FORKEE_REQUIRE_SUCCESS
16901.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
16911.1Skamil
16921.1Skamil		forkee_status_exited(status, exitval2);
16931.1Skamil
16941.13Schristos		DPRINTF("Before exiting of the child process\n");
16951.1Skamil		_exit(exitval);
16961.1Skamil	}
16971.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16981.1Skamil
16991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17011.1Skamil
17021.1Skamil	validate_status_stopped(status, sigval);
17031.1Skamil
17041.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
17051.1Skamil	event.pe_set_event = 0;
17061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17071.1Skamil
17081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17091.1Skamil	    "without signal to be sent\n");
17101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17111.1Skamil
17121.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
17131.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
17141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17151.1Skamil
17161.1Skamil	validate_status_stopped(status, SIGCHLD);
17171.1Skamil
17181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17191.1Skamil	    "without signal to be sent\n");
17201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17211.1Skamil
17221.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
17231.1Skamil	    TWAIT_FNAME);
17241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17251.1Skamil
17261.1Skamil	validate_status_exited(status, exitval);
17271.1Skamil
17281.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
17291.1Skamil	    TWAIT_FNAME);
17301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17311.1Skamil}
17321.1Skamil
17331.1SkamilATF_TC(vforkdone1);
17341.1SkamilATF_TC_HEAD(vforkdone1, tc)
17351.1Skamil{
17361.1Skamil	atf_tc_set_md_var(tc, "descr",
17371.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
17381.1Skamil	    "set to PTRACE_VFORK_DONE");
17391.1Skamil}
17401.1Skamil
17411.1SkamilATF_TC_BODY(vforkdone1, tc)
17421.1Skamil{
17431.1Skamil	const int exitval = 5;
17441.1Skamil	const int exitval2 = 15;
17451.1Skamil	const int sigval = SIGSTOP;
17461.1Skamil	pid_t child, child2, wpid;
17471.1Skamil#if defined(TWAIT_HAVE_STATUS)
17481.1Skamil	int status;
17491.1Skamil#endif
17501.1Skamil	ptrace_state_t state;
17511.1Skamil	const int slen = sizeof(state);
17521.1Skamil	ptrace_event_t event;
17531.1Skamil	const int elen = sizeof(event);
17541.1Skamil
17551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17571.1Skamil	if (child == 0) {
17581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17601.1Skamil
17611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17631.1Skamil
17641.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
17651.1Skamil
17661.1Skamil		if (child2 == 0)
17671.1Skamil			_exit(exitval2);
17681.1Skamil
17691.1Skamil		FORKEE_REQUIRE_SUCCESS
17701.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
17711.1Skamil
17721.1Skamil		forkee_status_exited(status, exitval2);
17731.1Skamil
17741.13Schristos		DPRINTF("Before exiting of the child process\n");
17751.1Skamil		_exit(exitval);
17761.1Skamil	}
17771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17781.1Skamil
17791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17811.1Skamil
17821.1Skamil	validate_status_stopped(status, sigval);
17831.1Skamil
17841.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
17851.1Skamil	    child);
17861.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
17871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17881.1Skamil
17891.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17901.1Skamil	    "without signal to be sent\n");
17911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17921.1Skamil
17931.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
17941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17951.1Skamil
17961.1Skamil	validate_status_stopped(status, SIGTRAP);
17971.1Skamil
17981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
17991.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
18001.1Skamil
18011.1Skamil	child2 = state.pe_other_pid;
18021.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
18031.1Skamil
18041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18051.1Skamil	    "without signal to be sent\n");
18061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18071.1Skamil
18081.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18091.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18111.1Skamil
18121.1Skamil	validate_status_stopped(status, SIGCHLD);
18131.1Skamil
18141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18151.1Skamil	    "without signal to be sent\n");
18161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18171.1Skamil
18181.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
18191.1Skamil	    TWAIT_FNAME);
18201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18211.1Skamil
18221.1Skamil	validate_status_exited(status, exitval);
18231.1Skamil
18241.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
18251.1Skamil	    TWAIT_FNAME);
18261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18271.1Skamil}
18281.1Skamil
18291.1SkamilATF_TC(vforkdone2);
18301.1SkamilATF_TC_HEAD(vforkdone2, tc)
18311.1Skamil{
18321.1Skamil	atf_tc_set_md_var(tc, "descr",
18331.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
18341.1Skamil	    "set to PTRACE_FORK | PTRACE_VFORK_DONE");
18351.1Skamil}
18361.1Skamil
18371.1SkamilATF_TC_BODY(vforkdone2, tc)
18381.1Skamil{
18391.1Skamil	const int exitval = 5;
18401.1Skamil	const int exitval2 = 15;
18411.1Skamil	const int sigval = SIGSTOP;
18421.1Skamil	pid_t child, child2, wpid;
18431.1Skamil#if defined(TWAIT_HAVE_STATUS)
18441.1Skamil	int status;
18451.1Skamil#endif
18461.1Skamil	ptrace_state_t state;
18471.1Skamil	const int slen = sizeof(state);
18481.1Skamil	ptrace_event_t event;
18491.1Skamil	const int elen = sizeof(event);
18501.1Skamil
18511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18531.1Skamil	if (child == 0) {
18541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18561.1Skamil
18571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18591.1Skamil
18601.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
18611.1Skamil
18621.1Skamil		if (child2 == 0)
18631.1Skamil			_exit(exitval2);
18641.1Skamil
18651.1Skamil		FORKEE_REQUIRE_SUCCESS
18661.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
18671.1Skamil
18681.1Skamil		forkee_status_exited(status, exitval2);
18691.1Skamil
18701.13Schristos		DPRINTF("Before exiting of the child process\n");
18711.1Skamil		_exit(exitval);
18721.1Skamil	}
18731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18741.1Skamil
18751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18771.1Skamil
18781.1Skamil	validate_status_stopped(status, sigval);
18791.1Skamil
18801.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
18811.1Skamil	event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE;
18821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
18831.1Skamil
18841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18851.1Skamil	    "without signal to be sent\n");
18861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18871.1Skamil
18881.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
18891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18901.1Skamil
18911.1Skamil	validate_status_stopped(status, SIGTRAP);
18921.1Skamil
18931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
18941.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
18951.1Skamil
18961.1Skamil	child2 = state.pe_other_pid;
18971.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
18981.1Skamil
18991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19001.1Skamil	    "without signal to be sent\n");
19011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19021.1Skamil
19031.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
19041.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
19051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19061.1Skamil
19071.1Skamil	validate_status_stopped(status, SIGCHLD);
19081.1Skamil
19091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19101.1Skamil	    "without signal to be sent\n");
19111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19121.1Skamil
19131.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
19141.1Skamil	    TWAIT_FNAME);
19151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19161.1Skamil
19171.1Skamil	validate_status_exited(status, exitval);
19181.1Skamil
19191.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
19201.1Skamil	    TWAIT_FNAME);
19211.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19221.1Skamil}
19231.1Skamil
19241.1SkamilATF_TC(io_read_d1);
19251.1SkamilATF_TC_HEAD(io_read_d1, tc)
19261.1Skamil{
19271.1Skamil	atf_tc_set_md_var(tc, "descr",
19281.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
19291.1Skamil}
19301.1Skamil
19311.1SkamilATF_TC_BODY(io_read_d1, tc)
19321.1Skamil{
19331.1Skamil	const int exitval = 5;
19341.1Skamil	const int sigval = SIGSTOP;
19351.1Skamil	pid_t child, wpid;
19361.1Skamil	uint8_t lookup_me = 0;
19371.1Skamil	const uint8_t magic = 0xab;
19381.1Skamil	struct ptrace_io_desc io = {
19391.1Skamil		.piod_op = PIOD_READ_D,
19401.1Skamil		.piod_offs = &lookup_me,
19411.1Skamil		.piod_addr = &lookup_me,
19421.1Skamil		.piod_len = sizeof(lookup_me)
19431.1Skamil	};
19441.1Skamil#if defined(TWAIT_HAVE_STATUS)
19451.1Skamil	int status;
19461.1Skamil#endif
19471.1Skamil
19481.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19491.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19501.1Skamil	if (child == 0) {
19511.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19521.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19531.1Skamil
19541.1Skamil		lookup_me = magic;
19551.1Skamil
19561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19581.1Skamil
19591.13Schristos		DPRINTF("Before exiting of the child process\n");
19601.1Skamil		_exit(exitval);
19611.1Skamil	}
19621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19631.1Skamil
19641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19661.1Skamil
19671.1Skamil	validate_status_stopped(status, sigval);
19681.1Skamil
19691.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19701.1Skamil	    child, getpid());
19711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19721.1Skamil
19731.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19741.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
19751.1Skamil
19761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19771.1Skamil	    "without signal to be sent\n");
19781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19791.1Skamil
19801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19821.1Skamil
19831.1Skamil	validate_status_exited(status, exitval);
19841.1Skamil
19851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19861.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19871.1Skamil}
19881.1Skamil
19891.1SkamilATF_TC(io_read_d2);
19901.1SkamilATF_TC_HEAD(io_read_d2, tc)
19911.1Skamil{
19921.1Skamil	atf_tc_set_md_var(tc, "descr",
19931.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
19941.1Skamil}
19951.1Skamil
19961.1SkamilATF_TC_BODY(io_read_d2, tc)
19971.1Skamil{
19981.1Skamil	const int exitval = 5;
19991.1Skamil	const int sigval = SIGSTOP;
20001.1Skamil	pid_t child, wpid;
20011.1Skamil	uint16_t lookup_me = 0;
20021.1Skamil	const uint16_t magic = 0x1234;
20031.1Skamil	struct ptrace_io_desc io = {
20041.1Skamil		.piod_op = PIOD_READ_D,
20051.1Skamil		.piod_offs = &lookup_me,
20061.1Skamil		.piod_addr = &lookup_me,
20071.1Skamil		.piod_len = sizeof(lookup_me)
20081.1Skamil	};
20091.1Skamil#if defined(TWAIT_HAVE_STATUS)
20101.1Skamil	int status;
20111.1Skamil#endif
20121.1Skamil
20131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20151.1Skamil	if (child == 0) {
20161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20181.1Skamil
20191.1Skamil		lookup_me = magic;
20201.1Skamil
20211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20231.1Skamil
20241.13Schristos		DPRINTF("Before exiting of the child process\n");
20251.1Skamil		_exit(exitval);
20261.1Skamil	}
20271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20281.1Skamil
20291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20311.1Skamil
20321.1Skamil	validate_status_stopped(status, sigval);
20331.1Skamil
20341.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20351.1Skamil	    child, getpid());
20361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20371.1Skamil
20381.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20391.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
20401.1Skamil
20411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20421.1Skamil	    "without signal to be sent\n");
20431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20441.1Skamil
20451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20471.1Skamil
20481.1Skamil	validate_status_exited(status, exitval);
20491.1Skamil
20501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20521.1Skamil}
20531.1Skamil
20541.1SkamilATF_TC(io_read_d3);
20551.1SkamilATF_TC_HEAD(io_read_d3, tc)
20561.1Skamil{
20571.1Skamil	atf_tc_set_md_var(tc, "descr",
20581.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
20591.1Skamil}
20601.1Skamil
20611.1SkamilATF_TC_BODY(io_read_d3, tc)
20621.1Skamil{
20631.1Skamil	const int exitval = 5;
20641.1Skamil	const int sigval = SIGSTOP;
20651.1Skamil	pid_t child, wpid;
20661.1Skamil	uint32_t lookup_me = 0;
20671.1Skamil	const uint32_t magic = 0x1234abcd;
20681.1Skamil	struct ptrace_io_desc io = {
20691.1Skamil		.piod_op = PIOD_READ_D,
20701.1Skamil		.piod_offs = &lookup_me,
20711.1Skamil		.piod_addr = &lookup_me,
20721.1Skamil		.piod_len = sizeof(lookup_me)
20731.1Skamil	};
20741.1Skamil#if defined(TWAIT_HAVE_STATUS)
20751.1Skamil	int status;
20761.1Skamil#endif
20771.1Skamil
20781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20801.1Skamil	if (child == 0) {
20811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20831.1Skamil
20841.1Skamil		lookup_me = magic;
20851.1Skamil
20861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20881.1Skamil
20891.13Schristos		DPRINTF("Before exiting of the child process\n");
20901.1Skamil		_exit(exitval);
20911.1Skamil	}
20921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20931.1Skamil
20941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20961.1Skamil
20971.1Skamil	validate_status_stopped(status, sigval);
20981.1Skamil
20991.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21001.1Skamil	    child, getpid());
21011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21021.1Skamil
21031.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21041.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
21051.1Skamil
21061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21071.1Skamil	    "without signal to be sent\n");
21081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21091.1Skamil
21101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21121.1Skamil
21131.1Skamil	validate_status_exited(status, exitval);
21141.1Skamil
21151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21171.1Skamil}
21181.1Skamil
21191.1SkamilATF_TC(io_read_d4);
21201.1SkamilATF_TC_HEAD(io_read_d4, tc)
21211.1Skamil{
21221.1Skamil	atf_tc_set_md_var(tc, "descr",
21231.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
21241.1Skamil}
21251.1Skamil
21261.1SkamilATF_TC_BODY(io_read_d4, tc)
21271.1Skamil{
21281.1Skamil	const int exitval = 5;
21291.1Skamil	const int sigval = SIGSTOP;
21301.1Skamil	pid_t child, wpid;
21311.1Skamil	uint64_t lookup_me = 0;
21321.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
21331.1Skamil	struct ptrace_io_desc io = {
21341.1Skamil		.piod_op = PIOD_READ_D,
21351.1Skamil		.piod_offs = &lookup_me,
21361.1Skamil		.piod_addr = &lookup_me,
21371.1Skamil		.piod_len = sizeof(lookup_me)
21381.1Skamil	};
21391.1Skamil#if defined(TWAIT_HAVE_STATUS)
21401.1Skamil	int status;
21411.1Skamil#endif
21421.1Skamil
21431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21451.1Skamil	if (child == 0) {
21461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21481.1Skamil
21491.1Skamil		lookup_me = magic;
21501.1Skamil
21511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21531.1Skamil
21541.13Schristos		DPRINTF("Before exiting of the child process\n");
21551.1Skamil		_exit(exitval);
21561.1Skamil	}
21571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21581.1Skamil
21591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21611.1Skamil
21621.1Skamil	validate_status_stopped(status, sigval);
21631.1Skamil
21641.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21651.1Skamil	    child, getpid());
21661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21671.1Skamil
21681.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21691.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
21701.1Skamil
21711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21721.1Skamil	    "without signal to be sent\n");
21731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21741.1Skamil
21751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21771.1Skamil
21781.1Skamil	validate_status_exited(status, exitval);
21791.1Skamil
21801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21811.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21821.1Skamil}
21831.1Skamil
21841.1SkamilATF_TC(io_write_d1);
21851.1SkamilATF_TC_HEAD(io_write_d1, tc)
21861.1Skamil{
21871.1Skamil	atf_tc_set_md_var(tc, "descr",
21881.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
21891.1Skamil}
21901.1Skamil
21911.1SkamilATF_TC_BODY(io_write_d1, tc)
21921.1Skamil{
21931.1Skamil	const int exitval = 5;
21941.1Skamil	const int sigval = SIGSTOP;
21951.1Skamil	pid_t child, wpid;
21961.1Skamil	uint8_t lookup_me = 0;
21971.1Skamil	const uint8_t magic = 0xab;
21981.1Skamil	struct ptrace_io_desc io = {
21991.1Skamil		.piod_op = PIOD_WRITE_D,
22001.1Skamil		.piod_offs = &lookup_me,
22011.1Skamil		.piod_addr = &lookup_me,
22021.1Skamil		.piod_len = sizeof(lookup_me)
22031.1Skamil	};
22041.1Skamil#if defined(TWAIT_HAVE_STATUS)
22051.1Skamil	int status;
22061.1Skamil#endif
22071.1Skamil
22081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22101.1Skamil	if (child == 0) {
22111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22131.1Skamil
22141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22161.1Skamil
22171.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22181.1Skamil
22191.13Schristos		DPRINTF("Before exiting of the child process\n");
22201.1Skamil		_exit(exitval);
22211.1Skamil	}
22221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22231.1Skamil
22241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22261.1Skamil
22271.1Skamil	validate_status_stopped(status, sigval);
22281.1Skamil
22291.1Skamil	lookup_me = magic;
22301.1Skamil
22311.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22321.1Skamil	    child, getpid());
22331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22341.1Skamil
22351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22361.1Skamil	    "without signal to be sent\n");
22371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22381.1Skamil
22391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22411.1Skamil
22421.1Skamil	validate_status_exited(status, exitval);
22431.1Skamil
22441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22461.1Skamil}
22471.1Skamil
22481.1SkamilATF_TC(io_write_d2);
22491.1SkamilATF_TC_HEAD(io_write_d2, tc)
22501.1Skamil{
22511.1Skamil	atf_tc_set_md_var(tc, "descr",
22521.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
22531.1Skamil}
22541.1Skamil
22551.1SkamilATF_TC_BODY(io_write_d2, tc)
22561.1Skamil{
22571.1Skamil	const int exitval = 5;
22581.1Skamil	const int sigval = SIGSTOP;
22591.1Skamil	pid_t child, wpid;
22601.1Skamil	uint16_t lookup_me = 0;
22611.1Skamil	const uint16_t magic = 0xab12;
22621.1Skamil	struct ptrace_io_desc io = {
22631.1Skamil		.piod_op = PIOD_WRITE_D,
22641.1Skamil		.piod_offs = &lookup_me,
22651.1Skamil		.piod_addr = &lookup_me,
22661.1Skamil		.piod_len = sizeof(lookup_me)
22671.1Skamil	};
22681.1Skamil#if defined(TWAIT_HAVE_STATUS)
22691.1Skamil	int status;
22701.1Skamil#endif
22711.1Skamil
22721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22741.1Skamil	if (child == 0) {
22751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22771.1Skamil
22781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22801.1Skamil
22811.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22821.1Skamil
22831.13Schristos		DPRINTF("Before exiting of the child process\n");
22841.1Skamil		_exit(exitval);
22851.1Skamil	}
22861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22871.1Skamil
22881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22901.1Skamil
22911.1Skamil	validate_status_stopped(status, sigval);
22921.1Skamil
22931.1Skamil	lookup_me = magic;
22941.1Skamil
22951.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22961.1Skamil	    child, getpid());
22971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22981.1Skamil
22991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23001.1Skamil	    "without signal to be sent\n");
23011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23021.1Skamil
23031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23051.1Skamil
23061.1Skamil	validate_status_exited(status, exitval);
23071.1Skamil
23081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23101.1Skamil}
23111.1Skamil
23121.1SkamilATF_TC(io_write_d3);
23131.1SkamilATF_TC_HEAD(io_write_d3, tc)
23141.1Skamil{
23151.1Skamil	atf_tc_set_md_var(tc, "descr",
23161.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
23171.1Skamil}
23181.1Skamil
23191.1SkamilATF_TC_BODY(io_write_d3, tc)
23201.1Skamil{
23211.1Skamil	const int exitval = 5;
23221.1Skamil	const int sigval = SIGSTOP;
23231.1Skamil	pid_t child, wpid;
23241.1Skamil	uint32_t lookup_me = 0;
23251.1Skamil	const uint32_t magic = 0xab127643;
23261.1Skamil	struct ptrace_io_desc io = {
23271.1Skamil		.piod_op = PIOD_WRITE_D,
23281.1Skamil		.piod_offs = &lookup_me,
23291.1Skamil		.piod_addr = &lookup_me,
23301.1Skamil		.piod_len = sizeof(lookup_me)
23311.1Skamil	};
23321.1Skamil#if defined(TWAIT_HAVE_STATUS)
23331.1Skamil	int status;
23341.1Skamil#endif
23351.1Skamil
23361.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23371.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23381.1Skamil	if (child == 0) {
23391.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23401.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23411.1Skamil
23421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23441.1Skamil
23451.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23461.1Skamil
23471.13Schristos		DPRINTF("Before exiting of the child process\n");
23481.1Skamil		_exit(exitval);
23491.1Skamil	}
23501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23511.1Skamil
23521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23541.1Skamil
23551.1Skamil	validate_status_stopped(status, sigval);
23561.1Skamil
23571.1Skamil	lookup_me = magic;
23581.1Skamil
23591.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23601.1Skamil	    child, getpid());
23611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23621.1Skamil
23631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23641.1Skamil	    "without signal to be sent\n");
23651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23661.1Skamil
23671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23691.1Skamil
23701.1Skamil	validate_status_exited(status, exitval);
23711.1Skamil
23721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23741.1Skamil}
23751.1Skamil
23761.1SkamilATF_TC(io_write_d4);
23771.1SkamilATF_TC_HEAD(io_write_d4, tc)
23781.1Skamil{
23791.1Skamil	atf_tc_set_md_var(tc, "descr",
23801.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
23811.1Skamil}
23821.1Skamil
23831.1SkamilATF_TC_BODY(io_write_d4, tc)
23841.1Skamil{
23851.1Skamil	const int exitval = 5;
23861.1Skamil	const int sigval = SIGSTOP;
23871.1Skamil	pid_t child, wpid;
23881.1Skamil	uint64_t lookup_me = 0;
23891.1Skamil	const uint64_t magic = 0xab12764376490123;
23901.1Skamil	struct ptrace_io_desc io = {
23911.1Skamil		.piod_op = PIOD_WRITE_D,
23921.1Skamil		.piod_offs = &lookup_me,
23931.1Skamil		.piod_addr = &lookup_me,
23941.1Skamil		.piod_len = sizeof(lookup_me)
23951.1Skamil	};
23961.1Skamil#if defined(TWAIT_HAVE_STATUS)
23971.1Skamil	int status;
23981.1Skamil#endif
23991.1Skamil
24001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24021.1Skamil	if (child == 0) {
24031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24051.1Skamil
24061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24081.1Skamil
24091.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
24101.1Skamil
24111.13Schristos		DPRINTF("Before exiting of the child process\n");
24121.1Skamil		_exit(exitval);
24131.1Skamil	}
24141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24151.1Skamil
24161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24181.1Skamil
24191.1Skamil	validate_status_stopped(status, sigval);
24201.1Skamil
24211.1Skamil	lookup_me = magic;
24221.1Skamil
24231.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24241.1Skamil	    child, getpid());
24251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24261.1Skamil
24271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24281.1Skamil	    "without signal to be sent\n");
24291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24301.1Skamil
24311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24331.1Skamil
24341.1Skamil	validate_status_exited(status, exitval);
24351.1Skamil
24361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24381.1Skamil}
24391.1Skamil
24401.1SkamilATF_TC(io_read_auxv1);
24411.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
24421.1Skamil{
24431.1Skamil	atf_tc_set_md_var(tc, "descr",
24441.1Skamil	    "Verify PT_READ_AUXV called for tracee");
24451.1Skamil}
24461.1Skamil
24471.1SkamilATF_TC_BODY(io_read_auxv1, tc)
24481.1Skamil{
24491.1Skamil	const int exitval = 5;
24501.1Skamil	const int sigval = SIGSTOP;
24511.1Skamil	pid_t child, wpid;
24521.1Skamil#if defined(TWAIT_HAVE_STATUS)
24531.1Skamil	int status;
24541.1Skamil#endif
24551.1Skamil	AuxInfo ai[100], *aip;
24561.1Skamil	struct ptrace_io_desc io = {
24571.1Skamil		.piod_op = PIOD_READ_AUXV,
24581.1Skamil		.piod_offs = 0,
24591.1Skamil		.piod_addr = ai,
24601.1Skamil		.piod_len = sizeof(ai)
24611.1Skamil	};
24621.1Skamil
24631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24651.1Skamil	if (child == 0) {
24661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24681.1Skamil
24691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24711.1Skamil
24721.13Schristos		DPRINTF("Before exiting of the child process\n");
24731.1Skamil		_exit(exitval);
24741.1Skamil	}
24751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24761.1Skamil
24771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24791.1Skamil
24801.1Skamil	validate_status_stopped(status, sigval);
24811.1Skamil
24821.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
24831.1Skamil	    child, getpid());
24841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24851.1Skamil
24861.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
24871.1Skamil	ATF_REQUIRE(io.piod_len > 0);
24881.1Skamil
24891.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
24901.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
24911.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
24921.1Skamil
24931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24941.1Skamil	    "without signal to be sent\n");
24951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24961.1Skamil
24971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24991.1Skamil
25001.1Skamil	validate_status_exited(status, exitval);
25011.1Skamil
25021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25041.1Skamil}
25051.1Skamil
25061.1SkamilATF_TC(read_d1);
25071.1SkamilATF_TC_HEAD(read_d1, tc)
25081.1Skamil{
25091.1Skamil	atf_tc_set_md_var(tc, "descr",
25101.1Skamil	    "Verify PT_READ_D called once");
25111.1Skamil}
25121.1Skamil
25131.1SkamilATF_TC_BODY(read_d1, tc)
25141.1Skamil{
25151.1Skamil	const int exitval = 5;
25161.1Skamil	const int sigval = SIGSTOP;
25171.1Skamil	pid_t child, wpid;
25181.1Skamil	int lookup_me = 0;
25191.1Skamil	const int magic = (int)random();
25201.1Skamil#if defined(TWAIT_HAVE_STATUS)
25211.1Skamil	int status;
25221.1Skamil#endif
25231.1Skamil
25241.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25251.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25261.1Skamil	if (child == 0) {
25271.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25281.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25291.1Skamil
25301.1Skamil		lookup_me = magic;
25311.1Skamil
25321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25341.1Skamil
25351.13Schristos		DPRINTF("Before exiting of the child process\n");
25361.1Skamil		_exit(exitval);
25371.1Skamil	}
25381.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25391.1Skamil
25401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25421.1Skamil
25431.1Skamil	validate_status_stopped(status, sigval);
25441.1Skamil
25451.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
25461.1Skamil	    child, getpid());
25471.1Skamil	errno = 0;
25481.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
25491.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25501.1Skamil
25511.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
25521.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
25531.1Skamil
25541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25551.1Skamil	    "without signal to be sent\n");
25561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25571.1Skamil
25581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25601.1Skamil
25611.1Skamil	validate_status_exited(status, exitval);
25621.1Skamil
25631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25651.1Skamil}
25661.1Skamil
25671.1SkamilATF_TC(read_d2);
25681.1SkamilATF_TC_HEAD(read_d2, tc)
25691.1Skamil{
25701.1Skamil	atf_tc_set_md_var(tc, "descr",
25711.1Skamil	    "Verify PT_READ_D called twice");
25721.1Skamil}
25731.1Skamil
25741.1SkamilATF_TC_BODY(read_d2, tc)
25751.1Skamil{
25761.1Skamil	const int exitval = 5;
25771.1Skamil	const int sigval = SIGSTOP;
25781.1Skamil	pid_t child, wpid;
25791.1Skamil	int lookup_me1 = 0;
25801.1Skamil	int lookup_me2 = 0;
25811.1Skamil	const int magic1 = (int)random();
25821.1Skamil	const int magic2 = (int)random();
25831.1Skamil#if defined(TWAIT_HAVE_STATUS)
25841.1Skamil	int status;
25851.1Skamil#endif
25861.1Skamil
25871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25891.1Skamil	if (child == 0) {
25901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25921.1Skamil
25931.1Skamil		lookup_me1 = magic1;
25941.1Skamil		lookup_me2 = magic2;
25951.1Skamil
25961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25981.1Skamil
25991.13Schristos		DPRINTF("Before exiting of the child process\n");
26001.1Skamil		_exit(exitval);
26011.1Skamil	}
26021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26031.1Skamil
26041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26061.1Skamil
26071.1Skamil	validate_status_stopped(status, sigval);
26081.1Skamil
26091.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26101.1Skamil	    child, getpid());
26111.1Skamil	errno = 0;
26121.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26131.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26141.1Skamil
26151.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26161.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26171.1Skamil
26181.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26191.1Skamil	    child, getpid());
26201.1Skamil	errno = 0;
26211.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26221.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26231.1Skamil
26241.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26251.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26261.1Skamil
26271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26281.1Skamil	    "without signal to be sent\n");
26291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26301.1Skamil
26311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26331.1Skamil
26341.1Skamil	validate_status_exited(status, exitval);
26351.1Skamil
26361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26381.1Skamil}
26391.1Skamil
26401.1SkamilATF_TC(read_d3);
26411.1SkamilATF_TC_HEAD(read_d3, tc)
26421.1Skamil{
26431.1Skamil	atf_tc_set_md_var(tc, "descr",
26441.1Skamil	    "Verify PT_READ_D called three times");
26451.1Skamil}
26461.1Skamil
26471.1SkamilATF_TC_BODY(read_d3, tc)
26481.1Skamil{
26491.1Skamil	const int exitval = 5;
26501.1Skamil	const int sigval = SIGSTOP;
26511.1Skamil	pid_t child, wpid;
26521.1Skamil	int lookup_me1 = 0;
26531.1Skamil	int lookup_me2 = 0;
26541.1Skamil	int lookup_me3 = 0;
26551.1Skamil	const int magic1 = (int)random();
26561.1Skamil	const int magic2 = (int)random();
26571.1Skamil	const int magic3 = (int)random();
26581.1Skamil#if defined(TWAIT_HAVE_STATUS)
26591.1Skamil	int status;
26601.1Skamil#endif
26611.1Skamil
26621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26641.1Skamil	if (child == 0) {
26651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26671.1Skamil
26681.1Skamil		lookup_me1 = magic1;
26691.1Skamil		lookup_me2 = magic2;
26701.1Skamil		lookup_me3 = magic3;
26711.1Skamil
26721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26741.1Skamil
26751.13Schristos		DPRINTF("Before exiting of the child process\n");
26761.1Skamil		_exit(exitval);
26771.1Skamil	}
26781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26791.1Skamil
26801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26821.1Skamil
26831.1Skamil	validate_status_stopped(status, sigval);
26841.1Skamil
26851.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26861.1Skamil	    child, getpid());
26871.1Skamil	errno = 0;
26881.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26891.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26901.1Skamil
26911.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26921.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26931.1Skamil
26941.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26951.1Skamil	    child, getpid());
26961.1Skamil	errno = 0;
26971.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26981.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26991.1Skamil
27001.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27011.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27021.1Skamil
27031.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27041.1Skamil	    child, getpid());
27051.1Skamil	errno = 0;
27061.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27071.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27081.1Skamil
27091.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27101.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27111.1Skamil
27121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27131.1Skamil	    "without signal to be sent\n");
27141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27151.1Skamil
27161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27181.1Skamil
27191.1Skamil	validate_status_exited(status, exitval);
27201.1Skamil
27211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27231.1Skamil}
27241.1Skamil
27251.1SkamilATF_TC(read_d4);
27261.1SkamilATF_TC_HEAD(read_d4, tc)
27271.1Skamil{
27281.1Skamil	atf_tc_set_md_var(tc, "descr",
27291.1Skamil	    "Verify PT_READ_D called four times");
27301.1Skamil}
27311.1Skamil
27321.1SkamilATF_TC_BODY(read_d4, tc)
27331.1Skamil{
27341.1Skamil	const int exitval = 5;
27351.1Skamil	const int sigval = SIGSTOP;
27361.1Skamil	pid_t child, wpid;
27371.1Skamil	int lookup_me1 = 0;
27381.1Skamil	int lookup_me2 = 0;
27391.1Skamil	int lookup_me3 = 0;
27401.1Skamil	int lookup_me4 = 0;
27411.1Skamil	const int magic1 = (int)random();
27421.1Skamil	const int magic2 = (int)random();
27431.1Skamil	const int magic3 = (int)random();
27441.1Skamil	const int magic4 = (int)random();
27451.1Skamil#if defined(TWAIT_HAVE_STATUS)
27461.1Skamil	int status;
27471.1Skamil#endif
27481.1Skamil
27491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27511.1Skamil	if (child == 0) {
27521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27541.1Skamil
27551.1Skamil		lookup_me1 = magic1;
27561.1Skamil		lookup_me2 = magic2;
27571.1Skamil		lookup_me3 = magic3;
27581.1Skamil		lookup_me4 = magic4;
27591.1Skamil
27601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27621.1Skamil
27631.13Schristos		DPRINTF("Before exiting of the child process\n");
27641.1Skamil		_exit(exitval);
27651.1Skamil	}
27661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27671.1Skamil
27681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27701.1Skamil
27711.1Skamil	validate_status_stopped(status, sigval);
27721.1Skamil
27731.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
27741.1Skamil	    child, getpid());
27751.1Skamil	errno = 0;
27761.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
27771.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27781.1Skamil
27791.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27801.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27811.1Skamil
27821.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27831.1Skamil	    child, getpid());
27841.1Skamil	errno = 0;
27851.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27861.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27871.1Skamil
27881.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27891.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27901.1Skamil
27911.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27921.1Skamil	    child, getpid());
27931.1Skamil	errno = 0;
27941.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27951.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27961.1Skamil
27971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27981.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27991.1Skamil
28001.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
28011.1Skamil	    child, getpid());
28021.1Skamil	errno = 0;
28031.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
28041.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
28051.1Skamil
28061.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
28071.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
28081.1Skamil
28091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28101.1Skamil	    "without signal to be sent\n");
28111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28121.1Skamil
28131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28151.1Skamil
28161.1Skamil	validate_status_exited(status, exitval);
28171.1Skamil
28181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28201.1Skamil}
28211.1Skamil
28221.1SkamilATF_TC(write_d1);
28231.1SkamilATF_TC_HEAD(write_d1, tc)
28241.1Skamil{
28251.1Skamil	atf_tc_set_md_var(tc, "descr",
28261.1Skamil	    "Verify PT_WRITE_D called once");
28271.1Skamil}
28281.1Skamil
28291.1SkamilATF_TC_BODY(write_d1, tc)
28301.1Skamil{
28311.1Skamil	const int exitval = 5;
28321.1Skamil	const int sigval = SIGSTOP;
28331.1Skamil	pid_t child, wpid;
28341.1Skamil	int lookup_me = 0;
28351.1Skamil	const int magic = (int)random();
28361.1Skamil#if defined(TWAIT_HAVE_STATUS)
28371.1Skamil	int status;
28381.1Skamil#endif
28391.1Skamil
28401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28421.1Skamil	if (child == 0) {
28431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28451.1Skamil
28461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28481.1Skamil
28491.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
28501.1Skamil
28511.13Schristos		DPRINTF("Before exiting of the child process\n");
28521.1Skamil		_exit(exitval);
28531.1Skamil	}
28541.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28551.1Skamil
28561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28581.1Skamil
28591.1Skamil	validate_status_stopped(status, sigval);
28601.1Skamil
28611.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
28621.1Skamil	    child, getpid());
28631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
28641.1Skamil
28651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28661.1Skamil	    "without signal to be sent\n");
28671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28681.1Skamil
28691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28711.1Skamil
28721.1Skamil	validate_status_exited(status, exitval);
28731.1Skamil
28741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28761.1Skamil}
28771.1Skamil
28781.1SkamilATF_TC(write_d2);
28791.1SkamilATF_TC_HEAD(write_d2, tc)
28801.1Skamil{
28811.1Skamil	atf_tc_set_md_var(tc, "descr",
28821.1Skamil	    "Verify PT_WRITE_D called twice");
28831.1Skamil}
28841.1Skamil
28851.1SkamilATF_TC_BODY(write_d2, tc)
28861.1Skamil{
28871.1Skamil	const int exitval = 5;
28881.1Skamil	const int sigval = SIGSTOP;
28891.1Skamil	pid_t child, wpid;
28901.1Skamil	int lookup_me1 = 0;
28911.1Skamil	int lookup_me2 = 0;
28921.1Skamil	const int magic1 = (int)random();
28931.1Skamil	const int magic2 = (int)random();
28941.1Skamil#if defined(TWAIT_HAVE_STATUS)
28951.1Skamil	int status;
28961.1Skamil#endif
28971.1Skamil
28981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29001.1Skamil	if (child == 0) {
29011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29031.1Skamil
29041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29061.1Skamil
29071.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29081.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29091.1Skamil
29101.13Schristos		DPRINTF("Before exiting of the child process\n");
29111.1Skamil		_exit(exitval);
29121.1Skamil	}
29131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29141.1Skamil
29151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29171.1Skamil
29181.1Skamil	validate_status_stopped(status, sigval);
29191.1Skamil
29201.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29211.1Skamil	    child, getpid());
29221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29231.1Skamil
29241.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29251.1Skamil	    child, getpid());
29261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29271.1Skamil
29281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29291.1Skamil	    "without signal to be sent\n");
29301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29311.1Skamil
29321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29341.1Skamil
29351.1Skamil	validate_status_exited(status, exitval);
29361.1Skamil
29371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29391.1Skamil}
29401.1Skamil
29411.1SkamilATF_TC(write_d3);
29421.1SkamilATF_TC_HEAD(write_d3, tc)
29431.1Skamil{
29441.1Skamil	atf_tc_set_md_var(tc, "descr",
29451.1Skamil	    "Verify PT_WRITE_D called three times");
29461.1Skamil}
29471.1Skamil
29481.1SkamilATF_TC_BODY(write_d3, tc)
29491.1Skamil{
29501.1Skamil	const int exitval = 5;
29511.1Skamil	const int sigval = SIGSTOP;
29521.1Skamil	pid_t child, wpid;
29531.1Skamil	int lookup_me1 = 0;
29541.1Skamil	int lookup_me2 = 0;
29551.1Skamil	int lookup_me3 = 0;
29561.1Skamil	const int magic1 = (int)random();
29571.1Skamil	const int magic2 = (int)random();
29581.1Skamil	const int magic3 = (int)random();
29591.1Skamil#if defined(TWAIT_HAVE_STATUS)
29601.1Skamil	int status;
29611.1Skamil#endif
29621.1Skamil
29631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29651.1Skamil	if (child == 0) {
29661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29681.1Skamil
29691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29711.1Skamil
29721.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29731.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29741.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
29751.1Skamil
29761.13Schristos		DPRINTF("Before exiting of the child process\n");
29771.1Skamil		_exit(exitval);
29781.1Skamil	}
29791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29801.1Skamil
29811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29831.1Skamil
29841.1Skamil	validate_status_stopped(status, sigval);
29851.1Skamil
29861.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29871.1Skamil	    child, getpid());
29881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29891.1Skamil
29901.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29911.1Skamil	    child, getpid());
29921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29931.1Skamil
29941.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
29951.1Skamil	    child, getpid());
29961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
29971.1Skamil
29981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29991.1Skamil	    "without signal to be sent\n");
30001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30011.1Skamil
30021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30041.1Skamil
30051.1Skamil	validate_status_exited(status, exitval);
30061.1Skamil
30071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30091.1Skamil}
30101.1Skamil
30111.1SkamilATF_TC(write_d4);
30121.1SkamilATF_TC_HEAD(write_d4, tc)
30131.1Skamil{
30141.1Skamil	atf_tc_set_md_var(tc, "descr",
30151.1Skamil	    "Verify PT_WRITE_D called four times");
30161.1Skamil}
30171.1Skamil
30181.1SkamilATF_TC_BODY(write_d4, tc)
30191.1Skamil{
30201.1Skamil	const int exitval = 5;
30211.1Skamil	const int sigval = SIGSTOP;
30221.1Skamil	pid_t child, wpid;
30231.1Skamil	int lookup_me1 = 0;
30241.1Skamil	int lookup_me2 = 0;
30251.1Skamil	int lookup_me3 = 0;
30261.1Skamil	int lookup_me4 = 0;
30271.1Skamil	const int magic1 = (int)random();
30281.1Skamil	const int magic2 = (int)random();
30291.1Skamil	const int magic3 = (int)random();
30301.1Skamil	const int magic4 = (int)random();
30311.1Skamil#if defined(TWAIT_HAVE_STATUS)
30321.1Skamil	int status;
30331.1Skamil#endif
30341.1Skamil
30351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30371.1Skamil	if (child == 0) {
30381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30401.1Skamil
30411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30431.1Skamil
30441.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
30451.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
30461.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
30471.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
30481.1Skamil
30491.13Schristos		DPRINTF("Before exiting of the child process\n");
30501.1Skamil		_exit(exitval);
30511.1Skamil	}
30521.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30531.1Skamil
30541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30561.1Skamil
30571.1Skamil	validate_status_stopped(status, sigval);
30581.1Skamil
30591.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
30601.1Skamil	    child, getpid());
30611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
30621.1Skamil
30631.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30641.1Skamil	    child, getpid());
30651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30661.1Skamil
30671.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30681.1Skamil	    child, getpid());
30691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30701.1Skamil
30711.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
30721.1Skamil	    child, getpid());
30731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
30741.1Skamil
30751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30761.1Skamil	    "without signal to be sent\n");
30771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30781.1Skamil
30791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30811.1Skamil
30821.1Skamil	validate_status_exited(status, exitval);
30831.1Skamil
30841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30861.1Skamil}
30871.1Skamil
30881.1SkamilATF_TC(io_read_d_write_d_handshake1);
30891.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
30901.1Skamil{
30911.1Skamil	atf_tc_set_md_var(tc, "descr",
30921.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
30931.1Skamil}
30941.1Skamil
30951.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
30961.1Skamil{
30971.1Skamil	const int exitval = 5;
30981.1Skamil	const int sigval = SIGSTOP;
30991.1Skamil	pid_t child, wpid;
31001.1Skamil	uint8_t lookup_me_fromtracee = 0;
31011.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31021.1Skamil	uint8_t lookup_me_totracee = 0;
31031.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31041.1Skamil	struct ptrace_io_desc io_fromtracee = {
31051.1Skamil		.piod_op = PIOD_READ_D,
31061.1Skamil		.piod_offs = &lookup_me_fromtracee,
31071.1Skamil		.piod_addr = &lookup_me_fromtracee,
31081.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31091.1Skamil	};
31101.1Skamil	struct ptrace_io_desc io_totracee = {
31111.1Skamil		.piod_op = PIOD_WRITE_D,
31121.1Skamil		.piod_offs = &lookup_me_totracee,
31131.1Skamil		.piod_addr = &lookup_me_totracee,
31141.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31151.1Skamil	};
31161.1Skamil#if defined(TWAIT_HAVE_STATUS)
31171.1Skamil	int status;
31181.1Skamil#endif
31191.1Skamil
31201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31221.1Skamil	if (child == 0) {
31231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31251.1Skamil
31261.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31271.1Skamil
31281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31301.1Skamil
31311.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31321.1Skamil
31331.13Schristos		DPRINTF("Before exiting of the child process\n");
31341.1Skamil		_exit(exitval);
31351.1Skamil	}
31361.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31371.1Skamil
31381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31401.1Skamil
31411.1Skamil	validate_status_stopped(status, sigval);
31421.1Skamil
31431.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31441.1Skamil	    child, getpid());
31451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
31461.1Skamil
31471.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31481.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
31491.1Skamil	    magic_fromtracee);
31501.1Skamil
31511.1Skamil	lookup_me_totracee = magic_totracee;
31521.1Skamil
31531.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
31541.1Skamil	    child, getpid());
31551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
31561.1Skamil
31571.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
31581.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
31591.1Skamil	    magic_totracee);
31601.1Skamil
31611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31621.1Skamil	    "without signal to be sent\n");
31631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31641.1Skamil
31651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31671.1Skamil
31681.1Skamil	validate_status_exited(status, exitval);
31691.1Skamil
31701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31711.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31721.1Skamil}
31731.1Skamil
31741.1SkamilATF_TC(io_read_d_write_d_handshake2);
31751.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
31761.1Skamil{
31771.1Skamil	atf_tc_set_md_var(tc, "descr",
31781.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
31791.1Skamil}
31801.1Skamil
31811.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
31821.1Skamil{
31831.1Skamil	const int exitval = 5;
31841.1Skamil	const int sigval = SIGSTOP;
31851.1Skamil	pid_t child, wpid;
31861.1Skamil	uint8_t lookup_me_fromtracee = 0;
31871.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31881.1Skamil	uint8_t lookup_me_totracee = 0;
31891.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31901.1Skamil	struct ptrace_io_desc io_fromtracee = {
31911.1Skamil		.piod_op = PIOD_READ_D,
31921.1Skamil		.piod_offs = &lookup_me_fromtracee,
31931.1Skamil		.piod_addr = &lookup_me_fromtracee,
31941.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31951.1Skamil	};
31961.1Skamil	struct ptrace_io_desc io_totracee = {
31971.1Skamil		.piod_op = PIOD_WRITE_D,
31981.1Skamil		.piod_offs = &lookup_me_totracee,
31991.1Skamil		.piod_addr = &lookup_me_totracee,
32001.1Skamil		.piod_len = sizeof(lookup_me_totracee)
32011.1Skamil	};
32021.1Skamil#if defined(TWAIT_HAVE_STATUS)
32031.1Skamil	int status;
32041.1Skamil#endif
32051.1Skamil
32061.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32071.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32081.1Skamil	if (child == 0) {
32091.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32101.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32111.1Skamil
32121.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32131.1Skamil
32141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32161.1Skamil
32171.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32181.1Skamil
32191.13Schristos		DPRINTF("Before exiting of the child process\n");
32201.1Skamil		_exit(exitval);
32211.1Skamil	}
32221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32231.1Skamil
32241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32261.1Skamil
32271.1Skamil	validate_status_stopped(status, sigval);
32281.1Skamil
32291.1Skamil	lookup_me_totracee = magic_totracee;
32301.1Skamil
32311.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
32321.1Skamil	    child, getpid());
32331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
32341.1Skamil
32351.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
32361.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
32371.1Skamil	    magic_totracee);
32381.1Skamil
32391.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32401.1Skamil	    child, getpid());
32411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
32421.1Skamil
32431.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32441.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
32451.1Skamil	    magic_fromtracee);
32461.1Skamil
32471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32481.1Skamil	    "without signal to be sent\n");
32491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32501.1Skamil
32511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32531.1Skamil
32541.1Skamil	validate_status_exited(status, exitval);
32551.1Skamil
32561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32581.1Skamil}
32591.1Skamil
32601.1SkamilATF_TC(read_d_write_d_handshake1);
32611.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
32621.1Skamil{
32631.1Skamil	atf_tc_set_md_var(tc, "descr",
32641.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
32651.1Skamil}
32661.1Skamil
32671.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
32681.1Skamil{
32691.1Skamil	const int exitval = 5;
32701.1Skamil	const int sigval = SIGSTOP;
32711.1Skamil	pid_t child, wpid;
32721.1Skamil	int lookup_me_fromtracee = 0;
32731.1Skamil	const int magic_fromtracee = (int)random();
32741.1Skamil	int lookup_me_totracee = 0;
32751.1Skamil	const int magic_totracee = (int)random();
32761.1Skamil#if defined(TWAIT_HAVE_STATUS)
32771.1Skamil	int status;
32781.1Skamil#endif
32791.1Skamil
32801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32821.1Skamil	if (child == 0) {
32831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32851.1Skamil
32861.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32871.1Skamil
32881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32901.1Skamil
32911.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32921.1Skamil
32931.13Schristos		DPRINTF("Before exiting of the child process\n");
32941.1Skamil		_exit(exitval);
32951.1Skamil	}
32961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32971.1Skamil
32981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33001.1Skamil
33011.1Skamil	validate_status_stopped(status, sigval);
33021.1Skamil
33031.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33041.1Skamil	    child, getpid());
33051.1Skamil	errno = 0;
33061.1Skamil	lookup_me_fromtracee =
33071.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33081.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33091.1Skamil
33101.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33111.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33121.1Skamil	    magic_fromtracee);
33131.1Skamil
33141.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33151.1Skamil	    child, getpid());
33161.1Skamil	ATF_REQUIRE
33171.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33181.1Skamil	    != -1);
33191.1Skamil
33201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33211.1Skamil	    "without signal to be sent\n");
33221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33231.1Skamil
33241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33261.1Skamil
33271.1Skamil	validate_status_exited(status, exitval);
33281.1Skamil
33291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33311.1Skamil}
33321.1Skamil
33331.1SkamilATF_TC(read_d_write_d_handshake2);
33341.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
33351.1Skamil{
33361.1Skamil	atf_tc_set_md_var(tc, "descr",
33371.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
33381.1Skamil}
33391.1Skamil
33401.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
33411.1Skamil{
33421.1Skamil	const int exitval = 5;
33431.1Skamil	const int sigval = SIGSTOP;
33441.1Skamil	pid_t child, wpid;
33451.1Skamil	int lookup_me_fromtracee = 0;
33461.1Skamil	const int magic_fromtracee = (int)random();
33471.1Skamil	int lookup_me_totracee = 0;
33481.1Skamil	const int magic_totracee = (int)random();
33491.1Skamil#if defined(TWAIT_HAVE_STATUS)
33501.1Skamil	int status;
33511.1Skamil#endif
33521.1Skamil
33531.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33541.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33551.1Skamil	if (child == 0) {
33561.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33571.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33581.1Skamil
33591.1Skamil		lookup_me_fromtracee = magic_fromtracee;
33601.1Skamil
33611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33631.1Skamil
33641.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33651.1Skamil
33661.13Schristos		DPRINTF("Before exiting of the child process\n");
33671.1Skamil		_exit(exitval);
33681.1Skamil	}
33691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33701.1Skamil
33711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33731.1Skamil
33741.1Skamil	validate_status_stopped(status, sigval);
33751.1Skamil
33761.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33771.1Skamil	    child, getpid());
33781.1Skamil	ATF_REQUIRE
33791.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33801.1Skamil	    != -1);
33811.1Skamil
33821.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33831.1Skamil	    child, getpid());
33841.1Skamil	errno = 0;
33851.1Skamil	lookup_me_fromtracee =
33861.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33881.1Skamil
33891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33901.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33911.1Skamil	    magic_fromtracee);
33921.1Skamil
33931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33941.1Skamil	    "without signal to be sent\n");
33951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33961.1Skamil
33971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33991.1Skamil
34001.1Skamil	validate_status_exited(status, exitval);
34011.1Skamil
34021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34041.1Skamil}
34051.1Skamil
34061.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
34071.1Skamilstatic int __used
34081.1Skamildummy_fn1(int a, int b, int c, int d)
34091.1Skamil{
34101.1Skamil
34111.1Skamil	a *= 1;
34121.1Skamil	b += 2;
34131.1Skamil	c -= 3;
34141.1Skamil	d /= 4;
34151.1Skamil
34161.1Skamil	return a + b * c - d;
34171.1Skamil}
34181.1Skamil
34191.1Skamilstatic int __used
34201.1Skamildummy_fn2(int a, int b, int c, int d)
34211.1Skamil{
34221.1Skamil
34231.1Skamil	a *= 4;
34241.1Skamil	b += 3;
34251.1Skamil	c -= 2;
34261.1Skamil	d /= 1;
34271.1Skamil
34281.1Skamil	return a + b * c - d;
34291.1Skamil}
34301.1Skamil
34311.1Skamilstatic int __used
34321.1Skamildummy_fn3(int a, int b, int c, int d)
34331.1Skamil{
34341.1Skamil
34351.1Skamil	a *= 10;
34361.1Skamil	b += 20;
34371.1Skamil	c -= 30;
34381.1Skamil	d /= 40;
34391.1Skamil
34401.1Skamil	return a + b * c - d;
34411.1Skamil}
34421.1Skamil
34431.1Skamilstatic int __used
34441.1Skamildummy_fn4(int a, int b, int c, int d)
34451.1Skamil{
34461.1Skamil
34471.1Skamil	a *= 40;
34481.1Skamil	b += 30;
34491.1Skamil	c -= 20;
34501.1Skamil	d /= 10;
34511.1Skamil
34521.1Skamil	return a + b * c - d;
34531.1Skamil}
34541.1Skamil
34551.1SkamilATF_TC(io_read_i1);
34561.1SkamilATF_TC_HEAD(io_read_i1, tc)
34571.1Skamil{
34581.1Skamil	atf_tc_set_md_var(tc, "descr",
34591.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
34601.1Skamil}
34611.1Skamil
34621.1SkamilATF_TC_BODY(io_read_i1, tc)
34631.1Skamil{
34641.1Skamil	const int exitval = 5;
34651.1Skamil	const int sigval = SIGSTOP;
34661.1Skamil	pid_t child, wpid;
34671.1Skamil	uint8_t lookup_me = 0;
34681.1Skamil	uint8_t magic;
34691.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34701.1Skamil	struct ptrace_io_desc io = {
34711.1Skamil		.piod_op = PIOD_READ_I,
34721.1Skamil		.piod_offs = dummy_fn1,
34731.1Skamil		.piod_addr = &lookup_me,
34741.1Skamil		.piod_len = sizeof(lookup_me)
34751.1Skamil	};
34761.1Skamil#if defined(TWAIT_HAVE_STATUS)
34771.1Skamil	int status;
34781.1Skamil#endif
34791.1Skamil
34801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34821.1Skamil	if (child == 0) {
34831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34851.1Skamil
34861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34881.1Skamil
34891.13Schristos		DPRINTF("Before exiting of the child process\n");
34901.1Skamil		_exit(exitval);
34911.1Skamil	}
34921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34931.1Skamil
34941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34961.1Skamil
34971.1Skamil	validate_status_stopped(status, sigval);
34981.1Skamil
34991.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35001.1Skamil	    child, getpid());
35011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35021.1Skamil
35031.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35041.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
35051.1Skamil
35061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35071.1Skamil	    "without signal to be sent\n");
35081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35091.1Skamil
35101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35121.1Skamil
35131.1Skamil	validate_status_exited(status, exitval);
35141.1Skamil
35151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35171.1Skamil}
35181.1Skamil
35191.1SkamilATF_TC(io_read_i2);
35201.1SkamilATF_TC_HEAD(io_read_i2, tc)
35211.1Skamil{
35221.1Skamil	atf_tc_set_md_var(tc, "descr",
35231.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
35241.1Skamil}
35251.1Skamil
35261.1SkamilATF_TC_BODY(io_read_i2, tc)
35271.1Skamil{
35281.1Skamil	const int exitval = 5;
35291.1Skamil	const int sigval = SIGSTOP;
35301.1Skamil	pid_t child, wpid;
35311.1Skamil	uint16_t lookup_me = 0;
35321.1Skamil	uint16_t magic;
35331.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35341.1Skamil	struct ptrace_io_desc io = {
35351.1Skamil		.piod_op = PIOD_READ_I,
35361.1Skamil		.piod_offs = dummy_fn1,
35371.1Skamil		.piod_addr = &lookup_me,
35381.1Skamil		.piod_len = sizeof(lookup_me)
35391.1Skamil	};
35401.1Skamil#if defined(TWAIT_HAVE_STATUS)
35411.1Skamil	int status;
35421.1Skamil#endif
35431.1Skamil
35441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35461.1Skamil	if (child == 0) {
35471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35491.1Skamil
35501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35521.1Skamil
35531.13Schristos		DPRINTF("Before exiting of the child process\n");
35541.1Skamil		_exit(exitval);
35551.1Skamil	}
35561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35571.1Skamil
35581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35601.1Skamil
35611.1Skamil	validate_status_stopped(status, sigval);
35621.1Skamil
35631.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35641.1Skamil	    child, getpid());
35651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35661.1Skamil
35671.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35681.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
35691.1Skamil
35701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35711.1Skamil	    "without signal to be sent\n");
35721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35731.1Skamil
35741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35761.1Skamil
35771.1Skamil	validate_status_exited(status, exitval);
35781.1Skamil
35791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35811.1Skamil}
35821.1Skamil
35831.1SkamilATF_TC(io_read_i3);
35841.1SkamilATF_TC_HEAD(io_read_i3, tc)
35851.1Skamil{
35861.1Skamil	atf_tc_set_md_var(tc, "descr",
35871.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
35881.1Skamil}
35891.1Skamil
35901.1SkamilATF_TC_BODY(io_read_i3, tc)
35911.1Skamil{
35921.1Skamil	const int exitval = 5;
35931.1Skamil	const int sigval = SIGSTOP;
35941.1Skamil	pid_t child, wpid;
35951.1Skamil	uint32_t lookup_me = 0;
35961.1Skamil	uint32_t magic;
35971.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35981.1Skamil	struct ptrace_io_desc io = {
35991.1Skamil		.piod_op = PIOD_READ_I,
36001.1Skamil		.piod_offs = dummy_fn1,
36011.1Skamil		.piod_addr = &lookup_me,
36021.1Skamil		.piod_len = sizeof(lookup_me)
36031.1Skamil	};
36041.1Skamil#if defined(TWAIT_HAVE_STATUS)
36051.1Skamil	int status;
36061.1Skamil#endif
36071.1Skamil
36081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36101.1Skamil	if (child == 0) {
36111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36131.1Skamil
36141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36161.1Skamil
36171.13Schristos		DPRINTF("Before exiting of the child process\n");
36181.1Skamil		_exit(exitval);
36191.1Skamil	}
36201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36211.1Skamil
36221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36241.1Skamil
36251.1Skamil	validate_status_stopped(status, sigval);
36261.1Skamil
36271.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36281.1Skamil	    child, getpid());
36291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36301.1Skamil
36311.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36321.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
36331.1Skamil
36341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36351.1Skamil	    "without signal to be sent\n");
36361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36371.1Skamil
36381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36401.1Skamil
36411.1Skamil	validate_status_exited(status, exitval);
36421.1Skamil
36431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36451.1Skamil}
36461.1Skamil
36471.1SkamilATF_TC(io_read_i4);
36481.1SkamilATF_TC_HEAD(io_read_i4, tc)
36491.1Skamil{
36501.1Skamil	atf_tc_set_md_var(tc, "descr",
36511.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
36521.1Skamil}
36531.1Skamil
36541.1SkamilATF_TC_BODY(io_read_i4, tc)
36551.1Skamil{
36561.1Skamil	const int exitval = 5;
36571.1Skamil	const int sigval = SIGSTOP;
36581.1Skamil	pid_t child, wpid;
36591.1Skamil	uint64_t lookup_me = 0;
36601.1Skamil	uint64_t magic;
36611.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36621.1Skamil	struct ptrace_io_desc io = {
36631.1Skamil		.piod_op = PIOD_READ_I,
36641.1Skamil		.piod_offs = dummy_fn1,
36651.1Skamil		.piod_addr = &lookup_me,
36661.1Skamil		.piod_len = sizeof(lookup_me)
36671.1Skamil	};
36681.1Skamil#if defined(TWAIT_HAVE_STATUS)
36691.1Skamil	int status;
36701.1Skamil#endif
36711.1Skamil
36721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36741.1Skamil	if (child == 0) {
36751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36771.1Skamil
36781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36801.1Skamil
36811.13Schristos		DPRINTF("Before exiting of the child process\n");
36821.1Skamil		_exit(exitval);
36831.1Skamil	}
36841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36851.1Skamil
36861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36881.1Skamil
36891.1Skamil	validate_status_stopped(status, sigval);
36901.1Skamil
36911.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36921.1Skamil	    child, getpid());
36931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36941.1Skamil
36951.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36961.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
36971.1Skamil
36981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36991.1Skamil	    "without signal to be sent\n");
37001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37011.1Skamil
37021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37041.1Skamil
37051.1Skamil	validate_status_exited(status, exitval);
37061.1Skamil
37071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37091.1Skamil}
37101.1Skamil
37111.1SkamilATF_TC(read_i1);
37121.1SkamilATF_TC_HEAD(read_i1, tc)
37131.1Skamil{
37141.1Skamil	atf_tc_set_md_var(tc, "descr",
37151.1Skamil	    "Verify PT_READ_I called once");
37161.1Skamil}
37171.1Skamil
37181.1SkamilATF_TC_BODY(read_i1, tc)
37191.1Skamil{
37201.1Skamil	const int exitval = 5;
37211.1Skamil	const int sigval = SIGSTOP;
37221.1Skamil	pid_t child, wpid;
37231.1Skamil	int lookup_me = 0;
37241.1Skamil	int magic;
37251.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
37261.1Skamil#if defined(TWAIT_HAVE_STATUS)
37271.1Skamil	int status;
37281.1Skamil#endif
37291.1Skamil
37301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37321.1Skamil	if (child == 0) {
37331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37351.1Skamil
37361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37381.1Skamil
37391.13Schristos		DPRINTF("Before exiting of the child process\n");
37401.1Skamil		_exit(exitval);
37411.1Skamil	}
37421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37431.1Skamil
37441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37461.1Skamil
37471.1Skamil	validate_status_stopped(status, sigval);
37481.1Skamil
37491.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37501.1Skamil	    child, getpid());
37511.1Skamil	errno = 0;
37521.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
37531.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37541.1Skamil
37551.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37561.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
37571.1Skamil
37581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37591.1Skamil	    "without signal to be sent\n");
37601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37611.1Skamil
37621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37641.1Skamil
37651.1Skamil	validate_status_exited(status, exitval);
37661.1Skamil
37671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37691.1Skamil}
37701.1Skamil
37711.1SkamilATF_TC(read_i2);
37721.1SkamilATF_TC_HEAD(read_i2, tc)
37731.1Skamil{
37741.1Skamil	atf_tc_set_md_var(tc, "descr",
37751.1Skamil	    "Verify PT_READ_I called twice");
37761.1Skamil}
37771.1Skamil
37781.1SkamilATF_TC_BODY(read_i2, tc)
37791.1Skamil{
37801.1Skamil	const int exitval = 5;
37811.1Skamil	const int sigval = SIGSTOP;
37821.1Skamil	pid_t child, wpid;
37831.1Skamil	int lookup_me1 = 0;
37841.1Skamil	int lookup_me2 = 0;
37851.1Skamil	int magic1;
37861.1Skamil	int magic2;
37871.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37881.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37891.1Skamil#if defined(TWAIT_HAVE_STATUS)
37901.1Skamil	int status;
37911.1Skamil#endif
37921.1Skamil
37931.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37941.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37951.1Skamil	if (child == 0) {
37961.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37971.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37981.1Skamil
37991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38011.1Skamil
38021.13Schristos		DPRINTF("Before exiting of the child process\n");
38031.1Skamil		_exit(exitval);
38041.1Skamil	}
38051.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38061.1Skamil
38071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38091.1Skamil
38101.1Skamil	validate_status_stopped(status, sigval);
38111.1Skamil
38121.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38131.1Skamil	    child, getpid());
38141.1Skamil	errno = 0;
38151.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38161.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38171.1Skamil
38181.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38191.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38201.1Skamil
38211.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38221.1Skamil	    child, getpid());
38231.1Skamil	errno = 0;
38241.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38251.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38261.1Skamil
38271.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38281.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38291.1Skamil
38301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38311.1Skamil	    "without signal to be sent\n");
38321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38331.1Skamil
38341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38361.1Skamil
38371.1Skamil	validate_status_exited(status, exitval);
38381.1Skamil
38391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38411.1Skamil}
38421.1Skamil
38431.1SkamilATF_TC(read_i3);
38441.1SkamilATF_TC_HEAD(read_i3, tc)
38451.1Skamil{
38461.1Skamil	atf_tc_set_md_var(tc, "descr",
38471.1Skamil	    "Verify PT_READ_I called three times");
38481.1Skamil}
38491.1Skamil
38501.1SkamilATF_TC_BODY(read_i3, tc)
38511.1Skamil{
38521.1Skamil	const int exitval = 5;
38531.1Skamil	const int sigval = SIGSTOP;
38541.1Skamil	pid_t child, wpid;
38551.1Skamil	int lookup_me1 = 0;
38561.1Skamil	int lookup_me2 = 0;
38571.1Skamil	int lookup_me3 = 0;
38581.1Skamil	int magic1;
38591.1Skamil	int magic2;
38601.1Skamil	int magic3;
38611.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
38621.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
38631.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
38641.1Skamil#if defined(TWAIT_HAVE_STATUS)
38651.1Skamil	int status;
38661.1Skamil#endif
38671.1Skamil
38681.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38691.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38701.1Skamil	if (child == 0) {
38711.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38721.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38731.1Skamil
38741.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38751.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38761.1Skamil
38771.13Schristos		DPRINTF("Before exiting of the child process\n");
38781.1Skamil		_exit(exitval);
38791.1Skamil	}
38801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38811.1Skamil
38821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38841.1Skamil
38851.1Skamil	validate_status_stopped(status, sigval);
38861.1Skamil
38871.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38881.1Skamil	    child, getpid());
38891.1Skamil	errno = 0;
38901.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38911.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38921.1Skamil
38931.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38941.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38951.1Skamil
38961.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38971.1Skamil	    child, getpid());
38981.1Skamil	errno = 0;
38991.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39001.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39011.1Skamil
39021.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39031.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39041.1Skamil
39051.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39061.1Skamil	    child, getpid());
39071.1Skamil	errno = 0;
39081.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39091.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39101.1Skamil
39111.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39121.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39131.1Skamil
39141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39151.1Skamil	    "without signal to be sent\n");
39161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39171.1Skamil
39181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39201.1Skamil
39211.1Skamil	validate_status_exited(status, exitval);
39221.1Skamil
39231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39251.1Skamil}
39261.1Skamil
39271.1SkamilATF_TC(read_i4);
39281.1SkamilATF_TC_HEAD(read_i4, tc)
39291.1Skamil{
39301.1Skamil	atf_tc_set_md_var(tc, "descr",
39311.1Skamil	    "Verify PT_READ_I called four times");
39321.1Skamil}
39331.1Skamil
39341.1SkamilATF_TC_BODY(read_i4, tc)
39351.1Skamil{
39361.1Skamil	const int exitval = 5;
39371.1Skamil	const int sigval = SIGSTOP;
39381.1Skamil	pid_t child, wpid;
39391.1Skamil	int lookup_me1 = 0;
39401.1Skamil	int lookup_me2 = 0;
39411.1Skamil	int lookup_me3 = 0;
39421.1Skamil	int lookup_me4 = 0;
39431.1Skamil	int magic1;
39441.1Skamil	int magic2;
39451.1Skamil	int magic3;
39461.1Skamil	int magic4;
39471.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
39481.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
39491.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
39501.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
39511.1Skamil#if defined(TWAIT_HAVE_STATUS)
39521.1Skamil	int status;
39531.1Skamil#endif
39541.1Skamil
39551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39571.1Skamil	if (child == 0) {
39581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39601.1Skamil
39611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39631.1Skamil
39641.13Schristos		DPRINTF("Before exiting of the child process\n");
39651.1Skamil		_exit(exitval);
39661.1Skamil	}
39671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39681.1Skamil
39691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39711.1Skamil
39721.1Skamil	validate_status_stopped(status, sigval);
39731.1Skamil
39741.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
39751.1Skamil	    child, getpid());
39761.1Skamil	errno = 0;
39771.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39781.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39791.1Skamil
39801.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39811.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39821.1Skamil
39831.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39841.1Skamil	    child, getpid());
39851.1Skamil	errno = 0;
39861.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39881.1Skamil
39891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39901.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39911.1Skamil
39921.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39931.1Skamil	    child, getpid());
39941.1Skamil	errno = 0;
39951.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39961.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39971.1Skamil
39981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39991.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
40001.1Skamil
40011.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
40021.1Skamil	    child, getpid());
40031.1Skamil	errno = 0;
40041.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
40051.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
40061.1Skamil
40071.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
40081.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
40091.1Skamil
40101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40111.1Skamil	    "without signal to be sent\n");
40121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40131.1Skamil
40141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40161.1Skamil
40171.1Skamil	validate_status_exited(status, exitval);
40181.1Skamil
40191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40211.1Skamil}
40221.1Skamil
40231.1Skamil#if defined(HAVE_GPREGS)
40241.1SkamilATF_TC(regs1);
40251.1SkamilATF_TC_HEAD(regs1, tc)
40261.1Skamil{
40271.1Skamil	atf_tc_set_md_var(tc, "descr",
40281.1Skamil	    "Verify plain PT_GETREGS call without further steps");
40291.1Skamil}
40301.1Skamil
40311.1SkamilATF_TC_BODY(regs1, tc)
40321.1Skamil{
40331.1Skamil	const int exitval = 5;
40341.1Skamil	const int sigval = SIGSTOP;
40351.1Skamil	pid_t child, wpid;
40361.1Skamil#if defined(TWAIT_HAVE_STATUS)
40371.1Skamil	int status;
40381.1Skamil#endif
40391.1Skamil	struct reg r;
40401.1Skamil
40411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40431.1Skamil	if (child == 0) {
40441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40461.1Skamil
40471.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40481.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40491.1Skamil
40501.13Schristos		DPRINTF("Before exiting of the child process\n");
40511.1Skamil		_exit(exitval);
40521.1Skamil	}
40531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40541.1Skamil
40551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40571.1Skamil
40581.1Skamil	validate_status_stopped(status, sigval);
40591.1Skamil
40601.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40621.1Skamil
40631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40641.1Skamil	    "without signal to be sent\n");
40651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40661.1Skamil
40671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40691.1Skamil
40701.1Skamil	validate_status_exited(status, exitval);
40711.1Skamil
40721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40741.1Skamil}
40751.1Skamil#endif
40761.1Skamil
40771.1Skamil#if defined(HAVE_GPREGS)
40781.1SkamilATF_TC(regs2);
40791.1SkamilATF_TC_HEAD(regs2, tc)
40801.1Skamil{
40811.1Skamil	atf_tc_set_md_var(tc, "descr",
40821.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
40831.1Skamil}
40841.1Skamil
40851.1SkamilATF_TC_BODY(regs2, tc)
40861.1Skamil{
40871.1Skamil	const int exitval = 5;
40881.1Skamil	const int sigval = SIGSTOP;
40891.1Skamil	pid_t child, wpid;
40901.1Skamil#if defined(TWAIT_HAVE_STATUS)
40911.1Skamil	int status;
40921.1Skamil#endif
40931.1Skamil	struct reg r;
40941.1Skamil
40951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40971.1Skamil	if (child == 0) {
40981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41001.1Skamil
41011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41031.1Skamil
41041.13Schristos		DPRINTF("Before exiting of the child process\n");
41051.1Skamil		_exit(exitval);
41061.1Skamil	}
41071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41081.1Skamil
41091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41111.1Skamil
41121.1Skamil	validate_status_stopped(status, sigval);
41131.1Skamil
41141.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41161.1Skamil
41171.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
41181.1Skamil
41191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41201.1Skamil	    "without signal to be sent\n");
41211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41221.1Skamil
41231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41251.1Skamil
41261.1Skamil	validate_status_exited(status, exitval);
41271.1Skamil
41281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41301.1Skamil}
41311.1Skamil#endif
41321.1Skamil
41331.1Skamil#if defined(HAVE_GPREGS)
41341.1SkamilATF_TC(regs3);
41351.1SkamilATF_TC_HEAD(regs3, tc)
41361.1Skamil{
41371.1Skamil	atf_tc_set_md_var(tc, "descr",
41381.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
41391.1Skamil}
41401.1Skamil
41411.1SkamilATF_TC_BODY(regs3, tc)
41421.1Skamil{
41431.1Skamil	const int exitval = 5;
41441.1Skamil	const int sigval = SIGSTOP;
41451.1Skamil	pid_t child, wpid;
41461.1Skamil#if defined(TWAIT_HAVE_STATUS)
41471.1Skamil	int status;
41481.1Skamil#endif
41491.1Skamil	struct reg r;
41501.1Skamil
41511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41531.1Skamil	if (child == 0) {
41541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41561.1Skamil
41571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41591.1Skamil
41601.13Schristos		DPRINTF("Before exiting of the child process\n");
41611.1Skamil		_exit(exitval);
41621.1Skamil	}
41631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41641.1Skamil
41651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41671.1Skamil
41681.1Skamil	validate_status_stopped(status, sigval);
41691.1Skamil
41701.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41721.1Skamil
41731.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
41741.1Skamil
41751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41761.1Skamil	    "without signal to be sent\n");
41771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41781.1Skamil
41791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41811.1Skamil
41821.1Skamil	validate_status_exited(status, exitval);
41831.1Skamil
41841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41861.1Skamil}
41871.1Skamil#endif
41881.1Skamil
41891.1Skamil#if defined(HAVE_GPREGS)
41901.1SkamilATF_TC(regs4);
41911.1SkamilATF_TC_HEAD(regs4, tc)
41921.1Skamil{
41931.1Skamil	atf_tc_set_md_var(tc, "descr",
41941.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
41951.1Skamil}
41961.1Skamil
41971.1SkamilATF_TC_BODY(regs4, tc)
41981.1Skamil{
41991.1Skamil	const int exitval = 5;
42001.1Skamil	const int sigval = SIGSTOP;
42011.1Skamil	pid_t child, wpid;
42021.1Skamil#if defined(TWAIT_HAVE_STATUS)
42031.1Skamil	int status;
42041.1Skamil#endif
42051.1Skamil	struct reg r;
42061.1Skamil
42071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42091.1Skamil	if (child == 0) {
42101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42121.1Skamil
42131.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42141.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42151.1Skamil
42161.13Schristos		DPRINTF("Before exiting of the child process\n");
42171.1Skamil		_exit(exitval);
42181.1Skamil	}
42191.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42201.1Skamil
42211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42231.1Skamil
42241.1Skamil	validate_status_stopped(status, sigval);
42251.1Skamil
42261.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42281.1Skamil
42291.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
42301.1Skamil
42311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42321.1Skamil	    "without signal to be sent\n");
42331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42341.1Skamil
42351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42371.1Skamil
42381.1Skamil	validate_status_exited(status, exitval);
42391.1Skamil
42401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42421.1Skamil}
42431.1Skamil#endif
42441.1Skamil
42451.1Skamil#if defined(HAVE_GPREGS)
42461.1SkamilATF_TC(regs5);
42471.1SkamilATF_TC_HEAD(regs5, tc)
42481.1Skamil{
42491.1Skamil	atf_tc_set_md_var(tc, "descr",
42501.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
42511.1Skamil}
42521.1Skamil
42531.1SkamilATF_TC_BODY(regs5, tc)
42541.1Skamil{
42551.1Skamil	const int exitval = 5;
42561.1Skamil	const int sigval = SIGSTOP;
42571.1Skamil	pid_t child, wpid;
42581.1Skamil#if defined(TWAIT_HAVE_STATUS)
42591.1Skamil	int status;
42601.1Skamil#endif
42611.1Skamil	struct reg r;
42621.1Skamil
42631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42651.1Skamil	if (child == 0) {
42661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42681.1Skamil
42691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42711.1Skamil
42721.13Schristos		DPRINTF("Before exiting of the child process\n");
42731.1Skamil		_exit(exitval);
42741.1Skamil	}
42751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42761.1Skamil
42771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42791.1Skamil
42801.1Skamil	validate_status_stopped(status, sigval);
42811.1Skamil
42821.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42841.1Skamil
42851.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
42861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42871.1Skamil
42881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42891.1Skamil	    "without signal to be sent\n");
42901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42911.1Skamil
42921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42941.1Skamil
42951.1Skamil	validate_status_exited(status, exitval);
42961.1Skamil
42971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42991.1Skamil}
43001.1Skamil#endif
43011.1Skamil
43021.1Skamil#if defined(HAVE_FPREGS)
43031.1SkamilATF_TC(fpregs1);
43041.1SkamilATF_TC_HEAD(fpregs1, tc)
43051.1Skamil{
43061.1Skamil	atf_tc_set_md_var(tc, "descr",
43071.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
43081.1Skamil}
43091.1Skamil
43101.1SkamilATF_TC_BODY(fpregs1, tc)
43111.1Skamil{
43121.1Skamil	const int exitval = 5;
43131.1Skamil	const int sigval = SIGSTOP;
43141.1Skamil	pid_t child, wpid;
43151.1Skamil#if defined(TWAIT_HAVE_STATUS)
43161.1Skamil	int status;
43171.1Skamil#endif
43181.1Skamil	struct fpreg r;
43191.1Skamil
43201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43221.1Skamil	if (child == 0) {
43231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43251.1Skamil
43261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43281.1Skamil
43291.13Schristos		DPRINTF("Before exiting of the child process\n");
43301.1Skamil		_exit(exitval);
43311.1Skamil	}
43321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43331.1Skamil
43341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43361.1Skamil
43371.1Skamil	validate_status_stopped(status, sigval);
43381.1Skamil
43391.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43411.1Skamil
43421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43431.1Skamil	    "without signal to be sent\n");
43441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43451.1Skamil
43461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43481.1Skamil
43491.1Skamil	validate_status_exited(status, exitval);
43501.1Skamil
43511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43521.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43531.1Skamil}
43541.1Skamil#endif
43551.1Skamil
43561.1Skamil#if defined(HAVE_FPREGS)
43571.1SkamilATF_TC(fpregs2);
43581.1SkamilATF_TC_HEAD(fpregs2, tc)
43591.1Skamil{
43601.1Skamil	atf_tc_set_md_var(tc, "descr",
43611.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
43621.1Skamil	    "regs");
43631.1Skamil}
43641.1Skamil
43651.1SkamilATF_TC_BODY(fpregs2, tc)
43661.1Skamil{
43671.1Skamil	const int exitval = 5;
43681.1Skamil	const int sigval = SIGSTOP;
43691.1Skamil	pid_t child, wpid;
43701.1Skamil#if defined(TWAIT_HAVE_STATUS)
43711.1Skamil	int status;
43721.1Skamil#endif
43731.1Skamil	struct fpreg r;
43741.1Skamil
43751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43771.1Skamil	if (child == 0) {
43781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43801.1Skamil
43811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43831.1Skamil
43841.13Schristos		DPRINTF("Before exiting of the child process\n");
43851.1Skamil		_exit(exitval);
43861.1Skamil	}
43871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43881.1Skamil
43891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43911.1Skamil
43921.1Skamil	validate_status_stopped(status, sigval);
43931.1Skamil
43941.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43961.1Skamil
43971.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
43981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
43991.1Skamil
44001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44011.1Skamil	    "without signal to be sent\n");
44021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44031.1Skamil
44041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44061.1Skamil
44071.1Skamil	validate_status_exited(status, exitval);
44081.1Skamil
44091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44111.1Skamil}
44121.1Skamil#endif
44131.1Skamil
44141.1Skamil#if defined(PT_STEP)
44151.1Skamilstatic void
44161.2Skamilptrace_step(int N, int setstep)
44171.1Skamil{
44181.1Skamil	const int exitval = 5;
44191.1Skamil	const int sigval = SIGSTOP;
44201.1Skamil	pid_t child, wpid;
44211.1Skamil#if defined(TWAIT_HAVE_STATUS)
44221.1Skamil	int status;
44231.1Skamil#endif
44241.1Skamil	int happy;
44251.1Skamil
44261.1Skamil#if defined(__arm__)
44271.1Skamil	/* PT_STEP not supported on arm 32-bit */
44281.1Skamil	atf_tc_expect_fail("PR kern/52119");
44291.1Skamil#endif
44301.1Skamil
44311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44331.1Skamil	if (child == 0) {
44341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44361.1Skamil
44371.1Skamil		happy = check_happy(999);
44381.1Skamil
44391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44411.1Skamil
44421.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
44431.1Skamil
44441.13Schristos		DPRINTF("Before exiting of the child process\n");
44451.1Skamil		_exit(exitval);
44461.1Skamil	}
44471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44481.1Skamil
44491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44511.1Skamil
44521.1Skamil	validate_status_stopped(status, sigval);
44531.1Skamil
44541.1Skamil	while (N --> 0) {
44551.2Skamil		if (setstep) {
44561.13Schristos			DPRINTF("Before resuming the child process where it "
44571.2Skamil			    "left off and without signal to be sent (use "
44581.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
44591.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
44601.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
44611.2Skamil			    != -1);
44621.2Skamil		} else {
44631.13Schristos			DPRINTF("Before resuming the child process where it "
44641.2Skamil			    "left off and without signal to be sent (use "
44651.2Skamil			    "PT_STEP)\n");
44661.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
44671.2Skamil			    != -1);
44681.2Skamil		}
44691.1Skamil
44701.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44711.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
44721.1Skamil		    child);
44731.1Skamil
44741.1Skamil		validate_status_stopped(status, SIGTRAP);
44751.2Skamil
44761.2Skamil		if (setstep) {
44771.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
44781.2Skamil		}
44791.1Skamil	}
44801.1Skamil
44811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44821.1Skamil	    "without signal to be sent\n");
44831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44841.1Skamil
44851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44871.1Skamil
44881.1Skamil	validate_status_exited(status, exitval);
44891.1Skamil
44901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44921.1Skamil}
44931.1Skamil#endif
44941.1Skamil
44951.1Skamil#if defined(PT_STEP)
44961.1SkamilATF_TC(step1);
44971.1SkamilATF_TC_HEAD(step1, tc)
44981.1Skamil{
44991.1Skamil	atf_tc_set_md_var(tc, "descr",
45001.1Skamil	    "Verify single PT_STEP call");
45011.1Skamil}
45021.1Skamil
45031.1SkamilATF_TC_BODY(step1, tc)
45041.1Skamil{
45051.2Skamil	ptrace_step(1, 0);
45061.1Skamil}
45071.1Skamil#endif
45081.1Skamil
45091.1Skamil#if defined(PT_STEP)
45101.1SkamilATF_TC(step2);
45111.1SkamilATF_TC_HEAD(step2, tc)
45121.1Skamil{
45131.1Skamil	atf_tc_set_md_var(tc, "descr",
45141.1Skamil	    "Verify PT_STEP called twice");
45151.1Skamil}
45161.1Skamil
45171.1SkamilATF_TC_BODY(step2, tc)
45181.1Skamil{
45191.2Skamil	ptrace_step(2, 0);
45201.1Skamil}
45211.1Skamil#endif
45221.1Skamil
45231.1Skamil#if defined(PT_STEP)
45241.1SkamilATF_TC(step3);
45251.1SkamilATF_TC_HEAD(step3, tc)
45261.1Skamil{
45271.1Skamil	atf_tc_set_md_var(tc, "descr",
45281.1Skamil	    "Verify PT_STEP called three times");
45291.1Skamil}
45301.1Skamil
45311.1SkamilATF_TC_BODY(step3, tc)
45321.1Skamil{
45331.2Skamil	ptrace_step(3, 0);
45341.1Skamil}
45351.1Skamil#endif
45361.1Skamil
45371.1Skamil#if defined(PT_STEP)
45381.1SkamilATF_TC(step4);
45391.1SkamilATF_TC_HEAD(step4, tc)
45401.1Skamil{
45411.1Skamil	atf_tc_set_md_var(tc, "descr",
45421.1Skamil	    "Verify PT_STEP called four times");
45431.1Skamil}
45441.1Skamil
45451.1SkamilATF_TC_BODY(step4, tc)
45461.1Skamil{
45471.2Skamil	ptrace_step(4, 0);
45481.2Skamil}
45491.2Skamil#endif
45501.2Skamil
45511.2Skamil#if defined(PT_STEP)
45521.2SkamilATF_TC(setstep1);
45531.2SkamilATF_TC_HEAD(setstep1, tc)
45541.2Skamil{
45551.2Skamil	atf_tc_set_md_var(tc, "descr",
45561.2Skamil	    "Verify single PT_SETSTEP call");
45571.2Skamil}
45581.2Skamil
45591.2SkamilATF_TC_BODY(setstep1, tc)
45601.2Skamil{
45611.2Skamil	ptrace_step(1, 1);
45621.2Skamil}
45631.2Skamil#endif
45641.2Skamil
45651.2Skamil#if defined(PT_STEP)
45661.2SkamilATF_TC(setstep2);
45671.2SkamilATF_TC_HEAD(setstep2, tc)
45681.2Skamil{
45691.2Skamil	atf_tc_set_md_var(tc, "descr",
45701.2Skamil	    "Verify PT_SETSTEP called twice");
45711.2Skamil}
45721.2Skamil
45731.2SkamilATF_TC_BODY(setstep2, tc)
45741.2Skamil{
45751.2Skamil	ptrace_step(2, 1);
45761.2Skamil}
45771.2Skamil#endif
45781.2Skamil
45791.2Skamil#if defined(PT_STEP)
45801.2SkamilATF_TC(setstep3);
45811.2SkamilATF_TC_HEAD(setstep3, tc)
45821.2Skamil{
45831.2Skamil	atf_tc_set_md_var(tc, "descr",
45841.2Skamil	    "Verify PT_SETSTEP called three times");
45851.2Skamil}
45861.2Skamil
45871.2SkamilATF_TC_BODY(setstep3, tc)
45881.2Skamil{
45891.2Skamil	ptrace_step(3, 1);
45901.2Skamil}
45911.2Skamil#endif
45921.2Skamil
45931.2Skamil#if defined(PT_STEP)
45941.2SkamilATF_TC(setstep4);
45951.2SkamilATF_TC_HEAD(setstep4, tc)
45961.2Skamil{
45971.2Skamil	atf_tc_set_md_var(tc, "descr",
45981.2Skamil	    "Verify PT_SETSTEP called four times");
45991.2Skamil}
46001.2Skamil
46011.2SkamilATF_TC_BODY(setstep4, tc)
46021.2Skamil{
46031.2Skamil	ptrace_step(4, 1);
46041.1Skamil}
46051.1Skamil#endif
46061.1Skamil
46071.1SkamilATF_TC(kill1);
46081.1SkamilATF_TC_HEAD(kill1, tc)
46091.1Skamil{
46101.1Skamil	atf_tc_set_md_var(tc, "descr",
46111.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
46121.1Skamil}
46131.1Skamil
46141.1SkamilATF_TC_BODY(kill1, tc)
46151.1Skamil{
46161.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
46171.1Skamil	pid_t child, wpid;
46181.1Skamil#if defined(TWAIT_HAVE_STATUS)
46191.1Skamil	int status;
46201.1Skamil#endif
46211.1Skamil
46221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46241.1Skamil	if (child == 0) {
46251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46271.1Skamil
46281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46301.1Skamil
46311.1Skamil		/* NOTREACHED */
46321.1Skamil		FORKEE_ASSERTX(0 &&
46331.1Skamil		    "Child should be terminated by a signal from its parent");
46341.1Skamil	}
46351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46361.1Skamil
46371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46391.1Skamil
46401.1Skamil	validate_status_stopped(status, sigval);
46411.1Skamil
46421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46431.1Skamil	    "without signal to be sent\n");
46441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
46451.1Skamil
46461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46481.1Skamil
46491.1Skamil	validate_status_signaled(status, sigsent, 0);
46501.1Skamil
46511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46521.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46531.1Skamil}
46541.1Skamil
46551.1SkamilATF_TC(kill2);
46561.1SkamilATF_TC_HEAD(kill2, tc)
46571.1Skamil{
46581.1Skamil	atf_tc_set_md_var(tc, "descr",
46591.1Skamil	    "Verify that PT_KILL terminates child");
46601.1Skamil}
46611.1Skamil
46621.1SkamilATF_TC_BODY(kill2, tc)
46631.1Skamil{
46641.1Skamil	const int sigval = SIGSTOP;
46651.1Skamil	pid_t child, wpid;
46661.1Skamil#if defined(TWAIT_HAVE_STATUS)
46671.1Skamil	int status;
46681.1Skamil#endif
46691.1Skamil
46701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46721.1Skamil	if (child == 0) {
46731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46751.1Skamil
46761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46781.1Skamil
46791.1Skamil		/* NOTREACHED */
46801.1Skamil		FORKEE_ASSERTX(0 &&
46811.1Skamil		    "Child should be terminated by a signal from its parent");
46821.1Skamil	}
46831.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46841.1Skamil
46851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46871.1Skamil
46881.1Skamil	validate_status_stopped(status, sigval);
46891.1Skamil
46901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46911.1Skamil	    "without signal to be sent\n");
46921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
46931.1Skamil
46941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46961.1Skamil
46971.1Skamil	validate_status_signaled(status, SIGKILL, 0);
46981.1Skamil
46991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47001.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47011.1Skamil}
47021.1Skamil
47031.1SkamilATF_TC(lwpinfo1);
47041.1SkamilATF_TC_HEAD(lwpinfo1, tc)
47051.1Skamil{
47061.1Skamil	atf_tc_set_md_var(tc, "descr",
47071.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
47081.1Skamil}
47091.1Skamil
47101.1SkamilATF_TC_BODY(lwpinfo1, tc)
47111.1Skamil{
47121.1Skamil	const int exitval = 5;
47131.1Skamil	const int sigval = SIGSTOP;
47141.1Skamil	pid_t child, wpid;
47151.1Skamil#if defined(TWAIT_HAVE_STATUS)
47161.1Skamil	int status;
47171.1Skamil#endif
47181.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47191.1Skamil
47201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47221.1Skamil	if (child == 0) {
47231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47251.1Skamil
47261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47281.1Skamil
47291.13Schristos		DPRINTF("Before exiting of the child process\n");
47301.1Skamil		_exit(exitval);
47311.1Skamil	}
47321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47331.1Skamil
47341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47361.1Skamil
47371.1Skamil	validate_status_stopped(status, sigval);
47381.1Skamil
47391.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47411.1Skamil
47421.13Schristos	DPRINTF("Assert that there exists a thread\n");
47431.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
47441.1Skamil
47451.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
47461.1Skamil	    info.pl_lwpid);
47471.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
47481.1Skamil	    "Received event %d != expected event %d",
47491.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
47501.1Skamil
47511.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47531.1Skamil
47541.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
47551.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
47561.1Skamil
47571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47581.1Skamil	    "without signal to be sent\n");
47591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47601.1Skamil
47611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47631.1Skamil
47641.1Skamil	validate_status_exited(status, exitval);
47651.1Skamil
47661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47681.1Skamil}
47691.1Skamil
47701.1Skamil#if defined(TWAIT_HAVE_PID)
47711.1SkamilATF_TC(lwpinfo2);
47721.1SkamilATF_TC_HEAD(lwpinfo2, tc)
47731.1Skamil{
47741.1Skamil	atf_tc_set_md_var(tc, "descr",
47751.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
47761.1Skamil	    "tracer)");
47771.1Skamil}
47781.1Skamil
47791.1SkamilATF_TC_BODY(lwpinfo2, tc)
47801.1Skamil{
47811.1Skamil	struct msg_fds parent_tracee, parent_tracer;
47821.1Skamil	const int exitval_tracee = 5;
47831.1Skamil	const int exitval_tracer = 10;
47841.1Skamil	pid_t tracee, tracer, wpid;
47851.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
47861.1Skamil#if defined(TWAIT_HAVE_STATUS)
47871.1Skamil	int status;
47881.1Skamil#endif
47891.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47901.1Skamil
47911.13Schristos	DPRINTF("Spawn tracee\n");
47921.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
47931.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
47941.1Skamil	tracee = atf_utils_fork();
47951.1Skamil	if (tracee == 0) {
47961.1Skamil
47971.1Skamil		/* Wait for message from the parent */
47981.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
47991.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
48001.1Skamil
48011.1Skamil		_exit(exitval_tracee);
48021.1Skamil	}
48031.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
48041.1Skamil
48051.13Schristos	DPRINTF("Spawn debugger\n");
48061.1Skamil	tracer = atf_utils_fork();
48071.1Skamil	if (tracer == 0) {
48081.1Skamil		/* No IPC to communicate with the child */
48091.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
48101.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
48111.1Skamil
48121.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
48131.1Skamil		FORKEE_REQUIRE_SUCCESS(
48141.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48151.1Skamil
48161.1Skamil		forkee_status_stopped(status, SIGSTOP);
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 exists a thread\n");
48231.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
48241.1Skamil
48251.13Schristos		DPRINTF("Assert that lwp thread %d received event "
48261.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
48271.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
48281.1Skamil
48291.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48301.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48311.1Skamil		    != -1);
48321.1Skamil
48331.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
48341.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
48351.1Skamil
48361.1Skamil		/* Resume tracee with PT_CONTINUE */
48371.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
48381.1Skamil
48391.1Skamil		/* Inform parent that tracer has attached to tracee */
48401.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
48411.1Skamil		/* Wait for parent */
48421.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
48431.1Skamil
48441.1Skamil		/* Wait for tracee and assert that it exited */
48451.1Skamil		FORKEE_REQUIRE_SUCCESS(
48461.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48471.1Skamil
48481.1Skamil		forkee_status_exited(status, exitval_tracee);
48491.1Skamil
48501.13Schristos		DPRINTF("Before exiting of the tracer process\n");
48511.1Skamil		_exit(exitval_tracer);
48521.1Skamil	}
48531.1Skamil
48541.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
48551.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
48561.1Skamil
48571.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
48581.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
48591.1Skamil
48601.13Schristos	DPRINTF("Detect that tracee is zombie\n");
48611.1Skamil	await_zombie(tracee);
48621.1Skamil
48631.13Schristos	DPRINTF("Assert that there is no status about tracee - "
48641.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
48651.1Skamil	TWAIT_REQUIRE_SUCCESS(
48661.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
48671.1Skamil
48681.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
48691.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
48701.1Skamil
48711.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
48721.1Skamil	    TWAIT_FNAME);
48731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
48741.1Skamil	    tracer);
48751.1Skamil
48761.1Skamil	validate_status_exited(status, exitval_tracer);
48771.1Skamil
48781.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
48791.1Skamil	    TWAIT_FNAME);
48801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
48811.1Skamil	    tracee);
48821.1Skamil
48831.1Skamil	validate_status_exited(status, exitval_tracee);
48841.1Skamil
48851.1Skamil	msg_close(&parent_tracer);
48861.1Skamil	msg_close(&parent_tracee);
48871.1Skamil}
48881.1Skamil#endif
48891.1Skamil
48901.1SkamilATF_TC(siginfo1);
48911.1SkamilATF_TC_HEAD(siginfo1, tc)
48921.1Skamil{
48931.1Skamil	atf_tc_set_md_var(tc, "descr",
48941.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
48951.1Skamil}
48961.1Skamil
48971.1SkamilATF_TC_BODY(siginfo1, tc)
48981.1Skamil{
48991.1Skamil	const int exitval = 5;
49001.1Skamil	const int sigval = SIGTRAP;
49011.1Skamil	pid_t child, wpid;
49021.1Skamil#if defined(TWAIT_HAVE_STATUS)
49031.1Skamil	int status;
49041.1Skamil#endif
49051.1Skamil	struct ptrace_siginfo info;
49061.1Skamil	memset(&info, 0, sizeof(info));
49071.1Skamil
49081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49101.1Skamil	if (child == 0) {
49111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49131.1Skamil
49141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49161.1Skamil
49171.13Schristos		DPRINTF("Before exiting of the child process\n");
49181.1Skamil		_exit(exitval);
49191.1Skamil	}
49201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49211.1Skamil
49221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49241.1Skamil
49251.1Skamil	validate_status_stopped(status, sigval);
49261.1Skamil
49271.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49291.1Skamil
49301.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49311.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49321.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49331.1Skamil	    info.psi_siginfo.si_errno);
49341.1Skamil
49351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49361.1Skamil	    "without signal to be sent\n");
49371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49381.1Skamil
49391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49411.1Skamil
49421.1Skamil	validate_status_exited(status, exitval);
49431.1Skamil
49441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49461.1Skamil}
49471.1Skamil
49481.1SkamilATF_TC(siginfo2);
49491.1SkamilATF_TC_HEAD(siginfo2, tc)
49501.1Skamil{
49511.1Skamil	atf_tc_set_md_var(tc, "descr",
49521.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
49531.1Skamil	    "modification of SIGINT from tracee");
49541.1Skamil}
49551.1Skamil
49561.1Skamilstatic int siginfo2_caught = 0;
49571.1Skamil
49581.1Skamilstatic void
49591.1Skamilsiginfo2_sighandler(int sig)
49601.1Skamil{
49611.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
49621.1Skamil
49631.1Skamil	++siginfo2_caught;
49641.1Skamil}
49651.1Skamil
49661.1SkamilATF_TC_BODY(siginfo2, tc)
49671.1Skamil{
49681.1Skamil	const int exitval = 5;
49691.1Skamil	const int sigval = SIGINT;
49701.1Skamil	pid_t child, wpid;
49711.1Skamil	struct sigaction sa;
49721.1Skamil#if defined(TWAIT_HAVE_STATUS)
49731.1Skamil	int status;
49741.1Skamil#endif
49751.1Skamil	struct ptrace_siginfo info;
49761.1Skamil	memset(&info, 0, sizeof(info));
49771.1Skamil
49781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49801.1Skamil	if (child == 0) {
49811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49831.1Skamil
49841.1Skamil		sa.sa_handler = siginfo2_sighandler;
49851.1Skamil		sa.sa_flags = SA_SIGINFO;
49861.1Skamil		sigemptyset(&sa.sa_mask);
49871.1Skamil
49881.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
49891.1Skamil
49901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49921.1Skamil
49931.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
49941.1Skamil
49951.13Schristos		DPRINTF("Before exiting of the child process\n");
49961.1Skamil		_exit(exitval);
49971.1Skamil	}
49981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49991.1Skamil
50001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50021.1Skamil
50031.1Skamil	validate_status_stopped(status, sigval);
50041.1Skamil
50051.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50071.1Skamil
50081.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50091.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50101.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50111.1Skamil	    info.psi_siginfo.si_errno);
50121.1Skamil
50131.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50151.1Skamil
50161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50171.1Skamil	    "without signal to be sent\n");
50181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
50191.1Skamil
50201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50221.1Skamil
50231.1Skamil	validate_status_exited(status, exitval);
50241.1Skamil
50251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50271.1Skamil}
50281.1Skamil
50291.1SkamilATF_TC(siginfo3);
50301.1SkamilATF_TC_HEAD(siginfo3, tc)
50311.1Skamil{
50321.1Skamil	atf_tc_set_md_var(tc, "descr",
50331.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
50341.1Skamil	    "setting signal to new value");
50351.1Skamil}
50361.1Skamil
50371.1Skamilstatic int siginfo3_caught = 0;
50381.1Skamil
50391.1Skamilstatic void
50401.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
50411.1Skamil{
50421.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
50431.1Skamil
50441.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
50451.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
50461.1Skamil
50471.1Skamil	++siginfo3_caught;
50481.1Skamil}
50491.1Skamil
50501.1SkamilATF_TC_BODY(siginfo3, tc)
50511.1Skamil{
50521.1Skamil	const int exitval = 5;
50531.1Skamil	const int sigval = SIGINT;
50541.1Skamil	const int sigfaked = SIGTRAP;
50551.1Skamil	const int sicodefaked = TRAP_BRKPT;
50561.1Skamil	pid_t child, wpid;
50571.1Skamil	struct sigaction sa;
50581.1Skamil#if defined(TWAIT_HAVE_STATUS)
50591.1Skamil	int status;
50601.1Skamil#endif
50611.1Skamil	struct ptrace_siginfo info;
50621.1Skamil	memset(&info, 0, sizeof(info));
50631.1Skamil
50641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50661.1Skamil	if (child == 0) {
50671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50691.1Skamil
50701.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
50711.1Skamil		sa.sa_flags = SA_SIGINFO;
50721.1Skamil		sigemptyset(&sa.sa_mask);
50731.1Skamil
50741.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
50751.1Skamil
50761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50781.1Skamil
50791.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
50801.1Skamil
50811.13Schristos		DPRINTF("Before exiting of the child process\n");
50821.1Skamil		_exit(exitval);
50831.1Skamil	}
50841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50851.1Skamil
50861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50881.1Skamil
50891.1Skamil	validate_status_stopped(status, sigval);
50901.1Skamil
50911.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50931.1Skamil
50941.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50951.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50961.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50971.1Skamil	    info.psi_siginfo.si_errno);
50981.1Skamil
50991.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
51001.1Skamil	    sigfaked, sicodefaked);
51011.1Skamil	info.psi_siginfo.si_signo = sigfaked;
51021.1Skamil	info.psi_siginfo.si_code = sicodefaked;
51031.1Skamil
51041.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
51051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
51061.1Skamil
51071.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51091.1Skamil
51101.13Schristos	DPRINTF("Before checking siginfo_t\n");
51111.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
51121.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
51131.1Skamil
51141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51151.1Skamil	    "without signal to be sent\n");
51161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
51171.1Skamil
51181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51201.1Skamil
51211.1Skamil	validate_status_exited(status, exitval);
51221.1Skamil
51231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51251.1Skamil}
51261.1Skamil
51271.1SkamilATF_TC(siginfo4);
51281.1SkamilATF_TC_HEAD(siginfo4, tc)
51291.1Skamil{
51301.1Skamil	atf_tc_set_md_var(tc, "descr",
51311.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
51321.1Skamil}
51331.1Skamil
51341.1SkamilATF_TC_BODY(siginfo4, tc)
51351.1Skamil{
51361.1Skamil	const int sigval = SIGTRAP;
51371.1Skamil	pid_t child, wpid;
51381.1Skamil#if defined(TWAIT_HAVE_STATUS)
51391.1Skamil	int status;
51401.1Skamil#endif
51411.1Skamil
51421.1Skamil	struct ptrace_siginfo info;
51431.1Skamil	memset(&info, 0, sizeof(info));
51441.1Skamil
51451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51471.1Skamil	if (child == 0) {
51481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51501.1Skamil
51511.13Schristos		DPRINTF("Before calling execve(2) from child\n");
51521.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
51531.1Skamil
51541.1Skamil		FORKEE_ASSERT(0 && "Not reached");
51551.1Skamil	}
51561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51571.1Skamil
51581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51601.1Skamil
51611.1Skamil	validate_status_stopped(status, sigval);
51621.1Skamil
51631.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51651.1Skamil
51661.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51671.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51681.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51691.1Skamil	    info.psi_siginfo.si_errno);
51701.1Skamil
51711.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51721.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
51731.1Skamil
51741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51751.1Skamil	    "without signal to be sent\n");
51761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51771.1Skamil
51781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51801.1Skamil
51811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51831.1Skamil}
51841.1Skamil
51851.1Skamil#if defined(TWAIT_HAVE_PID)
51861.1SkamilATF_TC(siginfo5);
51871.1SkamilATF_TC_HEAD(siginfo5, tc)
51881.1Skamil{
51891.1Skamil	atf_tc_set_md_var(tc, "descr",
51901.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
51911.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
51921.1Skamil}
51931.1Skamil
51941.1SkamilATF_TC_BODY(siginfo5, tc)
51951.1Skamil{
51961.1Skamil	const int exitval = 5;
51971.1Skamil	const int exitval2 = 15;
51981.1Skamil	const int sigval = SIGSTOP;
51991.1Skamil	pid_t child, child2, wpid;
52001.1Skamil#if defined(TWAIT_HAVE_STATUS)
52011.1Skamil	int status;
52021.1Skamil#endif
52031.1Skamil	ptrace_state_t state;
52041.1Skamil	const int slen = sizeof(state);
52051.1Skamil	ptrace_event_t event;
52061.1Skamil	const int elen = sizeof(event);
52071.1Skamil	struct ptrace_siginfo info;
52081.1Skamil
52091.1Skamil	memset(&info, 0, sizeof(info));
52101.1Skamil
52111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52131.1Skamil	if (child == 0) {
52141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52161.1Skamil
52171.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52181.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52191.1Skamil
52201.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
52211.1Skamil
52221.1Skamil		if (child2 == 0)
52231.1Skamil			_exit(exitval2);
52241.1Skamil
52251.1Skamil		FORKEE_REQUIRE_SUCCESS
52261.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
52271.1Skamil
52281.1Skamil		forkee_status_exited(status, exitval2);
52291.1Skamil
52301.13Schristos		DPRINTF("Before exiting of the child process\n");
52311.1Skamil		_exit(exitval);
52321.1Skamil	}
52331.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52341.1Skamil
52351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52371.1Skamil
52381.1Skamil	validate_status_stopped(status, sigval);
52391.1Skamil
52401.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52421.1Skamil
52431.13Schristos	DPRINTF("Before checking siginfo_t\n");
52441.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
52451.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
52461.1Skamil
52471.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
52481.1Skamil	event.pe_set_event = PTRACE_FORK;
52491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52501.1Skamil
52511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52521.1Skamil	    "without signal to be sent\n");
52531.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
52541.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
52551.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
52561.1Skamil                "state.pe_other_pid=child)\n", child);
52571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52581.1Skamil
52591.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
52601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52611.1Skamil
52621.1Skamil	validate_status_stopped(status, SIGTRAP);
52631.1Skamil
52641.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52661.1Skamil
52671.13Schristos	DPRINTF("Before checking siginfo_t\n");
52681.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52691.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52701.1Skamil
52711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52721.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52731.1Skamil
52741.1Skamil	child2 = state.pe_other_pid;
52751.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
52761.1Skamil
52771.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
52781.1Skamil	    TWAIT_FNAME, child2, child);
52791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52801.1Skamil	    child2);
52811.1Skamil
52821.1Skamil	validate_status_stopped(status, SIGTRAP);
52831.1Skamil
52841.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52861.1Skamil
52871.13Schristos	DPRINTF("Before checking siginfo_t\n");
52881.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52891.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52901.1Skamil
52911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
52921.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52931.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
52941.1Skamil
52951.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
52961.1Skamil	    "without signal to be sent\n");
52971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
52981.1Skamil
52991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53001.1Skamil	    "without signal to be sent\n");
53011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53021.1Skamil
53031.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
53041.1Skamil	    TWAIT_FNAME);
53051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
53061.1Skamil	    child2);
53071.1Skamil
53081.1Skamil	validate_status_exited(status, exitval2);
53091.1Skamil
53101.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
53111.1Skamil	    TWAIT_FNAME);
53121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
53131.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
53141.1Skamil
53151.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53161.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
53171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53181.1Skamil
53191.1Skamil	validate_status_stopped(status, SIGCHLD);
53201.1Skamil
53211.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53231.1Skamil
53241.13Schristos	DPRINTF("Before checking siginfo_t\n");
53251.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
53261.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
53271.1Skamil
53281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53291.1Skamil	    "without signal to be sent\n");
53301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53311.1Skamil
53321.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53331.1Skamil	    TWAIT_FNAME);
53341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53351.1Skamil
53361.1Skamil	validate_status_exited(status, exitval);
53371.1Skamil
53381.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53391.1Skamil	    TWAIT_FNAME);
53401.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53411.1Skamil}
53421.1Skamil#endif
53431.1Skamil
53441.1Skamil#if defined(PT_STEP)
53451.1SkamilATF_TC(siginfo6);
53461.1SkamilATF_TC_HEAD(siginfo6, tc)
53471.1Skamil{
53481.1Skamil	atf_tc_set_md_var(tc, "descr",
53491.1Skamil	    "Verify single PT_STEP call with signal information check");
53501.1Skamil}
53511.1Skamil
53521.1SkamilATF_TC_BODY(siginfo6, tc)
53531.1Skamil{
53541.1Skamil	const int exitval = 5;
53551.1Skamil	const int sigval = SIGSTOP;
53561.1Skamil	pid_t child, wpid;
53571.1Skamil#if defined(TWAIT_HAVE_STATUS)
53581.1Skamil	int status;
53591.1Skamil#endif
53601.1Skamil	int happy;
53611.1Skamil	struct ptrace_siginfo info;
53621.1Skamil
53631.1Skamil#if defined(__arm__)
53641.1Skamil	/* PT_STEP not supported on arm 32-bit */
53651.1Skamil	atf_tc_expect_fail("PR kern/52119");
53661.1Skamil#endif
53671.1Skamil
53681.1Skamil	memset(&info, 0, sizeof(info));
53691.1Skamil
53701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53721.1Skamil	if (child == 0) {
53731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53751.1Skamil
53761.1Skamil		happy = check_happy(100);
53771.1Skamil
53781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53801.1Skamil
53811.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
53821.1Skamil
53831.13Schristos		DPRINTF("Before exiting of the child process\n");
53841.1Skamil		_exit(exitval);
53851.1Skamil	}
53861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53871.1Skamil
53881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53901.1Skamil
53911.1Skamil	validate_status_stopped(status, sigval);
53921.1Skamil
53931.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53951.1Skamil
53961.13Schristos	DPRINTF("Before checking siginfo_t\n");
53971.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
53981.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
53991.1Skamil
54001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54011.1Skamil	    "without signal to be sent (use PT_STEP)\n");
54021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
54031.1Skamil
54041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54061.1Skamil
54071.1Skamil	validate_status_stopped(status, SIGTRAP);
54081.1Skamil
54091.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
54101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
54111.1Skamil
54121.13Schristos	DPRINTF("Before checking siginfo_t\n");
54131.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
54141.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
54151.1Skamil
54161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54171.1Skamil	    "without signal to be sent\n");
54181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54191.1Skamil
54201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54221.1Skamil
54231.1Skamil	validate_status_exited(status, exitval);
54241.1Skamil
54251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54271.1Skamil}
54281.1Skamil#endif
54291.1Skamil
54301.1Skamilvolatile lwpid_t the_lwp_id = 0;
54311.1Skamil
54321.1Skamilstatic void
54331.1Skamillwp_main_func(void *arg)
54341.1Skamil{
54351.1Skamil	the_lwp_id = _lwp_self();
54361.1Skamil	_lwp_exit();
54371.1Skamil}
54381.1Skamil
54391.1SkamilATF_TC(lwp_create1);
54401.1SkamilATF_TC_HEAD(lwp_create1, tc)
54411.1Skamil{
54421.1Skamil	atf_tc_set_md_var(tc, "descr",
54431.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
54441.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
54451.1Skamil}
54461.1Skamil
54471.1SkamilATF_TC_BODY(lwp_create1, tc)
54481.1Skamil{
54491.1Skamil	const int exitval = 5;
54501.1Skamil	const int sigval = SIGSTOP;
54511.1Skamil	pid_t child, wpid;
54521.1Skamil#if defined(TWAIT_HAVE_STATUS)
54531.1Skamil	int status;
54541.1Skamil#endif
54551.1Skamil	ptrace_state_t state;
54561.1Skamil	const int slen = sizeof(state);
54571.1Skamil	ptrace_event_t event;
54581.1Skamil	const int elen = sizeof(event);
54591.1Skamil	ucontext_t uc;
54601.1Skamil	lwpid_t lid;
54611.1Skamil	static const size_t ssize = 16*1024;
54621.1Skamil	void *stack;
54631.1Skamil
54641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54661.1Skamil	if (child == 0) {
54671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54691.1Skamil
54701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54721.1Skamil
54731.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
54741.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
54751.1Skamil
54761.13Schristos		DPRINTF("Before making context for new lwp in child\n");
54771.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
54781.1Skamil
54791.13Schristos		DPRINTF("Before creating new in child\n");
54801.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
54811.1Skamil
54821.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
54831.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
54841.1Skamil
54851.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
54861.1Skamil		    "are the same\n", lid, the_lwp_id);
54871.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
54881.1Skamil
54891.13Schristos		DPRINTF("Before exiting of the child process\n");
54901.1Skamil		_exit(exitval);
54911.1Skamil	}
54921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54931.1Skamil
54941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54961.1Skamil
54971.1Skamil	validate_status_stopped(status, sigval);
54981.1Skamil
54991.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55001.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
55011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55021.1Skamil
55031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55041.1Skamil	    "without signal to be sent\n");
55051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55061.1Skamil
55071.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55081.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55101.1Skamil
55111.1Skamil	validate_status_stopped(status, SIGTRAP);
55121.1Skamil
55131.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55141.1Skamil
55151.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
55161.1Skamil
55171.1Skamil	lid = state.pe_lwp;
55181.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
55191.1Skamil
55201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55211.1Skamil	    "without signal to be sent\n");
55221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55231.1Skamil
55241.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
55251.1Skamil	    TWAIT_FNAME);
55261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55271.1Skamil
55281.1Skamil	validate_status_exited(status, exitval);
55291.1Skamil
55301.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
55311.1Skamil	    TWAIT_FNAME);
55321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55331.1Skamil}
55341.1Skamil
55351.1SkamilATF_TC(lwp_exit1);
55361.1SkamilATF_TC_HEAD(lwp_exit1, tc)
55371.1Skamil{
55381.1Skamil	atf_tc_set_md_var(tc, "descr",
55391.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
55401.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
55411.1Skamil}
55421.1Skamil
55431.1SkamilATF_TC_BODY(lwp_exit1, tc)
55441.1Skamil{
55451.1Skamil	const int exitval = 5;
55461.1Skamil	const int sigval = SIGSTOP;
55471.1Skamil	pid_t child, wpid;
55481.1Skamil#if defined(TWAIT_HAVE_STATUS)
55491.1Skamil	int status;
55501.1Skamil#endif
55511.1Skamil	ptrace_state_t state;
55521.1Skamil	const int slen = sizeof(state);
55531.1Skamil	ptrace_event_t event;
55541.1Skamil	const int elen = sizeof(event);
55551.1Skamil	ucontext_t uc;
55561.1Skamil	lwpid_t lid;
55571.1Skamil	static const size_t ssize = 16*1024;
55581.1Skamil	void *stack;
55591.1Skamil
55601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55621.1Skamil	if (child == 0) {
55631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55651.1Skamil
55661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55681.1Skamil
55691.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
55701.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
55711.1Skamil
55721.13Schristos		DPRINTF("Before making context for new lwp in child\n");
55731.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
55741.1Skamil
55751.13Schristos		DPRINTF("Before creating new in child\n");
55761.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
55771.1Skamil
55781.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
55791.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
55801.1Skamil
55811.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
55821.1Skamil		    "are the same\n", lid, the_lwp_id);
55831.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
55841.1Skamil
55851.13Schristos		DPRINTF("Before exiting of the child process\n");
55861.1Skamil		_exit(exitval);
55871.1Skamil	}
55881.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55891.1Skamil
55901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55921.1Skamil
55931.1Skamil	validate_status_stopped(status, sigval);
55941.1Skamil
55951.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55961.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
55971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55981.1Skamil
55991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56001.1Skamil	    "without signal to be sent\n");
56011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56021.1Skamil
56031.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
56041.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
56051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56061.1Skamil
56071.1Skamil	validate_status_stopped(status, SIGTRAP);
56081.1Skamil
56091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
56101.1Skamil
56111.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
56121.1Skamil
56131.1Skamil	lid = state.pe_lwp;
56141.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
56151.1Skamil
56161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56171.1Skamil	    "without signal to be sent\n");
56181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56191.1Skamil
56201.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
56211.1Skamil	    TWAIT_FNAME);
56221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56231.1Skamil
56241.1Skamil	validate_status_exited(status, exitval);
56251.1Skamil
56261.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
56271.1Skamil	    TWAIT_FNAME);
56281.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56291.1Skamil}
56301.1Skamil
56311.1SkamilATF_TC(signal1);
56321.1SkamilATF_TC_HEAD(signal1, tc)
56331.1Skamil{
56341.1Skamil	atf_tc_set_md_var(tc, "descr",
56351.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
56361.1Skamil	    "from catching other signals");
56371.1Skamil}
56381.1Skamil
56391.1SkamilATF_TC_BODY(signal1, tc)
56401.1Skamil{
56411.1Skamil	const int exitval = 5;
56421.1Skamil	const int sigval = SIGSTOP;
56431.1Skamil	const int sigmasked = SIGTRAP;
56441.1Skamil	const int signotmasked = SIGINT;
56451.1Skamil	pid_t child, wpid;
56461.1Skamil#if defined(TWAIT_HAVE_STATUS)
56471.1Skamil	int status;
56481.1Skamil#endif
56491.1Skamil	sigset_t intmask;
56501.1Skamil
56511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56531.1Skamil	if (child == 0) {
56541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56561.1Skamil
56571.1Skamil		sigemptyset(&intmask);
56581.1Skamil		sigaddset(&intmask, sigmasked);
56591.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56601.1Skamil
56611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56631.1Skamil
56641.13Schristos		DPRINTF("Before raising %s from child\n",
56651.1Skamil		    strsignal(signotmasked));
56661.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
56671.1Skamil
56681.13Schristos		DPRINTF("Before exiting of the child process\n");
56691.1Skamil		_exit(exitval);
56701.1Skamil	}
56711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56721.1Skamil
56731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56751.1Skamil
56761.1Skamil	validate_status_stopped(status, sigval);
56771.1Skamil
56781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56791.1Skamil	    "without signal to be sent\n");
56801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56811.1Skamil
56821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56841.1Skamil
56851.1Skamil	validate_status_stopped(status, signotmasked);
56861.1Skamil
56871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56881.1Skamil	    "without signal to be sent\n");
56891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56901.1Skamil
56911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56931.1Skamil
56941.1Skamil	validate_status_exited(status, exitval);
56951.1Skamil
56961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56981.1Skamil}
56991.1Skamil
57001.1SkamilATF_TC(signal2);
57011.1SkamilATF_TC_HEAD(signal2, tc)
57021.1Skamil{
57031.1Skamil	atf_tc_set_md_var(tc, "descr",
57041.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
57051.1Skamil	    "catching this raised signal");
57061.1Skamil}
57071.1Skamil
57081.1SkamilATF_TC_BODY(signal2, tc)
57091.1Skamil{
57101.1Skamil	const int exitval = 5;
57111.1Skamil	const int sigval = SIGSTOP;
57121.1Skamil	const int sigmasked = SIGTRAP;
57131.1Skamil	pid_t child, wpid;
57141.1Skamil#if defined(TWAIT_HAVE_STATUS)
57151.1Skamil	int status;
57161.1Skamil#endif
57171.1Skamil	sigset_t intmask;
57181.1Skamil
57191.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57201.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57211.1Skamil	if (child == 0) {
57221.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57231.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57241.1Skamil
57251.1Skamil		sigemptyset(&intmask);
57261.1Skamil		sigaddset(&intmask, sigmasked);
57271.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57281.1Skamil
57291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57311.1Skamil
57321.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
57331.1Skamil		    strsignal(sigmasked));
57341.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
57351.1Skamil
57361.13Schristos		DPRINTF("Before exiting of the child process\n");
57371.1Skamil		_exit(exitval);
57381.1Skamil	}
57391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57401.1Skamil
57411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57431.1Skamil
57441.1Skamil	validate_status_stopped(status, sigval);
57451.1Skamil
57461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57471.1Skamil	    "without signal to be sent\n");
57481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57491.1Skamil
57501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57521.1Skamil
57531.1Skamil	validate_status_exited(status, exitval);
57541.1Skamil
57551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57561.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57571.1Skamil}
57581.1Skamil
57591.1SkamilATF_TC(signal3);
57601.1SkamilATF_TC_HEAD(signal3, tc)
57611.1Skamil{
57621.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57631.1Skamil	atf_tc_set_md_var(tc, "descr",
57641.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57651.1Skamil	    "catching software breakpoints");
57661.1Skamil}
57671.1Skamil
57681.1SkamilATF_TC_BODY(signal3, tc)
57691.1Skamil{
57701.1Skamil	const int exitval = 5;
57711.1Skamil	const int sigval = SIGSTOP;
57721.1Skamil	const int sigmasked = SIGTRAP;
57731.1Skamil	pid_t child, wpid;
57741.1Skamil#if defined(TWAIT_HAVE_STATUS)
57751.1Skamil	int status;
57761.1Skamil#endif
57771.1Skamil	sigset_t intmask;
57781.1Skamil
57791.20Skamil	atf_tc_expect_fail("PR kern/51918");
57801.20Skamil
57811.20Skamil	// This test breaks now on some ports, temporarily disable it
57821.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
57831.20Skamil
57841.10Smartin#if defined(__sparc__)
57851.7Skamil	atf_tc_expect_timeout("PR kern/52167");
57861.7Skamil
57871.7Skamil	// timeout wins, failure still valid
57881.7Skamil	// atf_tc_expect_fail("PR kern/51918");
57891.7Skamil#endif
57901.1Skamil
57911.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57921.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57931.1Skamil	if (child == 0) {
57941.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57951.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57961.1Skamil
57971.1Skamil		sigemptyset(&intmask);
57981.1Skamil		sigaddset(&intmask, sigmasked);
57991.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58001.1Skamil
58011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58031.1Skamil
58041.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
58051.4Skamil
58061.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
58071.4Skamil		PTRACE_BREAKPOINT_ASM;
58081.1Skamil#else
58091.4Skamil		/* port me */
58101.1Skamil#endif
58111.1Skamil
58121.13Schristos		DPRINTF("Before exiting of the child process\n");
58131.1Skamil		_exit(exitval);
58141.1Skamil	}
58151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58161.1Skamil
58171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58191.1Skamil
58201.1Skamil	validate_status_stopped(status, sigval);
58211.1Skamil
58221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58231.1Skamil	    "without signal to be sent\n");
58241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58251.1Skamil
58261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58281.1Skamil
58291.1Skamil	validate_status_stopped(status, sigmasked);
58301.1Skamil
58311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58321.1Skamil	    "without signal to be sent\n");
58331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58341.1Skamil
58351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58371.1Skamil
58381.1Skamil	validate_status_exited(status, exitval);
58391.1Skamil
58401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58421.1Skamil}
58431.1Skamil
58441.1Skamil#if defined(PT_STEP)
58451.1SkamilATF_TC(signal4);
58461.1SkamilATF_TC_HEAD(signal4, tc)
58471.1Skamil{
58481.1Skamil	atf_tc_set_md_var(tc, "descr",
58491.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58501.1Skamil	    "catching single step trap");
58511.1Skamil}
58521.1Skamil
58531.1SkamilATF_TC_BODY(signal4, tc)
58541.1Skamil{
58551.1Skamil	const int exitval = 5;
58561.1Skamil	const int sigval = SIGSTOP;
58571.1Skamil	const int sigmasked = SIGTRAP;
58581.1Skamil	pid_t child, wpid;
58591.1Skamil#if defined(TWAIT_HAVE_STATUS)
58601.1Skamil	int status;
58611.1Skamil#endif
58621.1Skamil	sigset_t intmask;
58631.1Skamil	int happy;
58641.1Skamil
58651.1Skamil#if defined(__arm__)
58661.5Skamil	/* PT_STEP not supported on arm 32-bit */
58671.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
58681.1Skamil#endif
58691.1Skamil
58701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58721.1Skamil	if (child == 0) {
58731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58751.1Skamil
58761.1Skamil		happy = check_happy(100);
58771.1Skamil
58781.1Skamil		sigemptyset(&intmask);
58791.1Skamil		sigaddset(&intmask, sigmasked);
58801.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58811.1Skamil
58821.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58831.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58841.1Skamil
58851.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
58861.1Skamil
58871.13Schristos		DPRINTF("Before exiting of the child process\n");
58881.1Skamil		_exit(exitval);
58891.1Skamil	}
58901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58911.1Skamil
58921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58941.1Skamil
58951.1Skamil	validate_status_stopped(status, sigval);
58961.1Skamil
58971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58981.1Skamil	    "without signal to be sent\n");
58991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
59001.1Skamil
59011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59031.1Skamil
59041.1Skamil	validate_status_stopped(status, sigmasked);
59051.1Skamil
59061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59071.1Skamil	    "without signal to be sent\n");
59081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59091.1Skamil
59101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59121.1Skamil
59131.1Skamil	validate_status_exited(status, exitval);
59141.1Skamil
59151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59171.1Skamil}
59181.1Skamil#endif
59191.1Skamil
59201.1SkamilATF_TC(signal5);
59211.1SkamilATF_TC_HEAD(signal5, tc)
59221.1Skamil{
59231.1Skamil	atf_tc_set_md_var(tc, "descr",
59241.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59251.1Skamil	    "catching exec() breakpoint");
59261.1Skamil}
59271.1Skamil
59281.1SkamilATF_TC_BODY(signal5, tc)
59291.1Skamil{
59301.1Skamil	const int exitval = 5;
59311.1Skamil	const int sigval = SIGSTOP;
59321.1Skamil	const int sigmasked = SIGTRAP;
59331.1Skamil	pid_t child, wpid;
59341.1Skamil#if defined(TWAIT_HAVE_STATUS)
59351.1Skamil	int status;
59361.1Skamil#endif
59371.1Skamil	sigset_t intmask;
59381.1Skamil
59391.14Schristos	atf_tc_expect_fail("wrong signal");
59401.14Schristos
59411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59431.1Skamil	if (child == 0) {
59441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59461.1Skamil
59471.1Skamil		sigemptyset(&intmask);
59481.1Skamil		sigaddset(&intmask, sigmasked);
59491.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59501.1Skamil
59511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59531.1Skamil
59541.13Schristos		DPRINTF("Before calling execve(2) from child\n");
59551.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
59561.1Skamil
59571.13Schristos		DPRINTF("Before exiting of the child process\n");
59581.1Skamil		_exit(exitval);
59591.1Skamil	}
59601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59611.1Skamil
59621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59641.1Skamil
59651.1Skamil	validate_status_stopped(status, sigval);
59661.1Skamil
59671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59681.1Skamil	    "without signal to be sent\n");
59691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59701.1Skamil
59711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59731.1Skamil
59741.1Skamil	validate_status_stopped(status, sigmasked);
59751.1Skamil
59761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59771.1Skamil	    "without signal to be sent\n");
59781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59791.1Skamil
59801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59821.1Skamil
59831.1Skamil	validate_status_exited(status, exitval);
59841.1Skamil
59851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59861.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59871.1Skamil}
59881.1Skamil
59891.1Skamil#if defined(TWAIT_HAVE_PID)
59901.1SkamilATF_TC(signal6);
59911.1SkamilATF_TC_HEAD(signal6, tc)
59921.1Skamil{
59931.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
59941.1Skamil	atf_tc_set_md_var(tc, "descr",
59951.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59961.1Skamil	    "catching PTRACE_FORK breakpoint");
59971.1Skamil}
59981.1Skamil
59991.1SkamilATF_TC_BODY(signal6, tc)
60001.1Skamil{
60011.1Skamil	const int exitval = 5;
60021.1Skamil	const int exitval2 = 15;
60031.1Skamil	const int sigval = SIGSTOP;
60041.1Skamil	const int sigmasked = SIGTRAP;
60051.1Skamil	pid_t child, child2, wpid;
60061.1Skamil#if defined(TWAIT_HAVE_STATUS)
60071.1Skamil	int status;
60081.1Skamil#endif
60091.1Skamil	sigset_t intmask;
60101.1Skamil	ptrace_state_t state;
60111.1Skamil	const int slen = sizeof(state);
60121.1Skamil	ptrace_event_t event;
60131.1Skamil	const int elen = sizeof(event);
60141.1Skamil
60151.14Schristos	atf_tc_expect_timeout("PR kern/51918");
60161.14Schristos
60171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60191.1Skamil	if (child == 0) {
60201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60221.1Skamil
60231.1Skamil		sigemptyset(&intmask);
60241.1Skamil		sigaddset(&intmask, sigmasked);
60251.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60261.1Skamil
60271.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60281.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60291.1Skamil
60301.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
60311.1Skamil
60321.1Skamil		if (child2 == 0)
60331.1Skamil			_exit(exitval2);
60341.1Skamil
60351.1Skamil		FORKEE_REQUIRE_SUCCESS
60361.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60371.1Skamil
60381.1Skamil		forkee_status_exited(status, exitval2);
60391.1Skamil
60401.13Schristos		DPRINTF("Before exiting of the child process\n");
60411.1Skamil		_exit(exitval);
60421.1Skamil	}
60431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60441.1Skamil
60451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60471.1Skamil
60481.1Skamil	validate_status_stopped(status, sigval);
60491.1Skamil
60501.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
60511.1Skamil	event.pe_set_event = PTRACE_FORK;
60521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60531.1Skamil
60541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60551.1Skamil	    "without signal to be sent\n");
60561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60571.1Skamil
60581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60601.1Skamil
60611.1Skamil	validate_status_stopped(status, sigmasked);
60621.1Skamil
60631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60641.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60651.1Skamil
60661.1Skamil	child2 = state.pe_other_pid;
60671.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
60681.1Skamil
60691.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
60701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60711.1Skamil	    child2);
60721.1Skamil
60731.1Skamil	validate_status_stopped(status, SIGTRAP);
60741.1Skamil
60751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
60761.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60771.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
60781.1Skamil
60791.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
60801.1Skamil	    "without signal to be sent\n");
60811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
60821.1Skamil
60831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60841.1Skamil	    "without signal to be sent\n");
60851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60861.1Skamil
60871.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60881.1Skamil	    TWAIT_FNAME);
60891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60901.1Skamil	    child2);
60911.1Skamil
60921.1Skamil	validate_status_exited(status, exitval2);
60931.1Skamil
60941.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
60951.1Skamil	    TWAIT_FNAME);
60961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
60971.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
60981.1Skamil
60991.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61001.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
61011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61021.1Skamil
61031.1Skamil	validate_status_stopped(status, SIGCHLD);
61041.1Skamil
61051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61061.1Skamil	    "without signal to be sent\n");
61071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61081.1Skamil
61091.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61101.1Skamil	    TWAIT_FNAME);
61111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61121.1Skamil
61131.1Skamil	validate_status_exited(status, exitval);
61141.1Skamil
61151.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61161.1Skamil	    TWAIT_FNAME);
61171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61181.1Skamil}
61191.1Skamil#endif
61201.1Skamil
61211.1Skamil#if defined(TWAIT_HAVE_PID)
61221.1SkamilATF_TC(signal7);
61231.1SkamilATF_TC_HEAD(signal7, tc)
61241.1Skamil{
61251.1Skamil	atf_tc_set_md_var(tc, "descr",
61261.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61271.1Skamil	    "catching PTRACE_VFORK breakpoint");
61281.1Skamil}
61291.1Skamil
61301.1SkamilATF_TC_BODY(signal7, tc)
61311.1Skamil{
61321.1Skamil	const int exitval = 5;
61331.1Skamil	const int exitval2 = 15;
61341.1Skamil	const int sigval = SIGSTOP;
61351.1Skamil	const int sigmasked = SIGTRAP;
61361.1Skamil	pid_t child, child2, wpid;
61371.1Skamil#if defined(TWAIT_HAVE_STATUS)
61381.1Skamil	int status;
61391.1Skamil#endif
61401.1Skamil	sigset_t intmask;
61411.1Skamil	ptrace_state_t state;
61421.1Skamil	const int slen = sizeof(state);
61431.1Skamil	ptrace_event_t event;
61441.1Skamil	const int elen = sizeof(event);
61451.1Skamil
61461.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
61471.14Schristos
61481.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61491.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61501.1Skamil	if (child == 0) {
61511.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61521.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61531.1Skamil
61541.1Skamil		sigemptyset(&intmask);
61551.1Skamil		sigaddset(&intmask, sigmasked);
61561.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61571.1Skamil
61581.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61591.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61601.1Skamil
61611.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
61621.1Skamil
61631.1Skamil		if (child2 == 0)
61641.1Skamil			_exit(exitval2);
61651.1Skamil
61661.1Skamil		FORKEE_REQUIRE_SUCCESS
61671.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
61681.1Skamil
61691.1Skamil		forkee_status_exited(status, exitval2);
61701.1Skamil
61711.13Schristos		DPRINTF("Before exiting of the child process\n");
61721.1Skamil		_exit(exitval);
61731.1Skamil	}
61741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61751.1Skamil
61761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61781.1Skamil
61791.1Skamil	validate_status_stopped(status, sigval);
61801.1Skamil
61811.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
61821.1Skamil	event.pe_set_event = PTRACE_VFORK;
61831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
61841.1Skamil
61851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61861.1Skamil	    "without signal to be sent\n");
61871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61881.1Skamil
61891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61911.1Skamil
61921.1Skamil	validate_status_stopped(status, sigmasked);
61931.1Skamil
61941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61951.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61961.1Skamil
61971.1Skamil	child2 = state.pe_other_pid;
61981.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
61991.1Skamil
62001.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
62011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62021.1Skamil	    child2);
62031.1Skamil
62041.1Skamil	validate_status_stopped(status, SIGTRAP);
62051.1Skamil
62061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
62071.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
62081.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
62091.1Skamil
62101.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
62111.1Skamil	    "without signal to be sent\n");
62121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
62131.1Skamil
62141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62151.1Skamil	    "without signal to be sent\n");
62161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62171.1Skamil
62181.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
62191.1Skamil	    TWAIT_FNAME);
62201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62211.1Skamil	    child2);
62221.1Skamil
62231.1Skamil	validate_status_exited(status, exitval2);
62241.1Skamil
62251.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
62261.1Skamil	    TWAIT_FNAME);
62271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
62281.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
62291.1Skamil
62301.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62311.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
62321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62331.1Skamil
62341.1Skamil	validate_status_stopped(status, SIGCHLD);
62351.1Skamil
62361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62371.1Skamil	    "without signal to be sent\n");
62381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62391.1Skamil
62401.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62411.1Skamil	    TWAIT_FNAME);
62421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62431.1Skamil
62441.1Skamil	validate_status_exited(status, exitval);
62451.1Skamil
62461.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62471.1Skamil	    TWAIT_FNAME);
62481.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62491.1Skamil}
62501.1Skamil#endif
62511.1Skamil
62521.1SkamilATF_TC(signal8);
62531.1SkamilATF_TC_HEAD(signal8, tc)
62541.1Skamil{
62551.1Skamil	atf_tc_set_md_var(tc, "descr",
62561.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62571.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
62581.1Skamil}
62591.1Skamil
62601.1SkamilATF_TC_BODY(signal8, tc)
62611.1Skamil{
62621.1Skamil	const int exitval = 5;
62631.1Skamil	const int exitval2 = 15;
62641.1Skamil	const int sigval = SIGSTOP;
62651.1Skamil	const int sigmasked = SIGTRAP;
62661.1Skamil	pid_t child, child2, wpid;
62671.1Skamil#if defined(TWAIT_HAVE_STATUS)
62681.1Skamil	int status;
62691.1Skamil#endif
62701.1Skamil	sigset_t intmask;
62711.1Skamil	ptrace_state_t state;
62721.1Skamil	const int slen = sizeof(state);
62731.1Skamil	ptrace_event_t event;
62741.1Skamil	const int elen = sizeof(event);
62751.1Skamil
62761.14Schristos	atf_tc_expect_fail("PR kern/51918");
62771.14Schristos
62781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62801.1Skamil	if (child == 0) {
62811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62831.1Skamil
62841.1Skamil		sigemptyset(&intmask);
62851.1Skamil		sigaddset(&intmask, sigmasked);
62861.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62871.1Skamil
62881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62901.1Skamil
62911.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
62921.1Skamil
62931.1Skamil		if (child2 == 0)
62941.1Skamil			_exit(exitval2);
62951.1Skamil
62961.1Skamil		FORKEE_REQUIRE_SUCCESS
62971.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
62981.1Skamil
62991.1Skamil		forkee_status_exited(status, exitval2);
63001.1Skamil
63011.13Schristos		DPRINTF("Before exiting of the child process\n");
63021.1Skamil		_exit(exitval);
63031.1Skamil	}
63041.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63051.1Skamil
63061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63081.1Skamil
63091.1Skamil	validate_status_stopped(status, sigval);
63101.1Skamil
63111.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
63121.1Skamil	    child);
63131.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
63141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
63151.1Skamil
63161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63171.1Skamil	    "without signal to be sent\n");
63181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63191.1Skamil
63201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63221.1Skamil
63231.1Skamil	validate_status_stopped(status, sigmasked);
63241.1Skamil
63251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63261.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
63271.1Skamil
63281.1Skamil	child2 = state.pe_other_pid;
63291.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
63301.1Skamil
63311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63321.1Skamil	    "without signal to be sent\n");
63331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63341.1Skamil
63351.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63361.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
63371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63381.1Skamil
63391.1Skamil	validate_status_stopped(status, SIGCHLD);
63401.1Skamil
63411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63421.1Skamil	    "without signal to be sent\n");
63431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63441.1Skamil
63451.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63461.1Skamil	    TWAIT_FNAME);
63471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63481.1Skamil
63491.1Skamil	validate_status_exited(status, exitval);
63501.1Skamil
63511.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63521.1Skamil	    TWAIT_FNAME);
63531.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63541.1Skamil}
63551.1Skamil
63561.1SkamilATF_TC(signal9);
63571.1SkamilATF_TC_HEAD(signal9, tc)
63581.1Skamil{
63591.1Skamil	atf_tc_set_md_var(tc, "descr",
63601.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
63611.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
63621.1Skamil}
63631.1Skamil
63641.1SkamilATF_TC_BODY(signal9, tc)
63651.1Skamil{
63661.1Skamil	const int exitval = 5;
63671.1Skamil	const int sigval = SIGSTOP;
63681.1Skamil	const int sigmasked = SIGTRAP;
63691.1Skamil	pid_t child, wpid;
63701.1Skamil#if defined(TWAIT_HAVE_STATUS)
63711.1Skamil	int status;
63721.1Skamil#endif
63731.1Skamil	sigset_t intmask;
63741.1Skamil	ptrace_state_t state;
63751.1Skamil	const int slen = sizeof(state);
63761.1Skamil	ptrace_event_t event;
63771.1Skamil	const int elen = sizeof(event);
63781.1Skamil	ucontext_t uc;
63791.1Skamil	lwpid_t lid;
63801.1Skamil	static const size_t ssize = 16*1024;
63811.1Skamil	void *stack;
63821.1Skamil
63831.14Schristos	atf_tc_expect_fail("PR kern/51918");
63841.14Schristos
63851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63871.1Skamil	if (child == 0) {
63881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63901.1Skamil
63911.1Skamil		sigemptyset(&intmask);
63921.1Skamil		sigaddset(&intmask, sigmasked);
63931.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
63941.1Skamil
63951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63971.1Skamil
63981.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63991.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64001.1Skamil
64011.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64021.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
64031.1Skamil
64041.13Schristos		DPRINTF("Before creating new in child\n");
64051.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64061.1Skamil
64071.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64081.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64091.1Skamil
64101.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64111.1Skamil		    "are the same\n", lid, the_lwp_id);
64121.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64131.1Skamil
64141.13Schristos		DPRINTF("Before exiting of the child process\n");
64151.1Skamil		_exit(exitval);
64161.1Skamil	}
64171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64181.1Skamil
64191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64211.1Skamil
64221.1Skamil	validate_status_stopped(status, sigval);
64231.1Skamil
64241.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
64251.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
64261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
64271.1Skamil
64281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64291.1Skamil	    "without signal to be sent\n");
64301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64311.1Skamil
64321.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64331.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64351.1Skamil
64361.1Skamil	validate_status_stopped(status, sigmasked);
64371.1Skamil
64381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
64391.1Skamil
64401.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
64411.1Skamil
64421.1Skamil	lid = state.pe_lwp;
64431.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
64441.1Skamil
64451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64461.1Skamil	    "without signal to be sent\n");
64471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64481.1Skamil
64491.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64501.1Skamil	    TWAIT_FNAME);
64511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64521.1Skamil
64531.1Skamil	validate_status_exited(status, exitval);
64541.1Skamil
64551.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64561.1Skamil	    TWAIT_FNAME);
64571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64581.1Skamil}
64591.1Skamil
64601.1SkamilATF_TC(signal10);
64611.1SkamilATF_TC_HEAD(signal10, tc)
64621.1Skamil{
64631.1Skamil	atf_tc_set_md_var(tc, "descr",
64641.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
64651.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
64661.1Skamil}
64671.1Skamil
64681.1SkamilATF_TC_BODY(signal10, tc)
64691.1Skamil{
64701.1Skamil	const int exitval = 5;
64711.1Skamil	const int sigval = SIGSTOP;
64721.1Skamil	const int sigmasked = SIGTRAP;
64731.1Skamil	pid_t child, wpid;
64741.1Skamil#if defined(TWAIT_HAVE_STATUS)
64751.1Skamil	int status;
64761.1Skamil#endif
64771.1Skamil	sigset_t intmask;
64781.1Skamil	ptrace_state_t state;
64791.1Skamil	const int slen = sizeof(state);
64801.1Skamil	ptrace_event_t event;
64811.1Skamil	const int elen = sizeof(event);
64821.1Skamil	ucontext_t uc;
64831.1Skamil	lwpid_t lid;
64841.1Skamil	static const size_t ssize = 16*1024;
64851.1Skamil	void *stack;
64861.1Skamil
64871.14Schristos	atf_tc_expect_fail("PR kern/51918");
64881.14Schristos
64891.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64901.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64911.1Skamil	if (child == 0) {
64921.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64931.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64941.1Skamil
64951.1Skamil		sigemptyset(&intmask);
64961.1Skamil		sigaddset(&intmask, sigmasked);
64971.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
64981.1Skamil
64991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65011.1Skamil
65021.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
65031.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
65041.1Skamil
65051.13Schristos		DPRINTF("Before making context for new lwp in child\n");
65061.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
65071.1Skamil
65081.13Schristos		DPRINTF("Before creating new in child\n");
65091.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
65101.1Skamil
65111.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
65121.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
65131.1Skamil
65141.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
65151.1Skamil		    "are the same\n", lid, the_lwp_id);
65161.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
65171.1Skamil
65181.13Schristos		DPRINTF("Before exiting of the child process\n");
65191.1Skamil		_exit(exitval);
65201.1Skamil	}
65211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65221.1Skamil
65231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65251.1Skamil
65261.1Skamil	validate_status_stopped(status, sigval);
65271.1Skamil
65281.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
65291.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
65301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
65311.1Skamil
65321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65331.1Skamil	    "without signal to be sent\n");
65341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65351.1Skamil
65361.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65371.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65391.1Skamil
65401.1Skamil	validate_status_stopped(status, sigmasked);
65411.1Skamil
65421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
65431.1Skamil
65441.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
65451.1Skamil
65461.1Skamil	lid = state.pe_lwp;
65471.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
65481.1Skamil
65491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65501.1Skamil	    "without signal to be sent\n");
65511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65521.1Skamil
65531.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65541.1Skamil	    TWAIT_FNAME);
65551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65561.1Skamil
65571.1Skamil	validate_status_exited(status, exitval);
65581.1Skamil
65591.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65601.1Skamil	    TWAIT_FNAME);
65611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65621.1Skamil}
65631.1Skamil
65641.1Skamilstatic void
65651.1Skamillwp_main_stop(void *arg)
65661.1Skamil{
65671.1Skamil	the_lwp_id = _lwp_self();
65681.1Skamil
65691.1Skamil	raise(SIGTRAP);
65701.1Skamil
65711.1Skamil	_lwp_exit();
65721.1Skamil}
65731.1Skamil
65741.1SkamilATF_TC(suspend1);
65751.1SkamilATF_TC_HEAD(suspend1, tc)
65761.1Skamil{
65771.1Skamil	atf_tc_set_md_var(tc, "descr",
65781.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
65791.1Skamil	    "resumed by a tracee");
65801.1Skamil}
65811.1Skamil
65821.1SkamilATF_TC_BODY(suspend1, tc)
65831.1Skamil{
65841.1Skamil	const int exitval = 5;
65851.1Skamil	const int sigval = SIGSTOP;
65861.1Skamil	pid_t child, wpid;
65871.1Skamil#if defined(TWAIT_HAVE_STATUS)
65881.1Skamil	int status;
65891.1Skamil#endif
65901.1Skamil	ucontext_t uc;
65911.1Skamil	lwpid_t lid;
65921.1Skamil	static const size_t ssize = 16*1024;
65931.1Skamil	void *stack;
65941.1Skamil	struct ptrace_lwpinfo pl;
65951.1Skamil	struct ptrace_siginfo psi;
65961.1Skamil	volatile int go = 0;
65971.1Skamil
65981.17Skamil	// Feature pending for refactoring
65991.17Skamil	atf_tc_expect_fail("PR kern/51995");
66001.17Skamil
66011.16Skamil	// Hangs with qemu
66021.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
66031.16Skamil
66041.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66051.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66061.1Skamil	if (child == 0) {
66071.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66081.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66091.1Skamil
66101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66121.1Skamil
66131.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
66141.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
66151.1Skamil
66161.13Schristos		DPRINTF("Before making context for new lwp in child\n");
66171.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
66181.1Skamil
66191.13Schristos		DPRINTF("Before creating new in child\n");
66201.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
66211.1Skamil
66221.1Skamil		while (go == 0)
66231.1Skamil			continue;
66241.1Skamil
66251.1Skamil		raise(SIGINT);
66261.1Skamil
66271.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
66281.1Skamil
66291.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
66301.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
66311.1Skamil
66321.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
66331.1Skamil		    "are the same\n", lid, the_lwp_id);
66341.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
66351.1Skamil
66361.13Schristos		DPRINTF("Before exiting of the child process\n");
66371.1Skamil		_exit(exitval);
66381.1Skamil	}
66391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66401.1Skamil
66411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66431.1Skamil
66441.1Skamil	validate_status_stopped(status, sigval);
66451.1Skamil
66461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66471.1Skamil	    "without signal to be sent\n");
66481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66491.1Skamil
66501.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66511.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
66521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66531.1Skamil
66541.1Skamil	validate_status_stopped(status, SIGTRAP);
66551.1Skamil
66561.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
66571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
66581.1Skamil
66591.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
66601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
66611.1Skamil
66621.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
66631.1Skamil	    child, getpid());
66641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
66651.1Skamil
66661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66671.1Skamil	    "without signal to be sent\n");
66681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66691.1Skamil
66701.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66711.1Skamil	    "SIGINT\n", TWAIT_FNAME);
66721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66731.1Skamil
66741.1Skamil	validate_status_stopped(status, SIGINT);
66751.1Skamil
66761.1Skamil	pl.pl_lwpid = 0;
66771.1Skamil
66781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66791.1Skamil	while (pl.pl_lwpid != 0) {
66801.1Skamil
66811.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66821.1Skamil		switch (pl.pl_lwpid) {
66831.1Skamil		case 1:
66841.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
66851.1Skamil			break;
66861.1Skamil		case 2:
66871.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
66881.1Skamil			break;
66891.1Skamil		}
66901.1Skamil	}
66911.1Skamil
66921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66931.1Skamil	    "without signal to be sent\n");
66941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66951.1Skamil
66961.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
66971.1Skamil	    TWAIT_FNAME);
66981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66991.1Skamil
67001.1Skamil	validate_status_exited(status, exitval);
67011.1Skamil
67021.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
67031.1Skamil	    TWAIT_FNAME);
67041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67051.1Skamil}
67061.1Skamil
67071.1SkamilATF_TC(suspend2);
67081.1SkamilATF_TC_HEAD(suspend2, tc)
67091.1Skamil{
67101.1Skamil	atf_tc_set_md_var(tc, "descr",
67111.1Skamil	    "Verify that the while the only thread within a process is "
67121.1Skamil	    "suspended, the whole process cannot be unstopped");
67131.1Skamil}
67141.1Skamil
67151.1SkamilATF_TC_BODY(suspend2, tc)
67161.1Skamil{
67171.1Skamil	const int exitval = 5;
67181.1Skamil	const int sigval = SIGSTOP;
67191.1Skamil	pid_t child, wpid;
67201.1Skamil#if defined(TWAIT_HAVE_STATUS)
67211.1Skamil	int status;
67221.1Skamil#endif
67231.1Skamil	struct ptrace_siginfo psi;
67241.1Skamil
67251.17Skamil	// Feature pending for refactoring
67261.17Skamil	atf_tc_expect_fail("PR kern/51995");
67271.17Skamil
67281.16Skamil	// Hangs with qemu
67291.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
67301.16Skamil
67311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67331.1Skamil	if (child == 0) {
67341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67361.1Skamil
67371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67391.1Skamil
67401.13Schristos		DPRINTF("Before exiting of the child process\n");
67411.1Skamil		_exit(exitval);
67421.1Skamil	}
67431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67441.1Skamil
67451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67471.1Skamil
67481.1Skamil	validate_status_stopped(status, sigval);
67491.1Skamil
67501.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
67511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
67521.1Skamil
67531.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
67541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
67551.1Skamil
67561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67571.1Skamil	    "without signal to be sent\n");
67581.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
67591.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
67601.1Skamil
67611.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
67621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
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 - expected exited\n",
67691.1Skamil	    TWAIT_FNAME);
67701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67711.1Skamil
67721.1Skamil	validate_status_exited(status, exitval);
67731.1Skamil
67741.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
67751.1Skamil	    TWAIT_FNAME);
67761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67771.1Skamil}
67781.1Skamil
67791.1SkamilATF_TC(resume1);
67801.1SkamilATF_TC_HEAD(resume1, tc)
67811.1Skamil{
67821.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
67831.1Skamil	atf_tc_set_md_var(tc, "descr",
67841.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
67851.1Skamil	    "resumed by the debugger");
67861.1Skamil}
67871.1Skamil
67881.1SkamilATF_TC_BODY(resume1, tc)
67891.1Skamil{
67901.1Skamil	struct msg_fds fds;
67911.1Skamil	const int exitval = 5;
67921.1Skamil	const int sigval = SIGSTOP;
67931.1Skamil	pid_t child, wpid;
67941.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
67951.1Skamil#if defined(TWAIT_HAVE_STATUS)
67961.1Skamil	int status;
67971.1Skamil#endif
67981.1Skamil	ucontext_t uc;
67991.1Skamil	lwpid_t lid;
68001.1Skamil	static const size_t ssize = 16*1024;
68011.1Skamil	void *stack;
68021.1Skamil	struct ptrace_lwpinfo pl;
68031.1Skamil	struct ptrace_siginfo psi;
68041.1Skamil
68051.17Skamil	// Feature pending for refactoring
68061.17Skamil	atf_tc_expect_fail("PR kern/51995");
68071.17Skamil
68081.15Schristos	// Hangs with qemu
68091.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
68101.1Skamil
68111.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
68121.1Skamil
68131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
68141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
68151.1Skamil	if (child == 0) {
68161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68181.1Skamil
68191.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68201.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68211.1Skamil
68221.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
68231.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
68241.1Skamil
68251.13Schristos		DPRINTF("Before making context for new lwp in child\n");
68261.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
68271.1Skamil
68281.13Schristos		DPRINTF("Before creating new in child\n");
68291.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
68301.1Skamil
68311.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
68321.1Skamil
68331.1Skamil		raise(SIGINT);
68341.1Skamil
68351.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
68361.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
68371.1Skamil
68381.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
68391.1Skamil		    "are the same\n", lid, the_lwp_id);
68401.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
68411.1Skamil
68421.13Schristos		DPRINTF("Before exiting of the child process\n");
68431.1Skamil		_exit(exitval);
68441.1Skamil	}
68451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68461.1Skamil
68471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68491.1Skamil
68501.1Skamil	validate_status_stopped(status, sigval);
68511.1Skamil
68521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68531.1Skamil	    "without signal to be sent\n");
68541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68551.1Skamil
68561.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68571.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
68581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68591.1Skamil
68601.1Skamil	validate_status_stopped(status, SIGTRAP);
68611.1Skamil
68621.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
68631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
68641.1Skamil
68651.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
68661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
68671.1Skamil
68681.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
68691.1Skamil
68701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68711.1Skamil	    "without signal to be sent\n");
68721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68731.1Skamil
68741.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68751.1Skamil	    "SIGINT\n", TWAIT_FNAME);
68761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68771.1Skamil
68781.1Skamil	validate_status_stopped(status, SIGINT);
68791.1Skamil
68801.1Skamil	pl.pl_lwpid = 0;
68811.1Skamil
68821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68831.1Skamil	while (pl.pl_lwpid != 0) {
68841.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68851.1Skamil		switch (pl.pl_lwpid) {
68861.1Skamil		case 1:
68871.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
68881.1Skamil			break;
68891.1Skamil		case 2:
68901.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
68911.1Skamil			break;
68921.1Skamil		}
68931.1Skamil	}
68941.1Skamil
68951.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
68961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
68971.1Skamil
68981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68991.1Skamil	    "without signal to be sent\n");
69001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69011.1Skamil
69021.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
69031.1Skamil	    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 - expected no process\n",
69091.1Skamil	    TWAIT_FNAME);
69101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69111.1Skamil
69121.1Skamil	msg_close(&fds);
69131.1Skamil
69141.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
69151.1Skamil	sleep(10);
69161.1Skamil}
69171.1Skamil
69181.1SkamilATF_TC(syscall1);
69191.1SkamilATF_TC_HEAD(syscall1, tc)
69201.1Skamil{
69211.1Skamil	atf_tc_set_md_var(tc, "descr",
69221.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
69231.1Skamil}
69241.1Skamil
69251.1SkamilATF_TC_BODY(syscall1, tc)
69261.1Skamil{
69271.1Skamil	const int exitval = 5;
69281.1Skamil	const int sigval = SIGSTOP;
69291.1Skamil	pid_t child, wpid;
69301.1Skamil#if defined(TWAIT_HAVE_STATUS)
69311.1Skamil	int status;
69321.1Skamil#endif
69331.1Skamil	struct ptrace_siginfo info;
69341.1Skamil	memset(&info, 0, sizeof(info));
69351.1Skamil
69361.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69371.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69381.1Skamil	if (child == 0) {
69391.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69401.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69411.1Skamil
69421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
69441.1Skamil
69451.1Skamil		syscall(SYS_getpid);
69461.1Skamil
69471.13Schristos		DPRINTF("Before exiting of the child process\n");
69481.1Skamil		_exit(exitval);
69491.1Skamil	}
69501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
69511.1Skamil
69521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69541.1Skamil
69551.1Skamil	validate_status_stopped(status, sigval);
69561.1Skamil
69571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69581.1Skamil	    "without signal to be sent\n");
69591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69601.1Skamil
69611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69631.1Skamil
69641.1Skamil	validate_status_stopped(status, SIGTRAP);
69651.1Skamil
69661.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69681.1Skamil
69691.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69701.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
69711.1Skamil
69721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69731.1Skamil	    "without signal to be sent\n");
69741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69751.1Skamil
69761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69781.1Skamil
69791.1Skamil	validate_status_stopped(status, SIGTRAP);
69801.1Skamil
69811.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69831.1Skamil
69841.13Schristos	DPRINTF("Before checking siginfo_t\n");
69851.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69861.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
69871.1Skamil
69881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69891.1Skamil	    "without signal to be sent\n");
69901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69911.1Skamil
69921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69941.1Skamil
69951.1Skamil	validate_status_exited(status, exitval);
69961.1Skamil
69971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69991.1Skamil}
70001.1Skamil
70011.1SkamilATF_TC(syscallemu1);
70021.1SkamilATF_TC_HEAD(syscallemu1, tc)
70031.1Skamil{
70041.1Skamil	atf_tc_set_md_var(tc, "descr",
70051.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
70061.1Skamil}
70071.1Skamil
70081.1SkamilATF_TC_BODY(syscallemu1, tc)
70091.1Skamil{
70101.1Skamil	const int exitval = 5;
70111.1Skamil	const int sigval = SIGSTOP;
70121.1Skamil	pid_t child, wpid;
70131.1Skamil#if defined(TWAIT_HAVE_STATUS)
70141.1Skamil	int status;
70151.1Skamil#endif
70161.1Skamil
70171.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
70181.6Skamil	/* syscallemu does not work on sparc (32-bit) */
70191.6Skamil	atf_tc_expect_fail("PR kern/52166");
70201.6Skamil#endif
70211.6Skamil
70221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
70231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
70241.1Skamil	if (child == 0) {
70251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
70261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
70271.1Skamil
70281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70301.1Skamil
70311.1Skamil		syscall(SYS_exit, 100);
70321.1Skamil
70331.13Schristos		DPRINTF("Before exiting of the child process\n");
70341.1Skamil		_exit(exitval);
70351.1Skamil	}
70361.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70371.1Skamil
70381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70401.1Skamil
70411.1Skamil	validate_status_stopped(status, sigval);
70421.1Skamil
70431.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70441.1Skamil	    "without signal to be sent\n");
70451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70461.1Skamil
70471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70491.1Skamil
70501.1Skamil	validate_status_stopped(status, SIGTRAP);
70511.1Skamil
70521.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
70531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
70541.1Skamil
70551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70561.1Skamil	    "without signal to be sent\n");
70571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70581.1Skamil
70591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70611.1Skamil
70621.1Skamil	validate_status_stopped(status, SIGTRAP);
70631.1Skamil
70641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70651.1Skamil	    "without signal to be sent\n");
70661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70671.1Skamil
70681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70701.1Skamil
70711.1Skamil	validate_status_exited(status, exitval);
70721.1Skamil
70731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70751.1Skamil}
70761.1Skamil
70771.26Skamil#if defined(TWAIT_HAVE_PID)
70781.26SkamilATF_TC(race1);
70791.26SkamilATF_TC_HEAD(race1, tc)
70801.26Skamil{
70811.26Skamil	atf_tc_set_md_var(tc, "descr",
70821.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
70831.26Skamil	    "process and no other error is reported");
70841.26Skamil}
70851.26Skamil
70861.26SkamilATF_TC_BODY(race1, tc)
70871.26Skamil{
70881.26Skamil	time_t start, end;
70891.26Skamil	double diff;
70901.26Skamil	unsigned long N = 0;
70911.26Skamil
70921.26Skamil	/* Reuse this test with attach1 */
70931.26Skamil
70941.26Skamil	start = time(NULL);
70951.26Skamil	while (true) {
70961.26Skamil		DPRINTF("Step: %lu\n", N);
70971.26Skamil		attach1_raw(true);
70981.26Skamil		end = time(NULL);
70991.26Skamil		diff = difftime(end, start);
71001.26Skamil		if (diff >= 5.0)
71011.26Skamil			break;
71021.26Skamil		++N;
71031.26Skamil	}
71041.26Skamil	DPRINTF("Iterations: %lu\n", N);
71051.26Skamil}
71061.26Skamil#endif
71071.26Skamil
71081.1Skamil#include "t_ptrace_amd64_wait.h"
71091.1Skamil#include "t_ptrace_i386_wait.h"
71101.1Skamil#include "t_ptrace_x86_wait.h"
71111.1Skamil
71121.1SkamilATF_TP_ADD_TCS(tp)
71131.1Skamil{
71141.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
71151.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
71161.1Skamil	ATF_TP_ADD_TC(tp, traceme1);
71171.1Skamil	ATF_TP_ADD_TC(tp, traceme2);
71181.1Skamil	ATF_TP_ADD_TC(tp, traceme3);
71191.1Skamil	ATF_TP_ADD_TC(tp, traceme4);
71201.1Skamil
71211.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
71221.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
71231.1Skamil	ATF_TP_ADD_TC(tp, attach3);
71241.1Skamil	ATF_TP_ADD_TC(tp, attach4);
71251.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
71261.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
71271.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
71281.1Skamil
71291.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
71301.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
71311.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
71321.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
71331.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
71341.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
71351.1Skamil
71361.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork1);
71371.1Skamil	ATF_TP_ADD_TC(tp, fork2);
71381.1Skamil
71391.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork1);
71401.1Skamil	ATF_TP_ADD_TC(tp, vfork2);
71411.1Skamil
71421.1Skamil	ATF_TP_ADD_TC(tp, vforkdone1);
71431.1Skamil	ATF_TP_ADD_TC(tp, vforkdone2);
71441.1Skamil
71451.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
71461.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
71471.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
71481.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
71491.1Skamil
71501.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
71511.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
71521.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
71531.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
71541.1Skamil
71551.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
71561.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
71571.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
71581.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
71591.1Skamil
71601.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
71611.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
71621.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
71631.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
71641.1Skamil
71651.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
71661.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
71671.1Skamil
71681.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
71691.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
71701.1Skamil
71711.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
71721.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
71731.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
71741.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
71751.1Skamil
71761.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
71771.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
71781.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
71791.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
71801.1Skamil
71811.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
71821.1Skamil
71831.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
71841.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
71851.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
71861.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
71871.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
71881.1Skamil
71891.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
71901.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
71911.1Skamil
71921.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
71931.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
71941.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
71951.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
71961.1Skamil
71971.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
71981.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
71991.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
72001.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
72011.2Skamil
72021.1Skamil	ATF_TP_ADD_TC(tp, kill1);
72031.1Skamil	ATF_TP_ADD_TC(tp, kill2);
72041.1Skamil
72051.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
72061.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
72071.1Skamil
72081.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
72091.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
72101.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
72111.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
72121.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
72131.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
72141.1Skamil
72151.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
72161.1Skamil
72171.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
72181.1Skamil
72191.1Skamil	ATF_TP_ADD_TC(tp, signal1);
72201.1Skamil	ATF_TP_ADD_TC(tp, signal2);
72211.1Skamil	ATF_TP_ADD_TC(tp, signal3);
72221.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
72231.1Skamil	ATF_TP_ADD_TC(tp, signal5);
72241.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
72251.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
72261.1Skamil	ATF_TP_ADD_TC(tp, signal8);
72271.1Skamil	ATF_TP_ADD_TC(tp, signal9);
72281.1Skamil	ATF_TP_ADD_TC(tp, signal10);
72291.1Skamil
72301.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
72311.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
72321.1Skamil
72331.1Skamil	ATF_TP_ADD_TC(tp, resume1);
72341.1Skamil
72351.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
72361.1Skamil
72371.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
72381.1Skamil
72391.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
72401.26Skamil
72411.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
72421.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
72431.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
72441.1Skamil
72451.1Skamil	return atf_no_error();
72461.1Skamil}
7247