t_ptrace_wait.c revision 1.24
11.24Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.24 2018/03/07 10:53:55 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.24Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.24 2018/03/07 10:53:55 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.1Skamil#include <unistd.h>
521.1Skamil
531.1Skamil#include <atf-c.h>
541.1Skamil
551.1Skamil#include "h_macros.h"
561.1Skamil
571.1Skamil#include "t_ptrace_wait.h"
581.1Skamil#include "msg.h"
591.1Skamil
601.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
611.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
621.1Skamil
631.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
641.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
651.1Skamil
661.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
671.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
681.1Skamil
691.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
701.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
711.13Schristos
721.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
731.13Schristos    strerror(errno))
741.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
751.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
761.13Schristos
771.13Schristosstatic int debug = 0;
781.13Schristos
791.13Schristos#define DPRINTF(a, ...)	do  \
801.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
811.13Schristos    while (/*CONSTCOND*/0)
821.1Skamil
831.1Skamil
841.1SkamilATF_TC(traceme1);
851.1SkamilATF_TC_HEAD(traceme1, tc)
861.1Skamil{
871.1Skamil	atf_tc_set_md_var(tc, "descr",
881.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
891.1Skamil}
901.1Skamil
911.1SkamilATF_TC_BODY(traceme1, tc)
921.1Skamil{
931.1Skamil	const int exitval = 5;
941.1Skamil	const int sigval = SIGSTOP;
951.1Skamil	pid_t child, wpid;
961.1Skamil#if defined(TWAIT_HAVE_STATUS)
971.1Skamil	int status;
981.1Skamil#endif
991.1Skamil
1001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1021.1Skamil	if (child == 0) {
1031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1051.1Skamil
1061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1081.1Skamil
1091.13Schristos		DPRINTF("Before exiting of the child process\n");
1101.1Skamil		_exit(exitval);
1111.1Skamil	}
1121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1131.1Skamil
1141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1161.1Skamil
1171.1Skamil	validate_status_stopped(status, sigval);
1181.1Skamil
1191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
1201.1Skamil	    "without signal to be sent\n");
1211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1221.1Skamil
1231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1251.1Skamil
1261.1Skamil	validate_status_exited(status, exitval);
1271.1Skamil
1281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1301.1Skamil}
1311.1Skamil
1321.1SkamilATF_TC(traceme2);
1331.1SkamilATF_TC_HEAD(traceme2, tc)
1341.1Skamil{
1351.1Skamil	atf_tc_set_md_var(tc, "descr",
1361.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
1371.1Skamil}
1381.1Skamil
1391.1Skamilstatic int traceme2_caught = 0;
1401.1Skamil
1411.1Skamilstatic void
1421.1Skamiltraceme2_sighandler(int sig)
1431.1Skamil{
1441.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
1451.1Skamil
1461.1Skamil	++traceme2_caught;
1471.1Skamil}
1481.1Skamil
1491.1SkamilATF_TC_BODY(traceme2, tc)
1501.1Skamil{
1511.1Skamil	const int exitval = 5;
1521.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT;
1531.1Skamil	pid_t child, wpid;
1541.1Skamil	struct sigaction sa;
1551.1Skamil#if defined(TWAIT_HAVE_STATUS)
1561.1Skamil	int status;
1571.1Skamil#endif
1581.1Skamil
1591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1611.1Skamil	if (child == 0) {
1621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1641.1Skamil
1651.1Skamil		sa.sa_handler = traceme2_sighandler;
1661.1Skamil		sa.sa_flags = SA_SIGINFO;
1671.1Skamil		sigemptyset(&sa.sa_mask);
1681.1Skamil
1691.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1701.1Skamil
1711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1731.1Skamil
1741.1Skamil		FORKEE_ASSERT_EQ(traceme2_caught, 1);
1751.1Skamil
1761.13Schristos		DPRINTF("Before exiting of the child process\n");
1771.1Skamil		_exit(exitval);
1781.1Skamil	}
1791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1801.1Skamil
1811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1831.1Skamil
1841.1Skamil	validate_status_stopped(status, sigval);
1851.1Skamil
1861.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
1871.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
1881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1891.1Skamil
1901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1921.1Skamil
1931.1Skamil	validate_status_exited(status, exitval);
1941.1Skamil
1951.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1971.1Skamil}
1981.1Skamil
1991.1SkamilATF_TC(traceme3);
2001.1SkamilATF_TC_HEAD(traceme3, tc)
2011.1Skamil{
2021.1Skamil	atf_tc_set_md_var(tc, "descr",
2031.1Skamil	    "Verify SIGSTOP followed by termination by a signal in a child");
2041.1Skamil}
2051.1Skamil
2061.1SkamilATF_TC_BODY(traceme3, tc)
2071.1Skamil{
2081.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
2091.1Skamil	pid_t child, wpid;
2101.1Skamil#if defined(TWAIT_HAVE_STATUS)
2111.1Skamil	int status;
2121.1Skamil#endif
2131.1Skamil
2141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2161.1Skamil	if (child == 0) {
2171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2191.1Skamil
2201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2221.1Skamil
2231.1Skamil		/* NOTREACHED */
2241.1Skamil		FORKEE_ASSERTX(0 &&
2251.1Skamil		    "Child should be terminated by a signal from its parent");
2261.1Skamil	}
2271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2281.1Skamil
2291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2311.1Skamil
2321.1Skamil	validate_status_stopped(status, sigval);
2331.1Skamil
2341.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2351.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2371.1Skamil
2381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2401.1Skamil
2411.1Skamil	validate_status_signaled(status, sigsent, 0);
2421.1Skamil
2431.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2451.1Skamil}
2461.1Skamil
2471.1SkamilATF_TC(traceme4);
2481.1SkamilATF_TC_HEAD(traceme4, tc)
2491.1Skamil{
2501.1Skamil	atf_tc_set_md_var(tc, "descr",
2511.1Skamil	    "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child");
2521.1Skamil}
2531.1Skamil
2541.1SkamilATF_TC_BODY(traceme4, tc)
2551.1Skamil{
2561.1Skamil	const int exitval = 5;
2571.1Skamil	const int sigval = SIGSTOP, sigsent = SIGCONT;
2581.1Skamil	pid_t child, wpid;
2591.1Skamil#if defined(TWAIT_HAVE_STATUS)
2601.1Skamil	int status;
2611.1Skamil#endif
2621.1Skamil
2631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2651.1Skamil	if (child == 0) {
2661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2681.1Skamil
2691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2711.1Skamil
2721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigsent));
2731.1Skamil		FORKEE_ASSERT(raise(sigsent) == 0);
2741.1Skamil
2751.13Schristos		DPRINTF("Before exiting of the child process\n");
2761.1Skamil		_exit(exitval);
2771.1Skamil	}
2781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),child);
2791.1Skamil
2801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2821.1Skamil
2831.1Skamil	validate_status_stopped(status, sigval);
2841.1Skamil
2851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2861.1Skamil	    "without signal to be sent\n");
2871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2881.1Skamil
2891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2911.1Skamil
2921.1Skamil	validate_status_stopped(status, sigsent);
2931.1Skamil
2941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2951.1Skamil	    "without signal to be sent\n");
2961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2971.1Skamil
2981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3001.1Skamil
3011.1Skamil	validate_status_exited(status, exitval);
3021.1Skamil
3031.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
3041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3051.1Skamil}
3061.1Skamil
3071.1Skamil#if defined(TWAIT_HAVE_PID)
3081.1SkamilATF_TC(attach1);
3091.1SkamilATF_TC_HEAD(attach1, tc)
3101.1Skamil{
3111.1Skamil	atf_tc_set_md_var(tc, "descr",
3121.1Skamil	    "Assert that tracer sees process termination before the parent");
3131.1Skamil}
3141.1Skamil
3151.1SkamilATF_TC_BODY(attach1, tc)
3161.1Skamil{
3171.1Skamil	struct msg_fds parent_tracee, parent_tracer;
3181.1Skamil	const int exitval_tracee = 5;
3191.1Skamil	const int exitval_tracer = 10;
3201.1Skamil	pid_t tracee, tracer, wpid;
3211.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3221.1Skamil#if defined(TWAIT_HAVE_STATUS)
3231.1Skamil	int status;
3241.1Skamil#endif
3251.1Skamil
3261.13Schristos	DPRINTF("Spawn tracee\n");
3271.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3281.1Skamil	tracee = atf_utils_fork();
3291.1Skamil	if (tracee == 0) {
3301.1Skamil		// Wait for parent to let us exit
3311.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3321.1Skamil		_exit(exitval_tracee);
3331.1Skamil	}
3341.1Skamil
3351.13Schristos	DPRINTF("Spawn debugger\n");
3361.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3371.1Skamil	tracer = atf_utils_fork();
3381.1Skamil	if (tracer == 0) {
3391.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3401.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3411.1Skamil
3421.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3431.1Skamil		FORKEE_REQUIRE_SUCCESS(
3441.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3451.1Skamil
3461.1Skamil		forkee_status_stopped(status, SIGSTOP);
3471.1Skamil
3481.1Skamil		/* Resume tracee with PT_CONTINUE */
3491.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3501.1Skamil
3511.1Skamil		/* Inform parent that tracer has attached to tracee */
3521.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3531.1Skamil
3541.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3551.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3561.1Skamil
3571.1Skamil		/* Wait for tracee and assert that it exited */
3581.1Skamil		FORKEE_REQUIRE_SUCCESS(
3591.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3601.1Skamil
3611.1Skamil		forkee_status_exited(status, exitval_tracee);
3621.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3631.1Skamil
3641.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3651.1Skamil		_exit(exitval_tracer);
3661.1Skamil	}
3671.1Skamil
3681.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3691.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3701.1Skamil
3711.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3721.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3731.1Skamil
3741.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3751.1Skamil	await_zombie(tracee);
3761.1Skamil
3771.1Skamil
3781.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3791.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3801.1Skamil	    TWAIT_FNAME);
3811.1Skamil	TWAIT_REQUIRE_SUCCESS(
3821.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
3831.1Skamil
3841.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
3851.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
3861.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3871.1Skamil	    TWAIT_FNAME);
3881.1Skamil
3891.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
3901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3911.1Skamil	    tracer);
3921.1Skamil
3931.1Skamil	validate_status_exited(status, exitval_tracer);
3941.1Skamil
3951.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
3961.1Skamil	    TWAIT_FNAME);
3971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
3981.1Skamil	    tracee);
3991.1Skamil
4001.1Skamil	validate_status_exited(status, exitval_tracee);
4011.1Skamil
4021.1Skamil	msg_close(&parent_tracer);
4031.1Skamil	msg_close(&parent_tracee);
4041.1Skamil}
4051.1Skamil#endif
4061.1Skamil
4071.1Skamil#if defined(TWAIT_HAVE_PID)
4081.1SkamilATF_TC(attach2);
4091.1SkamilATF_TC_HEAD(attach2, tc)
4101.1Skamil{
4111.1Skamil	atf_tc_set_md_var(tc, "descr",
4121.1Skamil	    "Assert that any tracer sees process termination before its "
4131.1Skamil	    "parent");
4141.1Skamil}
4151.1Skamil
4161.1SkamilATF_TC_BODY(attach2, tc)
4171.1Skamil{
4181.1Skamil	struct msg_fds parent_tracer, parent_tracee;
4191.1Skamil	const int exitval_tracee = 5;
4201.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
4211.1Skamil	pid_t tracee, tracer, wpid;
4221.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4231.1Skamil#if defined(TWAIT_HAVE_STATUS)
4241.1Skamil	int status;
4251.1Skamil#endif
4261.1Skamil
4271.19Skamil	// Feature pending for refactoring
4281.19Skamil	atf_tc_expect_fail("test is racy");
4291.19Skamil
4301.13Schristos	DPRINTF("Spawn tracee\n");
4311.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4321.1Skamil	tracee = atf_utils_fork();
4331.1Skamil	if (tracee == 0) {
4341.1Skamil		/* Wait for message from the parent */
4351.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4361.1Skamil		_exit(exitval_tracee);
4371.1Skamil	}
4381.1Skamil
4391.13Schristos	DPRINTF("Spawn debugger\n");
4401.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4411.1Skamil	tracer = atf_utils_fork();
4421.1Skamil	if (tracer == 0) {
4431.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4441.1Skamil		tracer = atf_utils_fork();
4451.1Skamil		if (tracer != 0)
4461.1Skamil			_exit(exitval_tracer1);
4471.1Skamil
4481.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4491.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4501.1Skamil
4511.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4521.1Skamil		FORKEE_REQUIRE_SUCCESS(
4531.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4541.1Skamil
4551.1Skamil		forkee_status_stopped(status, SIGSTOP);
4561.1Skamil
4571.1Skamil		/* Resume tracee with PT_CONTINUE */
4581.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4591.1Skamil
4601.1Skamil		/* Inform parent that tracer has attached to tracee */
4611.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4621.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4631.1Skamil
4641.1Skamil		/* Wait for tracee and assert that it exited */
4651.1Skamil		FORKEE_REQUIRE_SUCCESS(
4661.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4671.1Skamil
4681.1Skamil		forkee_status_exited(status, exitval_tracee);
4691.1Skamil
4701.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4711.1Skamil		_exit(exitval_tracer2);
4721.1Skamil	}
4731.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4741.1Skamil	    "%s()\n", TWAIT_FNAME);
4751.1Skamil	TWAIT_REQUIRE_SUCCESS(
4761.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4771.1Skamil
4781.1Skamil	validate_status_exited(status, exitval_tracer1);
4791.1Skamil
4801.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4811.1Skamil	    TWAIT_FNAME);
4821.1Skamil	TWAIT_REQUIRE_SUCCESS(
4831.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4841.1Skamil
4851.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4861.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
4871.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4881.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
4891.1Skamil
4901.13Schristos	DPRINTF("Detect that tracee is zombie\n");
4911.1Skamil	await_zombie(tracee);
4921.1Skamil
4931.13Schristos	DPRINTF("Assert that there is no status about tracee - "
4941.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4951.1Skamil	TWAIT_REQUIRE_SUCCESS(
4961.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4971.1Skamil
4981.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
4991.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
5001.1Skamil
5011.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5021.1Skamil	    TWAIT_FNAME);
5031.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
5041.1Skamil	    tracee);
5051.1Skamil
5061.1Skamil	validate_status_exited(status, exitval_tracee);
5071.1Skamil
5081.1Skamil	msg_close(&parent_tracer);
5091.1Skamil	msg_close(&parent_tracee);
5101.1Skamil
5111.19Skamil	// Test is racy
5121.19Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5131.1Skamil}
5141.1Skamil#endif
5151.1Skamil
5161.1SkamilATF_TC(attach3);
5171.1SkamilATF_TC_HEAD(attach3, tc)
5181.1Skamil{
5191.1Skamil	atf_tc_set_md_var(tc, "descr",
5201.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
5211.1Skamil}
5221.1Skamil
5231.1SkamilATF_TC_BODY(attach3, tc)
5241.1Skamil{
5251.1Skamil	struct msg_fds parent_tracee;
5261.1Skamil	const int exitval_tracee = 5;
5271.1Skamil	pid_t tracee, wpid;
5281.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5291.1Skamil#if defined(TWAIT_HAVE_STATUS)
5301.1Skamil	int status;
5311.1Skamil#endif
5321.1Skamil
5331.13Schristos	DPRINTF("Spawn tracee\n");
5341.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5351.1Skamil	tracee = atf_utils_fork();
5361.1Skamil	if (tracee == 0) {
5371.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5381.13Schristos		DPRINTF("Parent should now attach to tracee\n");
5391.1Skamil
5401.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5411.1Skamil		/* Wait for message from the parent */
5421.1Skamil		_exit(exitval_tracee);
5431.1Skamil	}
5441.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5451.1Skamil
5461.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5481.1Skamil
5491.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5501.1Skamil	    TWAIT_FNAME);
5511.1Skamil	TWAIT_REQUIRE_SUCCESS(
5521.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5531.1Skamil
5541.1Skamil	validate_status_stopped(status, SIGSTOP);
5551.1Skamil
5561.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5581.1Skamil
5591.13Schristos	DPRINTF("Let the tracee exit now\n");
5601.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5611.1Skamil
5621.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5631.1Skamil	TWAIT_REQUIRE_SUCCESS(
5641.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5651.1Skamil
5661.1Skamil	validate_status_exited(status, exitval_tracee);
5671.1Skamil
5681.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5701.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5711.1Skamil
5721.1Skamil	msg_close(&parent_tracee);
5731.1Skamil}
5741.1Skamil
5751.1SkamilATF_TC(attach4);
5761.1SkamilATF_TC_HEAD(attach4, tc)
5771.1Skamil{
5781.1Skamil	atf_tc_set_md_var(tc, "descr",
5791.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
5801.1Skamil}
5811.1Skamil
5821.1SkamilATF_TC_BODY(attach4, tc)
5831.1Skamil{
5841.1Skamil	struct msg_fds parent_tracee;
5851.1Skamil	const int exitval_tracer = 5;
5861.1Skamil	pid_t tracer, wpid;
5871.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5881.1Skamil#if defined(TWAIT_HAVE_STATUS)
5891.1Skamil	int status;
5901.1Skamil#endif
5911.1Skamil
5921.13Schristos	DPRINTF("Spawn tracer\n");
5931.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5941.1Skamil	tracer = atf_utils_fork();
5951.1Skamil	if (tracer == 0) {
5961.1Skamil
5971.1Skamil		/* Wait for message from the parent */
5981.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5991.1Skamil
6001.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
6011.1Skamil		    getppid());
6021.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
6031.1Skamil
6041.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
6051.1Skamil		    TWAIT_FNAME);
6061.1Skamil		FORKEE_REQUIRE_SUCCESS(
6071.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
6081.1Skamil
6091.1Skamil		forkee_status_stopped(status, SIGSTOP);
6101.1Skamil
6111.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
6121.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
6131.1Skamil		    != -1);
6141.1Skamil
6151.1Skamil		/* Tell parent we are ready */
6161.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
6171.1Skamil
6181.1Skamil		_exit(exitval_tracer);
6191.1Skamil	}
6201.1Skamil
6211.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
6221.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6231.13Schristos	DPRINTF("Allow the tracer to exit now\n");
6241.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
6251.1Skamil
6261.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
6271.1Skamil	TWAIT_REQUIRE_SUCCESS(
6281.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6291.1Skamil
6301.1Skamil	validate_status_exited(status, exitval_tracer);
6311.1Skamil
6321.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
6331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6341.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
6351.1Skamil
6361.1Skamil	msg_close(&parent_tracee);
6371.1Skamil}
6381.1Skamil
6391.1Skamil#if defined(TWAIT_HAVE_PID)
6401.1SkamilATF_TC(attach5);
6411.1SkamilATF_TC_HEAD(attach5, tc)
6421.1Skamil{
6431.1Skamil	atf_tc_set_md_var(tc, "descr",
6441.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6451.1Skamil	    "(check getppid(2))");
6461.1Skamil}
6471.1Skamil
6481.1SkamilATF_TC_BODY(attach5, tc)
6491.1Skamil{
6501.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6511.1Skamil	const int exitval_tracee = 5;
6521.1Skamil	const int exitval_tracer = 10;
6531.1Skamil	pid_t parent, tracee, tracer, wpid;
6541.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6551.1Skamil#if defined(TWAIT_HAVE_STATUS)
6561.1Skamil	int status;
6571.1Skamil#endif
6581.1Skamil
6591.13Schristos	DPRINTF("Spawn tracee\n");
6601.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6611.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6621.1Skamil	tracee = atf_utils_fork();
6631.1Skamil	if (tracee == 0) {
6641.1Skamil		parent = getppid();
6651.1Skamil
6661.1Skamil		/* Emit message to the parent */
6671.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6681.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6691.1Skamil
6701.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6711.1Skamil
6721.1Skamil		_exit(exitval_tracee);
6731.1Skamil	}
6741.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6751.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6761.1Skamil
6771.13Schristos	DPRINTF("Spawn debugger\n");
6781.1Skamil	tracer = atf_utils_fork();
6791.1Skamil	if (tracer == 0) {
6801.1Skamil		/* No IPC to communicate with the child */
6811.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6821.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6831.1Skamil
6841.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6851.1Skamil		FORKEE_REQUIRE_SUCCESS(
6861.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6871.1Skamil
6881.1Skamil		forkee_status_stopped(status, SIGSTOP);
6891.1Skamil
6901.1Skamil		/* Resume tracee with PT_CONTINUE */
6911.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6921.1Skamil
6931.1Skamil		/* Inform parent that tracer has attached to tracee */
6941.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
6951.1Skamil
6961.1Skamil		/* Wait for parent to tell use that tracee should have exited */
6971.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
6981.1Skamil
6991.1Skamil		/* Wait for tracee and assert that it exited */
7001.1Skamil		FORKEE_REQUIRE_SUCCESS(
7011.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7021.1Skamil
7031.1Skamil		forkee_status_exited(status, exitval_tracee);
7041.1Skamil
7051.13Schristos		DPRINTF("Before exiting of the tracer process\n");
7061.1Skamil		_exit(exitval_tracer);
7071.1Skamil	}
7081.1Skamil
7091.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7101.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
7111.1Skamil
7121.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7131.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
7141.1Skamil
7151.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7161.1Skamil	await_zombie(tracee);
7171.1Skamil
7181.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7191.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7201.1Skamil	TWAIT_REQUIRE_SUCCESS(
7211.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7221.1Skamil
7231.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7241.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
7251.1Skamil
7261.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7281.1Skamil	    tracer);
7291.1Skamil
7301.1Skamil	validate_status_exited(status, exitval_tracer);
7311.1Skamil
7321.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7331.1Skamil	    TWAIT_FNAME);
7341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7351.1Skamil	    tracee);
7361.1Skamil
7371.1Skamil	validate_status_exited(status, exitval_tracee);
7381.1Skamil
7391.1Skamil	msg_close(&parent_tracer);
7401.1Skamil	msg_close(&parent_tracee);
7411.1Skamil}
7421.1Skamil#endif
7431.1Skamil
7441.1Skamil#if defined(TWAIT_HAVE_PID)
7451.1SkamilATF_TC(attach6);
7461.1SkamilATF_TC_HEAD(attach6, tc)
7471.1Skamil{
7481.1Skamil	atf_tc_set_md_var(tc, "descr",
7491.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7501.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7511.1Skamil}
7521.1Skamil
7531.1SkamilATF_TC_BODY(attach6, tc)
7541.1Skamil{
7551.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7561.1Skamil	const int exitval_tracee = 5;
7571.1Skamil	const int exitval_tracer = 10;
7581.1Skamil	pid_t parent, tracee, tracer, wpid;
7591.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7601.1Skamil#if defined(TWAIT_HAVE_STATUS)
7611.1Skamil	int status;
7621.1Skamil#endif
7631.1Skamil	int name[CTL_MAXNAME];
7641.1Skamil	struct kinfo_proc2 kp;
7651.1Skamil	size_t len = sizeof(kp);
7661.1Skamil	unsigned int namelen;
7671.1Skamil
7681.13Schristos	DPRINTF("Spawn tracee\n");
7691.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7701.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7711.1Skamil	tracee = atf_utils_fork();
7721.1Skamil	if (tracee == 0) {
7731.1Skamil		parent = getppid();
7741.1Skamil
7751.1Skamil		/* Emit message to the parent */
7761.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7771.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7781.1Skamil
7791.1Skamil		namelen = 0;
7801.1Skamil		name[namelen++] = CTL_KERN;
7811.1Skamil		name[namelen++] = KERN_PROC2;
7821.1Skamil		name[namelen++] = KERN_PROC_PID;
7831.1Skamil		name[namelen++] = getpid();
7841.1Skamil		name[namelen++] = len;
7851.1Skamil		name[namelen++] = 1;
7861.1Skamil
7871.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
7881.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
7891.1Skamil
7901.1Skamil		_exit(exitval_tracee);
7911.1Skamil	}
7921.1Skamil
7931.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
7941.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
7951.1Skamil
7961.13Schristos	DPRINTF("Spawn debugger\n");
7971.1Skamil	tracer = atf_utils_fork();
7981.1Skamil	if (tracer == 0) {
7991.1Skamil		/* No IPC to communicate with the child */
8001.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8011.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8021.1Skamil
8031.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8041.1Skamil		FORKEE_REQUIRE_SUCCESS(
8051.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8061.1Skamil
8071.1Skamil		forkee_status_stopped(status, SIGSTOP);
8081.1Skamil
8091.1Skamil		/* Resume tracee with PT_CONTINUE */
8101.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8111.1Skamil
8121.1Skamil		/* Inform parent that tracer has attached to tracee */
8131.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8141.1Skamil
8151.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8161.1Skamil
8171.1Skamil		/* Wait for tracee and assert that it exited */
8181.1Skamil		FORKEE_REQUIRE_SUCCESS(
8191.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8201.1Skamil
8211.1Skamil		forkee_status_exited(status, exitval_tracee);
8221.1Skamil
8231.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8241.1Skamil		_exit(exitval_tracer);
8251.1Skamil	}
8261.1Skamil
8271.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8281.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8291.1Skamil
8301.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8311.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8321.1Skamil
8331.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8341.1Skamil	await_zombie(tracee);
8351.1Skamil
8361.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8371.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8381.1Skamil	TWAIT_REQUIRE_SUCCESS(
8391.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8401.1Skamil
8411.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8421.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8431.1Skamil
8441.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8451.1Skamil	    TWAIT_FNAME);
8461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8471.1Skamil	    tracer);
8481.1Skamil
8491.1Skamil	validate_status_exited(status, exitval_tracer);
8501.1Skamil
8511.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8521.1Skamil	    TWAIT_FNAME);
8531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8541.1Skamil	    tracee);
8551.1Skamil
8561.1Skamil	validate_status_exited(status, exitval_tracee);
8571.1Skamil
8581.1Skamil	msg_close(&parent_tracee);
8591.1Skamil	msg_close(&parent_tracer);
8601.1Skamil}
8611.1Skamil#endif
8621.1Skamil
8631.1Skamil#if defined(TWAIT_HAVE_PID)
8641.1SkamilATF_TC(attach7);
8651.1SkamilATF_TC_HEAD(attach7, tc)
8661.1Skamil{
8671.1Skamil	atf_tc_set_md_var(tc, "descr",
8681.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8691.1Skamil	    "(check /proc/curproc/status 3rd column)");
8701.1Skamil}
8711.1Skamil
8721.1SkamilATF_TC_BODY(attach7, tc)
8731.1Skamil{
8741.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8751.1Skamil	int rv;
8761.1Skamil	const int exitval_tracee = 5;
8771.1Skamil	const int exitval_tracer = 10;
8781.1Skamil	pid_t parent, tracee, tracer, wpid;
8791.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8801.1Skamil#if defined(TWAIT_HAVE_STATUS)
8811.1Skamil	int status;
8821.1Skamil#endif
8831.1Skamil	FILE *fp;
8841.1Skamil	struct stat st;
8851.1Skamil	const char *fname = "/proc/curproc/status";
8861.1Skamil	char s_executable[MAXPATHLEN];
8871.1Skamil	int s_pid, s_ppid;
8881.1Skamil	/*
8891.1Skamil	 * Format:
8901.1Skamil	 *  EXECUTABLE PID PPID ...
8911.1Skamil	 */
8921.1Skamil
8931.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
8941.1Skamil	if (rv != 0) {
8951.1Skamil		atf_tc_skip("/proc/curproc/status not found");
8961.1Skamil	}
8971.1Skamil
8981.13Schristos	DPRINTF("Spawn tracee\n");
8991.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9001.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
9011.1Skamil	tracee = atf_utils_fork();
9021.1Skamil	if (tracee == 0) {
9031.1Skamil		parent = getppid();
9041.1Skamil
9051.1Skamil		// Wait for parent to let us exit
9061.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
9071.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
9081.1Skamil
9091.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
9101.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
9111.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
9121.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
9131.1Skamil
9141.1Skamil		_exit(exitval_tracee);
9151.1Skamil	}
9161.1Skamil
9171.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9181.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
9191.1Skamil
9201.13Schristos	DPRINTF("Spawn debugger\n");
9211.1Skamil	tracer = atf_utils_fork();
9221.1Skamil	if (tracer == 0) {
9231.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9241.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9251.1Skamil
9261.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9271.1Skamil		FORKEE_REQUIRE_SUCCESS(
9281.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9291.1Skamil
9301.1Skamil		forkee_status_stopped(status, SIGSTOP);
9311.1Skamil
9321.1Skamil		/* Resume tracee with PT_CONTINUE */
9331.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9341.1Skamil
9351.1Skamil		/* Inform parent that tracer has attached to tracee */
9361.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9371.1Skamil
9381.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9391.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9401.1Skamil
9411.1Skamil		/* Wait for tracee and assert that it exited */
9421.1Skamil		FORKEE_REQUIRE_SUCCESS(
9431.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9441.1Skamil
9451.1Skamil		forkee_status_exited(status, exitval_tracee);
9461.1Skamil
9471.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9481.1Skamil		_exit(exitval_tracer);
9491.1Skamil	}
9501.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9511.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9521.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9531.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9541.1Skamil
9551.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9561.1Skamil	await_zombie(tracee);
9571.1Skamil
9581.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9591.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9601.1Skamil	TWAIT_REQUIRE_SUCCESS(
9611.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9621.1Skamil
9631.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9641.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9651.1Skamil
9661.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9671.1Skamil	    TWAIT_FNAME);
9681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9691.1Skamil	    tracer);
9701.1Skamil
9711.1Skamil	validate_status_exited(status, exitval_tracer);
9721.1Skamil
9731.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9741.1Skamil	    TWAIT_FNAME);
9751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9761.1Skamil	    tracee);
9771.1Skamil
9781.1Skamil	validate_status_exited(status, exitval_tracee);
9791.1Skamil
9801.1Skamil	msg_close(&parent_tracee);
9811.1Skamil	msg_close(&parent_tracer);
9821.1Skamil}
9831.1Skamil#endif
9841.1Skamil
9851.1SkamilATF_TC(eventmask1);
9861.1SkamilATF_TC_HEAD(eventmask1, tc)
9871.1Skamil{
9881.1Skamil	atf_tc_set_md_var(tc, "descr",
9891.1Skamil	    "Verify that empty EVENT_MASK is preserved");
9901.1Skamil}
9911.1Skamil
9921.1SkamilATF_TC_BODY(eventmask1, tc)
9931.1Skamil{
9941.1Skamil	const int exitval = 5;
9951.1Skamil	const int sigval = SIGSTOP;
9961.1Skamil	pid_t child, wpid;
9971.1Skamil#if defined(TWAIT_HAVE_STATUS)
9981.1Skamil	int status;
9991.1Skamil#endif
10001.1Skamil	ptrace_event_t set_event, get_event;
10011.1Skamil	const int len = sizeof(ptrace_event_t);
10021.1Skamil
10031.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10041.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10051.1Skamil	if (child == 0) {
10061.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10071.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10081.1Skamil
10091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10111.1Skamil
10121.13Schristos		DPRINTF("Before exiting of the child process\n");
10131.1Skamil		_exit(exitval);
10141.1Skamil	}
10151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10161.1Skamil
10171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10191.1Skamil
10201.1Skamil	validate_status_stopped(status, sigval);
10211.1Skamil
10221.1Skamil	set_event.pe_set_event = 0;
10231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10251.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10261.1Skamil
10271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10281.1Skamil	    "without signal to be sent\n");
10291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10301.1Skamil
10311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10331.1Skamil
10341.1Skamil	validate_status_exited(status, exitval);
10351.1Skamil
10361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10381.1Skamil}
10391.1Skamil
10401.1SkamilATF_TC(eventmask2);
10411.1SkamilATF_TC_HEAD(eventmask2, tc)
10421.1Skamil{
10431.1Skamil	atf_tc_set_md_var(tc, "descr",
10441.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10451.1Skamil}
10461.1Skamil
10471.1SkamilATF_TC_BODY(eventmask2, tc)
10481.1Skamil{
10491.1Skamil	const int exitval = 5;
10501.1Skamil	const int sigval = SIGSTOP;
10511.1Skamil	pid_t child, wpid;
10521.1Skamil#if defined(TWAIT_HAVE_STATUS)
10531.1Skamil	int status;
10541.1Skamil#endif
10551.1Skamil	ptrace_event_t set_event, get_event;
10561.1Skamil	const int len = sizeof(ptrace_event_t);
10571.1Skamil
10581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10601.1Skamil	if (child == 0) {
10611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10631.1Skamil
10641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10661.1Skamil
10671.13Schristos		DPRINTF("Before exiting of the child process\n");
10681.1Skamil		_exit(exitval);
10691.1Skamil	}
10701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10711.1Skamil
10721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10741.1Skamil
10751.1Skamil	validate_status_stopped(status, sigval);
10761.1Skamil
10771.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10801.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10811.1Skamil
10821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10831.1Skamil	    "without signal to be sent\n");
10841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10851.1Skamil
10861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10881.1Skamil
10891.1Skamil	validate_status_exited(status, exitval);
10901.1Skamil
10911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10931.1Skamil}
10941.1Skamil
10951.1SkamilATF_TC(eventmask3);
10961.1SkamilATF_TC_HEAD(eventmask3, tc)
10971.1Skamil{
10981.1Skamil	atf_tc_set_md_var(tc, "descr",
10991.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
11001.1Skamil}
11011.1Skamil
11021.1SkamilATF_TC_BODY(eventmask3, tc)
11031.1Skamil{
11041.1Skamil	const int exitval = 5;
11051.1Skamil	const int sigval = SIGSTOP;
11061.1Skamil	pid_t child, wpid;
11071.1Skamil#if defined(TWAIT_HAVE_STATUS)
11081.1Skamil	int status;
11091.1Skamil#endif
11101.1Skamil	ptrace_event_t set_event, get_event;
11111.1Skamil	const int len = sizeof(ptrace_event_t);
11121.1Skamil
11131.14Schristos	atf_tc_expect_fail("PR kern/51630");
11141.14Schristos
11151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11171.1Skamil	if (child == 0) {
11181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11201.1Skamil
11211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11231.1Skamil
11241.13Schristos		DPRINTF("Before exiting of the child process\n");
11251.1Skamil		_exit(exitval);
11261.1Skamil	}
11271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11281.1Skamil
11291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11311.1Skamil
11321.1Skamil	validate_status_stopped(status, sigval);
11331.1Skamil
11341.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
11351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
11361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11371.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11381.1Skamil
11391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11401.1Skamil	    "without signal to be sent\n");
11411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11421.1Skamil
11431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11451.1Skamil
11461.1Skamil	validate_status_exited(status, exitval);
11471.1Skamil
11481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11501.1Skamil}
11511.1Skamil
11521.1SkamilATF_TC(eventmask4);
11531.1SkamilATF_TC_HEAD(eventmask4, tc)
11541.1Skamil{
11551.1Skamil	atf_tc_set_md_var(tc, "descr",
11561.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11571.1Skamil}
11581.1Skamil
11591.1SkamilATF_TC_BODY(eventmask4, tc)
11601.1Skamil{
11611.1Skamil	const int exitval = 5;
11621.1Skamil	const int sigval = SIGSTOP;
11631.1Skamil	pid_t child, wpid;
11641.1Skamil#if defined(TWAIT_HAVE_STATUS)
11651.1Skamil	int status;
11661.1Skamil#endif
11671.1Skamil	ptrace_event_t set_event, get_event;
11681.1Skamil	const int len = sizeof(ptrace_event_t);
11691.1Skamil
11701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11721.1Skamil	if (child == 0) {
11731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11751.1Skamil
11761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11781.1Skamil
11791.13Schristos		DPRINTF("Before exiting of the child process\n");
11801.1Skamil		_exit(exitval);
11811.1Skamil	}
11821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11831.1Skamil
11841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11861.1Skamil
11871.1Skamil	validate_status_stopped(status, sigval);
11881.1Skamil
11891.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
11901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11921.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11931.1Skamil
11941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11951.1Skamil	    "without signal to be sent\n");
11961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11971.1Skamil
11981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12001.1Skamil
12011.1Skamil	validate_status_exited(status, exitval);
12021.1Skamil
12031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12051.1Skamil}
12061.1Skamil
12071.1SkamilATF_TC(eventmask5);
12081.1SkamilATF_TC_HEAD(eventmask5, tc)
12091.1Skamil{
12101.1Skamil	atf_tc_set_md_var(tc, "descr",
12111.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
12121.1Skamil}
12131.1Skamil
12141.1SkamilATF_TC_BODY(eventmask5, tc)
12151.1Skamil{
12161.1Skamil	const int exitval = 5;
12171.1Skamil	const int sigval = SIGSTOP;
12181.1Skamil	pid_t child, wpid;
12191.1Skamil#if defined(TWAIT_HAVE_STATUS)
12201.1Skamil	int status;
12211.1Skamil#endif
12221.1Skamil	ptrace_event_t set_event, get_event;
12231.1Skamil	const int len = sizeof(ptrace_event_t);
12241.1Skamil
12251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12271.1Skamil	if (child == 0) {
12281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12301.1Skamil
12311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12331.1Skamil
12341.13Schristos		DPRINTF("Before exiting of the child process\n");
12351.1Skamil		_exit(exitval);
12361.1Skamil	}
12371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12381.1Skamil
12391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12411.1Skamil
12421.1Skamil	validate_status_stopped(status, sigval);
12431.1Skamil
12441.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12471.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12481.1Skamil
12491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12501.1Skamil	    "without signal to be sent\n");
12511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12521.1Skamil
12531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12551.1Skamil
12561.1Skamil	validate_status_exited(status, exitval);
12571.1Skamil
12581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12601.1Skamil}
12611.1Skamil
12621.1SkamilATF_TC(eventmask6);
12631.1SkamilATF_TC_HEAD(eventmask6, tc)
12641.1Skamil{
12651.1Skamil	atf_tc_set_md_var(tc, "descr",
12661.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12671.1Skamil}
12681.1Skamil
12691.1SkamilATF_TC_BODY(eventmask6, tc)
12701.1Skamil{
12711.1Skamil	const int exitval = 5;
12721.1Skamil	const int sigval = SIGSTOP;
12731.1Skamil	pid_t child, wpid;
12741.1Skamil#if defined(TWAIT_HAVE_STATUS)
12751.1Skamil	int status;
12761.1Skamil#endif
12771.1Skamil	ptrace_event_t set_event, get_event;
12781.1Skamil	const int len = sizeof(ptrace_event_t);
12791.1Skamil
12801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12821.1Skamil	if (child == 0) {
12831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12851.1Skamil
12861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12881.1Skamil
12891.13Schristos		DPRINTF("Before exiting of the child process\n");
12901.1Skamil		_exit(exitval);
12911.1Skamil	}
12921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12931.1Skamil
12941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12961.1Skamil
12971.1Skamil	validate_status_stopped(status, sigval);
12981.1Skamil
12991.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
13001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13021.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13031.1Skamil
13041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13051.1Skamil	    "without signal to be sent\n");
13061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13071.1Skamil
13081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13101.1Skamil
13111.1Skamil	validate_status_exited(status, exitval);
13121.1Skamil
13131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13151.1Skamil}
13161.1Skamil
13171.1Skamil#if defined(TWAIT_HAVE_PID)
13181.1SkamilATF_TC(fork1);
13191.1SkamilATF_TC_HEAD(fork1, tc)
13201.1Skamil{
13211.1Skamil	atf_tc_set_md_var(tc, "descr",
13221.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
13231.1Skamil	    "set to PTRACE_FORK");
13241.1Skamil}
13251.1Skamil
13261.1SkamilATF_TC_BODY(fork1, tc)
13271.1Skamil{
13281.1Skamil	const int exitval = 5;
13291.1Skamil	const int exitval2 = 15;
13301.1Skamil	const int sigval = SIGSTOP;
13311.1Skamil	pid_t child, child2, wpid;
13321.1Skamil#if defined(TWAIT_HAVE_STATUS)
13331.1Skamil	int status;
13341.1Skamil#endif
13351.1Skamil	ptrace_state_t state;
13361.1Skamil	const int slen = sizeof(state);
13371.1Skamil	ptrace_event_t event;
13381.1Skamil	const int elen = sizeof(event);
13391.1Skamil
13401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13421.1Skamil	if (child == 0) {
13431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13451.1Skamil
13461.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13471.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13481.1Skamil
13491.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
13501.1Skamil
13511.1Skamil		if (child2 == 0)
13521.1Skamil			_exit(exitval2);
13531.1Skamil
13541.1Skamil		FORKEE_REQUIRE_SUCCESS
13551.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13561.1Skamil
13571.1Skamil		forkee_status_exited(status, exitval2);
13581.1Skamil
13591.13Schristos		DPRINTF("Before exiting of the child process\n");
13601.1Skamil		_exit(exitval);
13611.1Skamil	}
13621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13631.1Skamil
13641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13661.1Skamil
13671.1Skamil	validate_status_stopped(status, sigval);
13681.1Skamil
13691.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
13701.1Skamil	event.pe_set_event = PTRACE_FORK;
13711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13721.1Skamil
13731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13741.1Skamil	    "without signal to be sent\n");
13751.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
13761.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
13771.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
13781.1Skamil                "state.pe_other_pid=child)\n", child);
13791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13801.1Skamil
13811.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
13821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13831.1Skamil
13841.1Skamil	validate_status_stopped(status, SIGTRAP);
13851.1Skamil
13861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
13871.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
13881.1Skamil
13891.1Skamil	child2 = state.pe_other_pid;
13901.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
13911.1Skamil
13921.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
13931.1Skamil	    TWAIT_FNAME, child2, child);
13941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
13951.1Skamil	    child2);
13961.1Skamil
13971.1Skamil	validate_status_stopped(status, SIGTRAP);
13981.1Skamil
13991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
14001.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
14011.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
14021.1Skamil
14031.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
14041.1Skamil	    "without signal to be sent\n");
14051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
14061.1Skamil
14071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14081.1Skamil	    "without signal to be sent\n");
14091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14101.1Skamil
14111.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
14121.1Skamil	    TWAIT_FNAME);
14131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14141.1Skamil	    child2);
14151.1Skamil
14161.1Skamil	validate_status_exited(status, exitval2);
14171.1Skamil
14181.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
14191.1Skamil	    TWAIT_FNAME);
14201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
14211.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
14221.1Skamil
14231.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14241.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14261.1Skamil
14271.1Skamil	validate_status_stopped(status, SIGCHLD);
14281.1Skamil
14291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14301.1Skamil	    "without signal to be sent\n");
14311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14321.1Skamil
14331.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
14341.1Skamil	    TWAIT_FNAME);
14351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14361.1Skamil
14371.1Skamil	validate_status_exited(status, exitval);
14381.1Skamil
14391.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
14401.1Skamil	    TWAIT_FNAME);
14411.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14421.1Skamil}
14431.1Skamil#endif
14441.1Skamil
14451.1SkamilATF_TC(fork2);
14461.1SkamilATF_TC_HEAD(fork2, tc)
14471.1Skamil{
14481.1Skamil	atf_tc_set_md_var(tc, "descr",
14491.1Skamil	    "Verify that fork(2) is not intercepted by ptrace(2) with empty "
14501.1Skamil	    "EVENT_MASK");
14511.1Skamil}
14521.1Skamil
14531.1SkamilATF_TC_BODY(fork2, tc)
14541.1Skamil{
14551.1Skamil	const int exitval = 5;
14561.1Skamil	const int exitval2 = 15;
14571.1Skamil	const int sigval = SIGSTOP;
14581.1Skamil	pid_t child, child2, wpid;
14591.1Skamil#if defined(TWAIT_HAVE_STATUS)
14601.1Skamil	int status;
14611.1Skamil#endif
14621.1Skamil	ptrace_event_t event;
14631.1Skamil	const int elen = sizeof(event);
14641.1Skamil
14651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14671.1Skamil	if (child == 0) {
14681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14701.1Skamil
14711.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14721.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14731.1Skamil
14741.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
14751.1Skamil
14761.1Skamil		if (child2 == 0)
14771.1Skamil			_exit(exitval2);
14781.1Skamil
14791.1Skamil		FORKEE_REQUIRE_SUCCESS
14801.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
14811.1Skamil
14821.1Skamil		forkee_status_exited(status, exitval2);
14831.1Skamil
14841.13Schristos		DPRINTF("Before exiting of the child process\n");
14851.1Skamil		_exit(exitval);
14861.1Skamil	}
14871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14881.1Skamil
14891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14911.1Skamil
14921.1Skamil	validate_status_stopped(status, sigval);
14931.1Skamil
14941.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
14951.1Skamil	event.pe_set_event = 0;
14961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
14971.1Skamil
14981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14991.1Skamil	    "without signal to be sent\n");
15001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15011.1Skamil
15021.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
15031.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
15041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15051.1Skamil
15061.1Skamil	validate_status_stopped(status, SIGCHLD);
15071.1Skamil
15081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15091.1Skamil	    "without signal to be sent\n");
15101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15111.1Skamil
15121.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
15131.1Skamil	    TWAIT_FNAME);
15141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15151.1Skamil
15161.1Skamil	validate_status_exited(status, exitval);
15171.1Skamil
15181.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
15191.1Skamil	    TWAIT_FNAME);
15201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15211.1Skamil}
15221.1Skamil
15231.1Skamil#if defined(TWAIT_HAVE_PID)
15241.1SkamilATF_TC(vfork1);
15251.1SkamilATF_TC_HEAD(vfork1, tc)
15261.1Skamil{
15271.1Skamil	atf_tc_set_md_var(tc, "descr",
15281.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
15291.1Skamil	    "set to PTRACE_VFORK");
15301.1Skamil}
15311.1Skamil
15321.1SkamilATF_TC_BODY(vfork1, tc)
15331.1Skamil{
15341.1Skamil	const int exitval = 5;
15351.1Skamil	const int exitval2 = 15;
15361.1Skamil	const int sigval = SIGSTOP;
15371.1Skamil	pid_t child, child2, wpid;
15381.1Skamil#if defined(TWAIT_HAVE_STATUS)
15391.1Skamil	int status;
15401.1Skamil#endif
15411.1Skamil	ptrace_state_t state;
15421.1Skamil	const int slen = sizeof(state);
15431.1Skamil	ptrace_event_t event;
15441.1Skamil	const int elen = sizeof(event);
15451.1Skamil
15461.1Skamil	atf_tc_expect_fail("PR kern/51630");
15471.1Skamil
15481.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15491.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15501.1Skamil	if (child == 0) {
15511.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15521.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15531.1Skamil
15541.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15551.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15561.1Skamil
15571.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
15581.1Skamil
15591.1Skamil		if (child2 == 0)
15601.1Skamil			_exit(exitval2);
15611.1Skamil
15621.1Skamil		FORKEE_REQUIRE_SUCCESS
15631.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
15641.1Skamil
15651.1Skamil		forkee_status_exited(status, exitval2);
15661.1Skamil
15671.13Schristos		DPRINTF("Before exiting of the child process\n");
15681.1Skamil		_exit(exitval);
15691.1Skamil	}
15701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15711.1Skamil
15721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15741.1Skamil
15751.1Skamil	validate_status_stopped(status, sigval);
15761.1Skamil
15771.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
15781.1Skamil	event.pe_set_event = PTRACE_VFORK;
15791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
15801.1Skamil
15811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15821.1Skamil	    "without signal to be sent\n");
15831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15841.1Skamil
15851.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
15861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15871.1Skamil
15881.1Skamil	validate_status_stopped(status, SIGTRAP);
15891.1Skamil
15901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
15911.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
15921.1Skamil
15931.1Skamil	child2 = state.pe_other_pid;
15941.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
15951.1Skamil
15961.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
15971.1Skamil	    TWAIT_FNAME, child2, child);
15981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
15991.1Skamil	    child2);
16001.1Skamil
16011.1Skamil	validate_status_stopped(status, SIGTRAP);
16021.1Skamil
16031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
16041.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
16051.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
16061.1Skamil
16071.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
16081.1Skamil	    "without signal to be sent\n");
16091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
16101.1Skamil
16111.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16121.1Skamil	    "without signal to be sent\n");
16131.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16141.1Skamil
16151.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
16161.1Skamil	    TWAIT_FNAME);
16171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
16181.1Skamil	    child2);
16191.1Skamil
16201.1Skamil	validate_status_exited(status, exitval2);
16211.1Skamil
16221.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
16231.1Skamil	    TWAIT_FNAME);
16241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
16251.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
16261.1Skamil
16271.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
16281.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
16291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16301.1Skamil
16311.1Skamil	validate_status_stopped(status, SIGCHLD);
16321.1Skamil
16331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16341.1Skamil	    "without signal to be sent\n");
16351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16361.1Skamil
16371.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
16381.1Skamil	    TWAIT_FNAME);
16391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16401.1Skamil
16411.1Skamil	validate_status_exited(status, exitval);
16421.1Skamil
16431.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
16441.1Skamil	    TWAIT_FNAME);
16451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16461.1Skamil}
16471.1Skamil#endif
16481.1Skamil
16491.1SkamilATF_TC(vfork2);
16501.1SkamilATF_TC_HEAD(vfork2, tc)
16511.1Skamil{
16521.1Skamil	atf_tc_set_md_var(tc, "descr",
16531.1Skamil	    "Verify that vfork(2) is not intercepted by ptrace(2) with empty "
16541.1Skamil	    "EVENT_MASK");
16551.1Skamil}
16561.1Skamil
16571.1SkamilATF_TC_BODY(vfork2, tc)
16581.1Skamil{
16591.1Skamil	const int exitval = 5;
16601.1Skamil	const int exitval2 = 15;
16611.1Skamil	const int sigval = SIGSTOP;
16621.1Skamil	pid_t child, child2, wpid;
16631.1Skamil#if defined(TWAIT_HAVE_STATUS)
16641.1Skamil	int status;
16651.1Skamil#endif
16661.1Skamil	ptrace_event_t event;
16671.1Skamil	const int elen = sizeof(event);
16681.1Skamil
16691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16711.1Skamil	if (child == 0) {
16721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16741.1Skamil
16751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16771.1Skamil
16781.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
16791.1Skamil
16801.1Skamil		if (child2 == 0)
16811.1Skamil			_exit(exitval2);
16821.1Skamil
16831.1Skamil		FORKEE_REQUIRE_SUCCESS
16841.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
16851.1Skamil
16861.1Skamil		forkee_status_exited(status, exitval2);
16871.1Skamil
16881.13Schristos		DPRINTF("Before exiting of the child process\n");
16891.1Skamil		_exit(exitval);
16901.1Skamil	}
16911.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16921.1Skamil
16931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16941.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16951.1Skamil
16961.1Skamil	validate_status_stopped(status, sigval);
16971.1Skamil
16981.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
16991.1Skamil	event.pe_set_event = 0;
17001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17011.1Skamil
17021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17031.1Skamil	    "without signal to be sent\n");
17041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17051.1Skamil
17061.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
17071.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
17081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17091.1Skamil
17101.1Skamil	validate_status_stopped(status, SIGCHLD);
17111.1Skamil
17121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17131.1Skamil	    "without signal to be sent\n");
17141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17151.1Skamil
17161.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
17171.1Skamil	    TWAIT_FNAME);
17181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17191.1Skamil
17201.1Skamil	validate_status_exited(status, exitval);
17211.1Skamil
17221.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
17231.1Skamil	    TWAIT_FNAME);
17241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17251.1Skamil}
17261.1Skamil
17271.1SkamilATF_TC(vforkdone1);
17281.1SkamilATF_TC_HEAD(vforkdone1, tc)
17291.1Skamil{
17301.1Skamil	atf_tc_set_md_var(tc, "descr",
17311.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
17321.1Skamil	    "set to PTRACE_VFORK_DONE");
17331.1Skamil}
17341.1Skamil
17351.1SkamilATF_TC_BODY(vforkdone1, tc)
17361.1Skamil{
17371.1Skamil	const int exitval = 5;
17381.1Skamil	const int exitval2 = 15;
17391.1Skamil	const int sigval = SIGSTOP;
17401.1Skamil	pid_t child, child2, wpid;
17411.1Skamil#if defined(TWAIT_HAVE_STATUS)
17421.1Skamil	int status;
17431.1Skamil#endif
17441.1Skamil	ptrace_state_t state;
17451.1Skamil	const int slen = sizeof(state);
17461.1Skamil	ptrace_event_t event;
17471.1Skamil	const int elen = sizeof(event);
17481.1Skamil
17491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17511.1Skamil	if (child == 0) {
17521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17541.1Skamil
17551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17571.1Skamil
17581.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
17591.1Skamil
17601.1Skamil		if (child2 == 0)
17611.1Skamil			_exit(exitval2);
17621.1Skamil
17631.1Skamil		FORKEE_REQUIRE_SUCCESS
17641.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
17651.1Skamil
17661.1Skamil		forkee_status_exited(status, exitval2);
17671.1Skamil
17681.13Schristos		DPRINTF("Before exiting of the child process\n");
17691.1Skamil		_exit(exitval);
17701.1Skamil	}
17711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17721.1Skamil
17731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17751.1Skamil
17761.1Skamil	validate_status_stopped(status, sigval);
17771.1Skamil
17781.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
17791.1Skamil	    child);
17801.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
17811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17821.1Skamil
17831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17841.1Skamil	    "without signal to be sent\n");
17851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17861.1Skamil
17871.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
17881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17891.1Skamil
17901.1Skamil	validate_status_stopped(status, SIGTRAP);
17911.1Skamil
17921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
17931.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
17941.1Skamil
17951.1Skamil	child2 = state.pe_other_pid;
17961.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
17971.1Skamil
17981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17991.1Skamil	    "without signal to be sent\n");
18001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18011.1Skamil
18021.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18031.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18051.1Skamil
18061.1Skamil	validate_status_stopped(status, SIGCHLD);
18071.1Skamil
18081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18091.1Skamil	    "without signal to be sent\n");
18101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18111.1Skamil
18121.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
18131.1Skamil	    TWAIT_FNAME);
18141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18151.1Skamil
18161.1Skamil	validate_status_exited(status, exitval);
18171.1Skamil
18181.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
18191.1Skamil	    TWAIT_FNAME);
18201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18211.1Skamil}
18221.1Skamil
18231.1SkamilATF_TC(vforkdone2);
18241.1SkamilATF_TC_HEAD(vforkdone2, tc)
18251.1Skamil{
18261.1Skamil	atf_tc_set_md_var(tc, "descr",
18271.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
18281.1Skamil	    "set to PTRACE_FORK | PTRACE_VFORK_DONE");
18291.1Skamil}
18301.1Skamil
18311.1SkamilATF_TC_BODY(vforkdone2, tc)
18321.1Skamil{
18331.1Skamil	const int exitval = 5;
18341.1Skamil	const int exitval2 = 15;
18351.1Skamil	const int sigval = SIGSTOP;
18361.1Skamil	pid_t child, child2, wpid;
18371.1Skamil#if defined(TWAIT_HAVE_STATUS)
18381.1Skamil	int status;
18391.1Skamil#endif
18401.1Skamil	ptrace_state_t state;
18411.1Skamil	const int slen = sizeof(state);
18421.1Skamil	ptrace_event_t event;
18431.1Skamil	const int elen = sizeof(event);
18441.1Skamil
18451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18471.1Skamil	if (child == 0) {
18481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18501.1Skamil
18511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18531.1Skamil
18541.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
18551.1Skamil
18561.1Skamil		if (child2 == 0)
18571.1Skamil			_exit(exitval2);
18581.1Skamil
18591.1Skamil		FORKEE_REQUIRE_SUCCESS
18601.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
18611.1Skamil
18621.1Skamil		forkee_status_exited(status, exitval2);
18631.1Skamil
18641.13Schristos		DPRINTF("Before exiting of the child process\n");
18651.1Skamil		_exit(exitval);
18661.1Skamil	}
18671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18681.1Skamil
18691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18711.1Skamil
18721.1Skamil	validate_status_stopped(status, sigval);
18731.1Skamil
18741.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
18751.1Skamil	event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE;
18761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
18771.1Skamil
18781.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18791.1Skamil	    "without signal to be sent\n");
18801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18811.1Skamil
18821.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
18831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18841.1Skamil
18851.1Skamil	validate_status_stopped(status, SIGTRAP);
18861.1Skamil
18871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
18881.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
18891.1Skamil
18901.1Skamil	child2 = state.pe_other_pid;
18911.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
18921.1Skamil
18931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18941.1Skamil	    "without signal to be sent\n");
18951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18961.1Skamil
18971.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18981.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19001.1Skamil
19011.1Skamil	validate_status_stopped(status, SIGCHLD);
19021.1Skamil
19031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19041.1Skamil	    "without signal to be sent\n");
19051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19061.1Skamil
19071.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
19081.1Skamil	    TWAIT_FNAME);
19091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19101.1Skamil
19111.1Skamil	validate_status_exited(status, exitval);
19121.1Skamil
19131.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
19141.1Skamil	    TWAIT_FNAME);
19151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19161.1Skamil}
19171.1Skamil
19181.1SkamilATF_TC(io_read_d1);
19191.1SkamilATF_TC_HEAD(io_read_d1, tc)
19201.1Skamil{
19211.1Skamil	atf_tc_set_md_var(tc, "descr",
19221.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
19231.1Skamil}
19241.1Skamil
19251.1SkamilATF_TC_BODY(io_read_d1, tc)
19261.1Skamil{
19271.1Skamil	const int exitval = 5;
19281.1Skamil	const int sigval = SIGSTOP;
19291.1Skamil	pid_t child, wpid;
19301.1Skamil	uint8_t lookup_me = 0;
19311.1Skamil	const uint8_t magic = 0xab;
19321.1Skamil	struct ptrace_io_desc io = {
19331.1Skamil		.piod_op = PIOD_READ_D,
19341.1Skamil		.piod_offs = &lookup_me,
19351.1Skamil		.piod_addr = &lookup_me,
19361.1Skamil		.piod_len = sizeof(lookup_me)
19371.1Skamil	};
19381.1Skamil#if defined(TWAIT_HAVE_STATUS)
19391.1Skamil	int status;
19401.1Skamil#endif
19411.1Skamil
19421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19441.1Skamil	if (child == 0) {
19451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19471.1Skamil
19481.1Skamil		lookup_me = magic;
19491.1Skamil
19501.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19511.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19521.1Skamil
19531.13Schristos		DPRINTF("Before exiting of the child process\n");
19541.1Skamil		_exit(exitval);
19551.1Skamil	}
19561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19571.1Skamil
19581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19601.1Skamil
19611.1Skamil	validate_status_stopped(status, sigval);
19621.1Skamil
19631.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19641.1Skamil	    child, getpid());
19651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19661.1Skamil
19671.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19681.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
19691.1Skamil
19701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19711.1Skamil	    "without signal to be sent\n");
19721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19731.1Skamil
19741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19761.1Skamil
19771.1Skamil	validate_status_exited(status, exitval);
19781.1Skamil
19791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19811.1Skamil}
19821.1Skamil
19831.1SkamilATF_TC(io_read_d2);
19841.1SkamilATF_TC_HEAD(io_read_d2, tc)
19851.1Skamil{
19861.1Skamil	atf_tc_set_md_var(tc, "descr",
19871.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
19881.1Skamil}
19891.1Skamil
19901.1SkamilATF_TC_BODY(io_read_d2, tc)
19911.1Skamil{
19921.1Skamil	const int exitval = 5;
19931.1Skamil	const int sigval = SIGSTOP;
19941.1Skamil	pid_t child, wpid;
19951.1Skamil	uint16_t lookup_me = 0;
19961.1Skamil	const uint16_t magic = 0x1234;
19971.1Skamil	struct ptrace_io_desc io = {
19981.1Skamil		.piod_op = PIOD_READ_D,
19991.1Skamil		.piod_offs = &lookup_me,
20001.1Skamil		.piod_addr = &lookup_me,
20011.1Skamil		.piod_len = sizeof(lookup_me)
20021.1Skamil	};
20031.1Skamil#if defined(TWAIT_HAVE_STATUS)
20041.1Skamil	int status;
20051.1Skamil#endif
20061.1Skamil
20071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20091.1Skamil	if (child == 0) {
20101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20121.1Skamil
20131.1Skamil		lookup_me = magic;
20141.1Skamil
20151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20171.1Skamil
20181.13Schristos		DPRINTF("Before exiting of the child process\n");
20191.1Skamil		_exit(exitval);
20201.1Skamil	}
20211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20221.1Skamil
20231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20251.1Skamil
20261.1Skamil	validate_status_stopped(status, sigval);
20271.1Skamil
20281.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20291.1Skamil	    child, getpid());
20301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20311.1Skamil
20321.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20331.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
20341.1Skamil
20351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20361.1Skamil	    "without signal to be sent\n");
20371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20381.1Skamil
20391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20411.1Skamil
20421.1Skamil	validate_status_exited(status, exitval);
20431.1Skamil
20441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20451.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20461.1Skamil}
20471.1Skamil
20481.1SkamilATF_TC(io_read_d3);
20491.1SkamilATF_TC_HEAD(io_read_d3, tc)
20501.1Skamil{
20511.1Skamil	atf_tc_set_md_var(tc, "descr",
20521.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
20531.1Skamil}
20541.1Skamil
20551.1SkamilATF_TC_BODY(io_read_d3, tc)
20561.1Skamil{
20571.1Skamil	const int exitval = 5;
20581.1Skamil	const int sigval = SIGSTOP;
20591.1Skamil	pid_t child, wpid;
20601.1Skamil	uint32_t lookup_me = 0;
20611.1Skamil	const uint32_t magic = 0x1234abcd;
20621.1Skamil	struct ptrace_io_desc io = {
20631.1Skamil		.piod_op = PIOD_READ_D,
20641.1Skamil		.piod_offs = &lookup_me,
20651.1Skamil		.piod_addr = &lookup_me,
20661.1Skamil		.piod_len = sizeof(lookup_me)
20671.1Skamil	};
20681.1Skamil#if defined(TWAIT_HAVE_STATUS)
20691.1Skamil	int status;
20701.1Skamil#endif
20711.1Skamil
20721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20741.1Skamil	if (child == 0) {
20751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20771.1Skamil
20781.1Skamil		lookup_me = magic;
20791.1Skamil
20801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20821.1Skamil
20831.13Schristos		DPRINTF("Before exiting of the child process\n");
20841.1Skamil		_exit(exitval);
20851.1Skamil	}
20861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20871.1Skamil
20881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20901.1Skamil
20911.1Skamil	validate_status_stopped(status, sigval);
20921.1Skamil
20931.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20941.1Skamil	    child, getpid());
20951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20961.1Skamil
20971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20981.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
20991.1Skamil
21001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21011.1Skamil	    "without signal to be sent\n");
21021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21031.1Skamil
21041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21061.1Skamil
21071.1Skamil	validate_status_exited(status, exitval);
21081.1Skamil
21091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21111.1Skamil}
21121.1Skamil
21131.1SkamilATF_TC(io_read_d4);
21141.1SkamilATF_TC_HEAD(io_read_d4, tc)
21151.1Skamil{
21161.1Skamil	atf_tc_set_md_var(tc, "descr",
21171.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
21181.1Skamil}
21191.1Skamil
21201.1SkamilATF_TC_BODY(io_read_d4, tc)
21211.1Skamil{
21221.1Skamil	const int exitval = 5;
21231.1Skamil	const int sigval = SIGSTOP;
21241.1Skamil	pid_t child, wpid;
21251.1Skamil	uint64_t lookup_me = 0;
21261.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
21271.1Skamil	struct ptrace_io_desc io = {
21281.1Skamil		.piod_op = PIOD_READ_D,
21291.1Skamil		.piod_offs = &lookup_me,
21301.1Skamil		.piod_addr = &lookup_me,
21311.1Skamil		.piod_len = sizeof(lookup_me)
21321.1Skamil	};
21331.1Skamil#if defined(TWAIT_HAVE_STATUS)
21341.1Skamil	int status;
21351.1Skamil#endif
21361.1Skamil
21371.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21381.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21391.1Skamil	if (child == 0) {
21401.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21411.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21421.1Skamil
21431.1Skamil		lookup_me = magic;
21441.1Skamil
21451.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21461.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21471.1Skamil
21481.13Schristos		DPRINTF("Before exiting of the child process\n");
21491.1Skamil		_exit(exitval);
21501.1Skamil	}
21511.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21521.1Skamil
21531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21551.1Skamil
21561.1Skamil	validate_status_stopped(status, sigval);
21571.1Skamil
21581.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21591.1Skamil	    child, getpid());
21601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21611.1Skamil
21621.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21631.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
21641.1Skamil
21651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21661.1Skamil	    "without signal to be sent\n");
21671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21681.1Skamil
21691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21711.1Skamil
21721.1Skamil	validate_status_exited(status, exitval);
21731.1Skamil
21741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21751.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21761.1Skamil}
21771.1Skamil
21781.1SkamilATF_TC(io_write_d1);
21791.1SkamilATF_TC_HEAD(io_write_d1, tc)
21801.1Skamil{
21811.1Skamil	atf_tc_set_md_var(tc, "descr",
21821.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
21831.1Skamil}
21841.1Skamil
21851.1SkamilATF_TC_BODY(io_write_d1, tc)
21861.1Skamil{
21871.1Skamil	const int exitval = 5;
21881.1Skamil	const int sigval = SIGSTOP;
21891.1Skamil	pid_t child, wpid;
21901.1Skamil	uint8_t lookup_me = 0;
21911.1Skamil	const uint8_t magic = 0xab;
21921.1Skamil	struct ptrace_io_desc io = {
21931.1Skamil		.piod_op = PIOD_WRITE_D,
21941.1Skamil		.piod_offs = &lookup_me,
21951.1Skamil		.piod_addr = &lookup_me,
21961.1Skamil		.piod_len = sizeof(lookup_me)
21971.1Skamil	};
21981.1Skamil#if defined(TWAIT_HAVE_STATUS)
21991.1Skamil	int status;
22001.1Skamil#endif
22011.1Skamil
22021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22041.1Skamil	if (child == 0) {
22051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22071.1Skamil
22081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22101.1Skamil
22111.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22121.1Skamil
22131.13Schristos		DPRINTF("Before exiting of the child process\n");
22141.1Skamil		_exit(exitval);
22151.1Skamil	}
22161.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22171.1Skamil
22181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22201.1Skamil
22211.1Skamil	validate_status_stopped(status, sigval);
22221.1Skamil
22231.1Skamil	lookup_me = magic;
22241.1Skamil
22251.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22261.1Skamil	    child, getpid());
22271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22281.1Skamil
22291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22301.1Skamil	    "without signal to be sent\n");
22311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22321.1Skamil
22331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22351.1Skamil
22361.1Skamil	validate_status_exited(status, exitval);
22371.1Skamil
22381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22401.1Skamil}
22411.1Skamil
22421.1SkamilATF_TC(io_write_d2);
22431.1SkamilATF_TC_HEAD(io_write_d2, tc)
22441.1Skamil{
22451.1Skamil	atf_tc_set_md_var(tc, "descr",
22461.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
22471.1Skamil}
22481.1Skamil
22491.1SkamilATF_TC_BODY(io_write_d2, tc)
22501.1Skamil{
22511.1Skamil	const int exitval = 5;
22521.1Skamil	const int sigval = SIGSTOP;
22531.1Skamil	pid_t child, wpid;
22541.1Skamil	uint16_t lookup_me = 0;
22551.1Skamil	const uint16_t magic = 0xab12;
22561.1Skamil	struct ptrace_io_desc io = {
22571.1Skamil		.piod_op = PIOD_WRITE_D,
22581.1Skamil		.piod_offs = &lookup_me,
22591.1Skamil		.piod_addr = &lookup_me,
22601.1Skamil		.piod_len = sizeof(lookup_me)
22611.1Skamil	};
22621.1Skamil#if defined(TWAIT_HAVE_STATUS)
22631.1Skamil	int status;
22641.1Skamil#endif
22651.1Skamil
22661.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22671.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22681.1Skamil	if (child == 0) {
22691.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22701.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22711.1Skamil
22721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22741.1Skamil
22751.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22761.1Skamil
22771.13Schristos		DPRINTF("Before exiting of the child process\n");
22781.1Skamil		_exit(exitval);
22791.1Skamil	}
22801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22811.1Skamil
22821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22841.1Skamil
22851.1Skamil	validate_status_stopped(status, sigval);
22861.1Skamil
22871.1Skamil	lookup_me = magic;
22881.1Skamil
22891.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22901.1Skamil	    child, getpid());
22911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22921.1Skamil
22931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22941.1Skamil	    "without signal to be sent\n");
22951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22961.1Skamil
22971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22991.1Skamil
23001.1Skamil	validate_status_exited(status, exitval);
23011.1Skamil
23021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23041.1Skamil}
23051.1Skamil
23061.1SkamilATF_TC(io_write_d3);
23071.1SkamilATF_TC_HEAD(io_write_d3, tc)
23081.1Skamil{
23091.1Skamil	atf_tc_set_md_var(tc, "descr",
23101.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
23111.1Skamil}
23121.1Skamil
23131.1SkamilATF_TC_BODY(io_write_d3, tc)
23141.1Skamil{
23151.1Skamil	const int exitval = 5;
23161.1Skamil	const int sigval = SIGSTOP;
23171.1Skamil	pid_t child, wpid;
23181.1Skamil	uint32_t lookup_me = 0;
23191.1Skamil	const uint32_t magic = 0xab127643;
23201.1Skamil	struct ptrace_io_desc io = {
23211.1Skamil		.piod_op = PIOD_WRITE_D,
23221.1Skamil		.piod_offs = &lookup_me,
23231.1Skamil		.piod_addr = &lookup_me,
23241.1Skamil		.piod_len = sizeof(lookup_me)
23251.1Skamil	};
23261.1Skamil#if defined(TWAIT_HAVE_STATUS)
23271.1Skamil	int status;
23281.1Skamil#endif
23291.1Skamil
23301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23321.1Skamil	if (child == 0) {
23331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23351.1Skamil
23361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23381.1Skamil
23391.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23401.1Skamil
23411.13Schristos		DPRINTF("Before exiting of the child process\n");
23421.1Skamil		_exit(exitval);
23431.1Skamil	}
23441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23451.1Skamil
23461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23481.1Skamil
23491.1Skamil	validate_status_stopped(status, sigval);
23501.1Skamil
23511.1Skamil	lookup_me = magic;
23521.1Skamil
23531.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23541.1Skamil	    child, getpid());
23551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23561.1Skamil
23571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23581.1Skamil	    "without signal to be sent\n");
23591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23601.1Skamil
23611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23631.1Skamil
23641.1Skamil	validate_status_exited(status, exitval);
23651.1Skamil
23661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23681.1Skamil}
23691.1Skamil
23701.1SkamilATF_TC(io_write_d4);
23711.1SkamilATF_TC_HEAD(io_write_d4, tc)
23721.1Skamil{
23731.1Skamil	atf_tc_set_md_var(tc, "descr",
23741.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
23751.1Skamil}
23761.1Skamil
23771.1SkamilATF_TC_BODY(io_write_d4, tc)
23781.1Skamil{
23791.1Skamil	const int exitval = 5;
23801.1Skamil	const int sigval = SIGSTOP;
23811.1Skamil	pid_t child, wpid;
23821.1Skamil	uint64_t lookup_me = 0;
23831.1Skamil	const uint64_t magic = 0xab12764376490123;
23841.1Skamil	struct ptrace_io_desc io = {
23851.1Skamil		.piod_op = PIOD_WRITE_D,
23861.1Skamil		.piod_offs = &lookup_me,
23871.1Skamil		.piod_addr = &lookup_me,
23881.1Skamil		.piod_len = sizeof(lookup_me)
23891.1Skamil	};
23901.1Skamil#if defined(TWAIT_HAVE_STATUS)
23911.1Skamil	int status;
23921.1Skamil#endif
23931.1Skamil
23941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23961.1Skamil	if (child == 0) {
23971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23991.1Skamil
24001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24021.1Skamil
24031.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
24041.1Skamil
24051.13Schristos		DPRINTF("Before exiting of the child process\n");
24061.1Skamil		_exit(exitval);
24071.1Skamil	}
24081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24091.1Skamil
24101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24121.1Skamil
24131.1Skamil	validate_status_stopped(status, sigval);
24141.1Skamil
24151.1Skamil	lookup_me = magic;
24161.1Skamil
24171.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24181.1Skamil	    child, getpid());
24191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24201.1Skamil
24211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24221.1Skamil	    "without signal to be sent\n");
24231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24241.1Skamil
24251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24271.1Skamil
24281.1Skamil	validate_status_exited(status, exitval);
24291.1Skamil
24301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24321.1Skamil}
24331.1Skamil
24341.1SkamilATF_TC(io_read_auxv1);
24351.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
24361.1Skamil{
24371.1Skamil	atf_tc_set_md_var(tc, "descr",
24381.1Skamil	    "Verify PT_READ_AUXV called for tracee");
24391.1Skamil}
24401.1Skamil
24411.1SkamilATF_TC_BODY(io_read_auxv1, tc)
24421.1Skamil{
24431.1Skamil	const int exitval = 5;
24441.1Skamil	const int sigval = SIGSTOP;
24451.1Skamil	pid_t child, wpid;
24461.1Skamil#if defined(TWAIT_HAVE_STATUS)
24471.1Skamil	int status;
24481.1Skamil#endif
24491.1Skamil	AuxInfo ai[100], *aip;
24501.1Skamil	struct ptrace_io_desc io = {
24511.1Skamil		.piod_op = PIOD_READ_AUXV,
24521.1Skamil		.piod_offs = 0,
24531.1Skamil		.piod_addr = ai,
24541.1Skamil		.piod_len = sizeof(ai)
24551.1Skamil	};
24561.1Skamil
24571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24591.1Skamil	if (child == 0) {
24601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24621.1Skamil
24631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24651.1Skamil
24661.13Schristos		DPRINTF("Before exiting of the child process\n");
24671.1Skamil		_exit(exitval);
24681.1Skamil	}
24691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24701.1Skamil
24711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24731.1Skamil
24741.1Skamil	validate_status_stopped(status, sigval);
24751.1Skamil
24761.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
24771.1Skamil	    child, getpid());
24781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24791.1Skamil
24801.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
24811.1Skamil	ATF_REQUIRE(io.piod_len > 0);
24821.1Skamil
24831.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
24841.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
24851.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
24861.1Skamil
24871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24881.1Skamil	    "without signal to be sent\n");
24891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24901.1Skamil
24911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24931.1Skamil
24941.1Skamil	validate_status_exited(status, exitval);
24951.1Skamil
24961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24981.1Skamil}
24991.1Skamil
25001.1SkamilATF_TC(read_d1);
25011.1SkamilATF_TC_HEAD(read_d1, tc)
25021.1Skamil{
25031.1Skamil	atf_tc_set_md_var(tc, "descr",
25041.1Skamil	    "Verify PT_READ_D called once");
25051.1Skamil}
25061.1Skamil
25071.1SkamilATF_TC_BODY(read_d1, tc)
25081.1Skamil{
25091.1Skamil	const int exitval = 5;
25101.1Skamil	const int sigval = SIGSTOP;
25111.1Skamil	pid_t child, wpid;
25121.1Skamil	int lookup_me = 0;
25131.1Skamil	const int magic = (int)random();
25141.1Skamil#if defined(TWAIT_HAVE_STATUS)
25151.1Skamil	int status;
25161.1Skamil#endif
25171.1Skamil
25181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25201.1Skamil	if (child == 0) {
25211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25231.1Skamil
25241.1Skamil		lookup_me = magic;
25251.1Skamil
25261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25281.1Skamil
25291.13Schristos		DPRINTF("Before exiting of the child process\n");
25301.1Skamil		_exit(exitval);
25311.1Skamil	}
25321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25331.1Skamil
25341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25361.1Skamil
25371.1Skamil	validate_status_stopped(status, sigval);
25381.1Skamil
25391.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
25401.1Skamil	    child, getpid());
25411.1Skamil	errno = 0;
25421.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
25431.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25441.1Skamil
25451.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
25461.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
25471.1Skamil
25481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25491.1Skamil	    "without signal to be sent\n");
25501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25511.1Skamil
25521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25541.1Skamil
25551.1Skamil	validate_status_exited(status, exitval);
25561.1Skamil
25571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25591.1Skamil}
25601.1Skamil
25611.1SkamilATF_TC(read_d2);
25621.1SkamilATF_TC_HEAD(read_d2, tc)
25631.1Skamil{
25641.1Skamil	atf_tc_set_md_var(tc, "descr",
25651.1Skamil	    "Verify PT_READ_D called twice");
25661.1Skamil}
25671.1Skamil
25681.1SkamilATF_TC_BODY(read_d2, tc)
25691.1Skamil{
25701.1Skamil	const int exitval = 5;
25711.1Skamil	const int sigval = SIGSTOP;
25721.1Skamil	pid_t child, wpid;
25731.1Skamil	int lookup_me1 = 0;
25741.1Skamil	int lookup_me2 = 0;
25751.1Skamil	const int magic1 = (int)random();
25761.1Skamil	const int magic2 = (int)random();
25771.1Skamil#if defined(TWAIT_HAVE_STATUS)
25781.1Skamil	int status;
25791.1Skamil#endif
25801.1Skamil
25811.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25821.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25831.1Skamil	if (child == 0) {
25841.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25851.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25861.1Skamil
25871.1Skamil		lookup_me1 = magic1;
25881.1Skamil		lookup_me2 = magic2;
25891.1Skamil
25901.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25911.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25921.1Skamil
25931.13Schristos		DPRINTF("Before exiting of the child process\n");
25941.1Skamil		_exit(exitval);
25951.1Skamil	}
25961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25971.1Skamil
25981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26001.1Skamil
26011.1Skamil	validate_status_stopped(status, sigval);
26021.1Skamil
26031.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26041.1Skamil	    child, getpid());
26051.1Skamil	errno = 0;
26061.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26071.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26081.1Skamil
26091.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26101.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26111.1Skamil
26121.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26131.1Skamil	    child, getpid());
26141.1Skamil	errno = 0;
26151.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26161.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26171.1Skamil
26181.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26191.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26201.1Skamil
26211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26221.1Skamil	    "without signal to be sent\n");
26231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26241.1Skamil
26251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26271.1Skamil
26281.1Skamil	validate_status_exited(status, exitval);
26291.1Skamil
26301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26321.1Skamil}
26331.1Skamil
26341.1SkamilATF_TC(read_d3);
26351.1SkamilATF_TC_HEAD(read_d3, tc)
26361.1Skamil{
26371.1Skamil	atf_tc_set_md_var(tc, "descr",
26381.1Skamil	    "Verify PT_READ_D called three times");
26391.1Skamil}
26401.1Skamil
26411.1SkamilATF_TC_BODY(read_d3, tc)
26421.1Skamil{
26431.1Skamil	const int exitval = 5;
26441.1Skamil	const int sigval = SIGSTOP;
26451.1Skamil	pid_t child, wpid;
26461.1Skamil	int lookup_me1 = 0;
26471.1Skamil	int lookup_me2 = 0;
26481.1Skamil	int lookup_me3 = 0;
26491.1Skamil	const int magic1 = (int)random();
26501.1Skamil	const int magic2 = (int)random();
26511.1Skamil	const int magic3 = (int)random();
26521.1Skamil#if defined(TWAIT_HAVE_STATUS)
26531.1Skamil	int status;
26541.1Skamil#endif
26551.1Skamil
26561.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26571.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26581.1Skamil	if (child == 0) {
26591.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26601.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26611.1Skamil
26621.1Skamil		lookup_me1 = magic1;
26631.1Skamil		lookup_me2 = magic2;
26641.1Skamil		lookup_me3 = magic3;
26651.1Skamil
26661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26681.1Skamil
26691.13Schristos		DPRINTF("Before exiting of the child process\n");
26701.1Skamil		_exit(exitval);
26711.1Skamil	}
26721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26731.1Skamil
26741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26761.1Skamil
26771.1Skamil	validate_status_stopped(status, sigval);
26781.1Skamil
26791.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26801.1Skamil	    child, getpid());
26811.1Skamil	errno = 0;
26821.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26831.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26841.1Skamil
26851.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26861.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26871.1Skamil
26881.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26891.1Skamil	    child, getpid());
26901.1Skamil	errno = 0;
26911.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26921.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
26931.1Skamil
26941.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26951.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26961.1Skamil
26971.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
26981.1Skamil	    child, getpid());
26991.1Skamil	errno = 0;
27001.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27011.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27021.1Skamil
27031.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27041.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27051.1Skamil
27061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27071.1Skamil	    "without signal to be sent\n");
27081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27091.1Skamil
27101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27121.1Skamil
27131.1Skamil	validate_status_exited(status, exitval);
27141.1Skamil
27151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27171.1Skamil}
27181.1Skamil
27191.1SkamilATF_TC(read_d4);
27201.1SkamilATF_TC_HEAD(read_d4, tc)
27211.1Skamil{
27221.1Skamil	atf_tc_set_md_var(tc, "descr",
27231.1Skamil	    "Verify PT_READ_D called four times");
27241.1Skamil}
27251.1Skamil
27261.1SkamilATF_TC_BODY(read_d4, tc)
27271.1Skamil{
27281.1Skamil	const int exitval = 5;
27291.1Skamil	const int sigval = SIGSTOP;
27301.1Skamil	pid_t child, wpid;
27311.1Skamil	int lookup_me1 = 0;
27321.1Skamil	int lookup_me2 = 0;
27331.1Skamil	int lookup_me3 = 0;
27341.1Skamil	int lookup_me4 = 0;
27351.1Skamil	const int magic1 = (int)random();
27361.1Skamil	const int magic2 = (int)random();
27371.1Skamil	const int magic3 = (int)random();
27381.1Skamil	const int magic4 = (int)random();
27391.1Skamil#if defined(TWAIT_HAVE_STATUS)
27401.1Skamil	int status;
27411.1Skamil#endif
27421.1Skamil
27431.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27441.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27451.1Skamil	if (child == 0) {
27461.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27471.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27481.1Skamil
27491.1Skamil		lookup_me1 = magic1;
27501.1Skamil		lookup_me2 = magic2;
27511.1Skamil		lookup_me3 = magic3;
27521.1Skamil		lookup_me4 = magic4;
27531.1Skamil
27541.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27551.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27561.1Skamil
27571.13Schristos		DPRINTF("Before exiting of the child process\n");
27581.1Skamil		_exit(exitval);
27591.1Skamil	}
27601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27611.1Skamil
27621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27641.1Skamil
27651.1Skamil	validate_status_stopped(status, sigval);
27661.1Skamil
27671.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
27681.1Skamil	    child, getpid());
27691.1Skamil	errno = 0;
27701.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
27711.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27721.1Skamil
27731.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27741.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27751.1Skamil
27761.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27771.1Skamil	    child, getpid());
27781.1Skamil	errno = 0;
27791.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27801.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27811.1Skamil
27821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27831.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27841.1Skamil
27851.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27861.1Skamil	    child, getpid());
27871.1Skamil	errno = 0;
27881.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27891.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27901.1Skamil
27911.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27921.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27931.1Skamil
27941.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
27951.1Skamil	    child, getpid());
27961.1Skamil	errno = 0;
27971.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
27981.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
27991.1Skamil
28001.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
28011.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
28021.1Skamil
28031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28041.1Skamil	    "without signal to be sent\n");
28051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28061.1Skamil
28071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28091.1Skamil
28101.1Skamil	validate_status_exited(status, exitval);
28111.1Skamil
28121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28141.1Skamil}
28151.1Skamil
28161.1SkamilATF_TC(write_d1);
28171.1SkamilATF_TC_HEAD(write_d1, tc)
28181.1Skamil{
28191.1Skamil	atf_tc_set_md_var(tc, "descr",
28201.1Skamil	    "Verify PT_WRITE_D called once");
28211.1Skamil}
28221.1Skamil
28231.1SkamilATF_TC_BODY(write_d1, tc)
28241.1Skamil{
28251.1Skamil	const int exitval = 5;
28261.1Skamil	const int sigval = SIGSTOP;
28271.1Skamil	pid_t child, wpid;
28281.1Skamil	int lookup_me = 0;
28291.1Skamil	const int magic = (int)random();
28301.1Skamil#if defined(TWAIT_HAVE_STATUS)
28311.1Skamil	int status;
28321.1Skamil#endif
28331.1Skamil
28341.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28351.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28361.1Skamil	if (child == 0) {
28371.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28381.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28391.1Skamil
28401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28421.1Skamil
28431.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
28441.1Skamil
28451.13Schristos		DPRINTF("Before exiting of the child process\n");
28461.1Skamil		_exit(exitval);
28471.1Skamil	}
28481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28491.1Skamil
28501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28521.1Skamil
28531.1Skamil	validate_status_stopped(status, sigval);
28541.1Skamil
28551.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
28561.1Skamil	    child, getpid());
28571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
28581.1Skamil
28591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28601.1Skamil	    "without signal to be sent\n");
28611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28621.1Skamil
28631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28651.1Skamil
28661.1Skamil	validate_status_exited(status, exitval);
28671.1Skamil
28681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28701.1Skamil}
28711.1Skamil
28721.1SkamilATF_TC(write_d2);
28731.1SkamilATF_TC_HEAD(write_d2, tc)
28741.1Skamil{
28751.1Skamil	atf_tc_set_md_var(tc, "descr",
28761.1Skamil	    "Verify PT_WRITE_D called twice");
28771.1Skamil}
28781.1Skamil
28791.1SkamilATF_TC_BODY(write_d2, tc)
28801.1Skamil{
28811.1Skamil	const int exitval = 5;
28821.1Skamil	const int sigval = SIGSTOP;
28831.1Skamil	pid_t child, wpid;
28841.1Skamil	int lookup_me1 = 0;
28851.1Skamil	int lookup_me2 = 0;
28861.1Skamil	const int magic1 = (int)random();
28871.1Skamil	const int magic2 = (int)random();
28881.1Skamil#if defined(TWAIT_HAVE_STATUS)
28891.1Skamil	int status;
28901.1Skamil#endif
28911.1Skamil
28921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28941.1Skamil	if (child == 0) {
28951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28971.1Skamil
28981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29001.1Skamil
29011.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29021.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29031.1Skamil
29041.13Schristos		DPRINTF("Before exiting of the child process\n");
29051.1Skamil		_exit(exitval);
29061.1Skamil	}
29071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29081.1Skamil
29091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29111.1Skamil
29121.1Skamil	validate_status_stopped(status, sigval);
29131.1Skamil
29141.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29151.1Skamil	    child, getpid());
29161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29171.1Skamil
29181.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29191.1Skamil	    child, getpid());
29201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29211.1Skamil
29221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29231.1Skamil	    "without signal to be sent\n");
29241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29251.1Skamil
29261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29281.1Skamil
29291.1Skamil	validate_status_exited(status, exitval);
29301.1Skamil
29311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29331.1Skamil}
29341.1Skamil
29351.1SkamilATF_TC(write_d3);
29361.1SkamilATF_TC_HEAD(write_d3, tc)
29371.1Skamil{
29381.1Skamil	atf_tc_set_md_var(tc, "descr",
29391.1Skamil	    "Verify PT_WRITE_D called three times");
29401.1Skamil}
29411.1Skamil
29421.1SkamilATF_TC_BODY(write_d3, tc)
29431.1Skamil{
29441.1Skamil	const int exitval = 5;
29451.1Skamil	const int sigval = SIGSTOP;
29461.1Skamil	pid_t child, wpid;
29471.1Skamil	int lookup_me1 = 0;
29481.1Skamil	int lookup_me2 = 0;
29491.1Skamil	int lookup_me3 = 0;
29501.1Skamil	const int magic1 = (int)random();
29511.1Skamil	const int magic2 = (int)random();
29521.1Skamil	const int magic3 = (int)random();
29531.1Skamil#if defined(TWAIT_HAVE_STATUS)
29541.1Skamil	int status;
29551.1Skamil#endif
29561.1Skamil
29571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29591.1Skamil	if (child == 0) {
29601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29621.1Skamil
29631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29651.1Skamil
29661.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29671.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29681.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
29691.1Skamil
29701.13Schristos		DPRINTF("Before exiting of the child process\n");
29711.1Skamil		_exit(exitval);
29721.1Skamil	}
29731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29741.1Skamil
29751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29771.1Skamil
29781.1Skamil	validate_status_stopped(status, sigval);
29791.1Skamil
29801.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29811.1Skamil	    child, getpid());
29821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29831.1Skamil
29841.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29851.1Skamil	    child, getpid());
29861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29871.1Skamil
29881.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
29891.1Skamil	    child, getpid());
29901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
29911.1Skamil
29921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29931.1Skamil	    "without signal to be sent\n");
29941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29951.1Skamil
29961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29981.1Skamil
29991.1Skamil	validate_status_exited(status, exitval);
30001.1Skamil
30011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30021.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30031.1Skamil}
30041.1Skamil
30051.1SkamilATF_TC(write_d4);
30061.1SkamilATF_TC_HEAD(write_d4, tc)
30071.1Skamil{
30081.1Skamil	atf_tc_set_md_var(tc, "descr",
30091.1Skamil	    "Verify PT_WRITE_D called four times");
30101.1Skamil}
30111.1Skamil
30121.1SkamilATF_TC_BODY(write_d4, tc)
30131.1Skamil{
30141.1Skamil	const int exitval = 5;
30151.1Skamil	const int sigval = SIGSTOP;
30161.1Skamil	pid_t child, wpid;
30171.1Skamil	int lookup_me1 = 0;
30181.1Skamil	int lookup_me2 = 0;
30191.1Skamil	int lookup_me3 = 0;
30201.1Skamil	int lookup_me4 = 0;
30211.1Skamil	const int magic1 = (int)random();
30221.1Skamil	const int magic2 = (int)random();
30231.1Skamil	const int magic3 = (int)random();
30241.1Skamil	const int magic4 = (int)random();
30251.1Skamil#if defined(TWAIT_HAVE_STATUS)
30261.1Skamil	int status;
30271.1Skamil#endif
30281.1Skamil
30291.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30301.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30311.1Skamil	if (child == 0) {
30321.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30331.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30341.1Skamil
30351.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30361.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30371.1Skamil
30381.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
30391.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
30401.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
30411.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
30421.1Skamil
30431.13Schristos		DPRINTF("Before exiting of the child process\n");
30441.1Skamil		_exit(exitval);
30451.1Skamil	}
30461.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30471.1Skamil
30481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30501.1Skamil
30511.1Skamil	validate_status_stopped(status, sigval);
30521.1Skamil
30531.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
30541.1Skamil	    child, getpid());
30551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
30561.1Skamil
30571.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30581.1Skamil	    child, getpid());
30591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30601.1Skamil
30611.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30621.1Skamil	    child, getpid());
30631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30641.1Skamil
30651.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
30661.1Skamil	    child, getpid());
30671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
30681.1Skamil
30691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30701.1Skamil	    "without signal to be sent\n");
30711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30721.1Skamil
30731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30751.1Skamil
30761.1Skamil	validate_status_exited(status, exitval);
30771.1Skamil
30781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30801.1Skamil}
30811.1Skamil
30821.1SkamilATF_TC(io_read_d_write_d_handshake1);
30831.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
30841.1Skamil{
30851.1Skamil	atf_tc_set_md_var(tc, "descr",
30861.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
30871.1Skamil}
30881.1Skamil
30891.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
30901.1Skamil{
30911.1Skamil	const int exitval = 5;
30921.1Skamil	const int sigval = SIGSTOP;
30931.1Skamil	pid_t child, wpid;
30941.1Skamil	uint8_t lookup_me_fromtracee = 0;
30951.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
30961.1Skamil	uint8_t lookup_me_totracee = 0;
30971.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
30981.1Skamil	struct ptrace_io_desc io_fromtracee = {
30991.1Skamil		.piod_op = PIOD_READ_D,
31001.1Skamil		.piod_offs = &lookup_me_fromtracee,
31011.1Skamil		.piod_addr = &lookup_me_fromtracee,
31021.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31031.1Skamil	};
31041.1Skamil	struct ptrace_io_desc io_totracee = {
31051.1Skamil		.piod_op = PIOD_WRITE_D,
31061.1Skamil		.piod_offs = &lookup_me_totracee,
31071.1Skamil		.piod_addr = &lookup_me_totracee,
31081.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31091.1Skamil	};
31101.1Skamil#if defined(TWAIT_HAVE_STATUS)
31111.1Skamil	int status;
31121.1Skamil#endif
31131.1Skamil
31141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31161.1Skamil	if (child == 0) {
31171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31191.1Skamil
31201.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31211.1Skamil
31221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31241.1Skamil
31251.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31261.1Skamil
31271.13Schristos		DPRINTF("Before exiting of the child process\n");
31281.1Skamil		_exit(exitval);
31291.1Skamil	}
31301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31311.1Skamil
31321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31341.1Skamil
31351.1Skamil	validate_status_stopped(status, sigval);
31361.1Skamil
31371.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31381.1Skamil	    child, getpid());
31391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
31401.1Skamil
31411.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31421.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
31431.1Skamil	    magic_fromtracee);
31441.1Skamil
31451.1Skamil	lookup_me_totracee = magic_totracee;
31461.1Skamil
31471.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
31481.1Skamil	    child, getpid());
31491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
31501.1Skamil
31511.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
31521.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
31531.1Skamil	    magic_totracee);
31541.1Skamil
31551.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31561.1Skamil	    "without signal to be sent\n");
31571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31581.1Skamil
31591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31611.1Skamil
31621.1Skamil	validate_status_exited(status, exitval);
31631.1Skamil
31641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31651.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31661.1Skamil}
31671.1Skamil
31681.1SkamilATF_TC(io_read_d_write_d_handshake2);
31691.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
31701.1Skamil{
31711.1Skamil	atf_tc_set_md_var(tc, "descr",
31721.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
31731.1Skamil}
31741.1Skamil
31751.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
31761.1Skamil{
31771.1Skamil	const int exitval = 5;
31781.1Skamil	const int sigval = SIGSTOP;
31791.1Skamil	pid_t child, wpid;
31801.1Skamil	uint8_t lookup_me_fromtracee = 0;
31811.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31821.1Skamil	uint8_t lookup_me_totracee = 0;
31831.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31841.1Skamil	struct ptrace_io_desc io_fromtracee = {
31851.1Skamil		.piod_op = PIOD_READ_D,
31861.1Skamil		.piod_offs = &lookup_me_fromtracee,
31871.1Skamil		.piod_addr = &lookup_me_fromtracee,
31881.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31891.1Skamil	};
31901.1Skamil	struct ptrace_io_desc io_totracee = {
31911.1Skamil		.piod_op = PIOD_WRITE_D,
31921.1Skamil		.piod_offs = &lookup_me_totracee,
31931.1Skamil		.piod_addr = &lookup_me_totracee,
31941.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31951.1Skamil	};
31961.1Skamil#if defined(TWAIT_HAVE_STATUS)
31971.1Skamil	int status;
31981.1Skamil#endif
31991.1Skamil
32001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32021.1Skamil	if (child == 0) {
32031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32051.1Skamil
32061.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32071.1Skamil
32081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32101.1Skamil
32111.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32121.1Skamil
32131.13Schristos		DPRINTF("Before exiting of the child process\n");
32141.1Skamil		_exit(exitval);
32151.1Skamil	}
32161.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32171.1Skamil
32181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32201.1Skamil
32211.1Skamil	validate_status_stopped(status, sigval);
32221.1Skamil
32231.1Skamil	lookup_me_totracee = magic_totracee;
32241.1Skamil
32251.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
32261.1Skamil	    child, getpid());
32271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
32281.1Skamil
32291.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
32301.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
32311.1Skamil	    magic_totracee);
32321.1Skamil
32331.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32341.1Skamil	    child, getpid());
32351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
32361.1Skamil
32371.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32381.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
32391.1Skamil	    magic_fromtracee);
32401.1Skamil
32411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32421.1Skamil	    "without signal to be sent\n");
32431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32441.1Skamil
32451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32471.1Skamil
32481.1Skamil	validate_status_exited(status, exitval);
32491.1Skamil
32501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32521.1Skamil}
32531.1Skamil
32541.1SkamilATF_TC(read_d_write_d_handshake1);
32551.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
32561.1Skamil{
32571.1Skamil	atf_tc_set_md_var(tc, "descr",
32581.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
32591.1Skamil}
32601.1Skamil
32611.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
32621.1Skamil{
32631.1Skamil	const int exitval = 5;
32641.1Skamil	const int sigval = SIGSTOP;
32651.1Skamil	pid_t child, wpid;
32661.1Skamil	int lookup_me_fromtracee = 0;
32671.1Skamil	const int magic_fromtracee = (int)random();
32681.1Skamil	int lookup_me_totracee = 0;
32691.1Skamil	const int magic_totracee = (int)random();
32701.1Skamil#if defined(TWAIT_HAVE_STATUS)
32711.1Skamil	int status;
32721.1Skamil#endif
32731.1Skamil
32741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32761.1Skamil	if (child == 0) {
32771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32791.1Skamil
32801.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32811.1Skamil
32821.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32831.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32841.1Skamil
32851.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32861.1Skamil
32871.13Schristos		DPRINTF("Before exiting of the child process\n");
32881.1Skamil		_exit(exitval);
32891.1Skamil	}
32901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32911.1Skamil
32921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32941.1Skamil
32951.1Skamil	validate_status_stopped(status, sigval);
32961.1Skamil
32971.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32981.1Skamil	    child, getpid());
32991.1Skamil	errno = 0;
33001.1Skamil	lookup_me_fromtracee =
33011.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33021.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33031.1Skamil
33041.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33051.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33061.1Skamil	    magic_fromtracee);
33071.1Skamil
33081.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33091.1Skamil	    child, getpid());
33101.1Skamil	ATF_REQUIRE
33111.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33121.1Skamil	    != -1);
33131.1Skamil
33141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33151.1Skamil	    "without signal to be sent\n");
33161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33171.1Skamil
33181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33201.1Skamil
33211.1Skamil	validate_status_exited(status, exitval);
33221.1Skamil
33231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33251.1Skamil}
33261.1Skamil
33271.1SkamilATF_TC(read_d_write_d_handshake2);
33281.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
33291.1Skamil{
33301.1Skamil	atf_tc_set_md_var(tc, "descr",
33311.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
33321.1Skamil}
33331.1Skamil
33341.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
33351.1Skamil{
33361.1Skamil	const int exitval = 5;
33371.1Skamil	const int sigval = SIGSTOP;
33381.1Skamil	pid_t child, wpid;
33391.1Skamil	int lookup_me_fromtracee = 0;
33401.1Skamil	const int magic_fromtracee = (int)random();
33411.1Skamil	int lookup_me_totracee = 0;
33421.1Skamil	const int magic_totracee = (int)random();
33431.1Skamil#if defined(TWAIT_HAVE_STATUS)
33441.1Skamil	int status;
33451.1Skamil#endif
33461.1Skamil
33471.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33481.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33491.1Skamil	if (child == 0) {
33501.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33511.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33521.1Skamil
33531.1Skamil		lookup_me_fromtracee = magic_fromtracee;
33541.1Skamil
33551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33571.1Skamil
33581.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33591.1Skamil
33601.13Schristos		DPRINTF("Before exiting of the child process\n");
33611.1Skamil		_exit(exitval);
33621.1Skamil	}
33631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33641.1Skamil
33651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33671.1Skamil
33681.1Skamil	validate_status_stopped(status, sigval);
33691.1Skamil
33701.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33711.1Skamil	    child, getpid());
33721.1Skamil	ATF_REQUIRE
33731.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33741.1Skamil	    != -1);
33751.1Skamil
33761.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33771.1Skamil	    child, getpid());
33781.1Skamil	errno = 0;
33791.1Skamil	lookup_me_fromtracee =
33801.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33811.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
33821.1Skamil
33831.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33841.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33851.1Skamil	    magic_fromtracee);
33861.1Skamil
33871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33881.1Skamil	    "without signal to be sent\n");
33891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33901.1Skamil
33911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33931.1Skamil
33941.1Skamil	validate_status_exited(status, exitval);
33951.1Skamil
33961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33981.1Skamil}
33991.1Skamil
34001.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
34011.1Skamilstatic int __used
34021.1Skamildummy_fn1(int a, int b, int c, int d)
34031.1Skamil{
34041.1Skamil
34051.1Skamil	a *= 1;
34061.1Skamil	b += 2;
34071.1Skamil	c -= 3;
34081.1Skamil	d /= 4;
34091.1Skamil
34101.1Skamil	return a + b * c - d;
34111.1Skamil}
34121.1Skamil
34131.1Skamilstatic int __used
34141.1Skamildummy_fn2(int a, int b, int c, int d)
34151.1Skamil{
34161.1Skamil
34171.1Skamil	a *= 4;
34181.1Skamil	b += 3;
34191.1Skamil	c -= 2;
34201.1Skamil	d /= 1;
34211.1Skamil
34221.1Skamil	return a + b * c - d;
34231.1Skamil}
34241.1Skamil
34251.1Skamilstatic int __used
34261.1Skamildummy_fn3(int a, int b, int c, int d)
34271.1Skamil{
34281.1Skamil
34291.1Skamil	a *= 10;
34301.1Skamil	b += 20;
34311.1Skamil	c -= 30;
34321.1Skamil	d /= 40;
34331.1Skamil
34341.1Skamil	return a + b * c - d;
34351.1Skamil}
34361.1Skamil
34371.1Skamilstatic int __used
34381.1Skamildummy_fn4(int a, int b, int c, int d)
34391.1Skamil{
34401.1Skamil
34411.1Skamil	a *= 40;
34421.1Skamil	b += 30;
34431.1Skamil	c -= 20;
34441.1Skamil	d /= 10;
34451.1Skamil
34461.1Skamil	return a + b * c - d;
34471.1Skamil}
34481.1Skamil
34491.1SkamilATF_TC(io_read_i1);
34501.1SkamilATF_TC_HEAD(io_read_i1, tc)
34511.1Skamil{
34521.1Skamil	atf_tc_set_md_var(tc, "descr",
34531.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
34541.1Skamil}
34551.1Skamil
34561.1SkamilATF_TC_BODY(io_read_i1, tc)
34571.1Skamil{
34581.1Skamil	const int exitval = 5;
34591.1Skamil	const int sigval = SIGSTOP;
34601.1Skamil	pid_t child, wpid;
34611.1Skamil	uint8_t lookup_me = 0;
34621.1Skamil	uint8_t magic;
34631.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34641.1Skamil	struct ptrace_io_desc io = {
34651.1Skamil		.piod_op = PIOD_READ_I,
34661.1Skamil		.piod_offs = dummy_fn1,
34671.1Skamil		.piod_addr = &lookup_me,
34681.1Skamil		.piod_len = sizeof(lookup_me)
34691.1Skamil	};
34701.1Skamil#if defined(TWAIT_HAVE_STATUS)
34711.1Skamil	int status;
34721.1Skamil#endif
34731.1Skamil
34741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34761.1Skamil	if (child == 0) {
34771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34791.1Skamil
34801.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34811.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34821.1Skamil
34831.13Schristos		DPRINTF("Before exiting of the child process\n");
34841.1Skamil		_exit(exitval);
34851.1Skamil	}
34861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34871.1Skamil
34881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34901.1Skamil
34911.1Skamil	validate_status_stopped(status, sigval);
34921.1Skamil
34931.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34941.1Skamil	    child, getpid());
34951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34961.1Skamil
34971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34981.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
34991.1Skamil
35001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35011.1Skamil	    "without signal to be sent\n");
35021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35031.1Skamil
35041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35061.1Skamil
35071.1Skamil	validate_status_exited(status, exitval);
35081.1Skamil
35091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35111.1Skamil}
35121.1Skamil
35131.1SkamilATF_TC(io_read_i2);
35141.1SkamilATF_TC_HEAD(io_read_i2, tc)
35151.1Skamil{
35161.1Skamil	atf_tc_set_md_var(tc, "descr",
35171.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
35181.1Skamil}
35191.1Skamil
35201.1SkamilATF_TC_BODY(io_read_i2, tc)
35211.1Skamil{
35221.1Skamil	const int exitval = 5;
35231.1Skamil	const int sigval = SIGSTOP;
35241.1Skamil	pid_t child, wpid;
35251.1Skamil	uint16_t lookup_me = 0;
35261.1Skamil	uint16_t magic;
35271.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35281.1Skamil	struct ptrace_io_desc io = {
35291.1Skamil		.piod_op = PIOD_READ_I,
35301.1Skamil		.piod_offs = dummy_fn1,
35311.1Skamil		.piod_addr = &lookup_me,
35321.1Skamil		.piod_len = sizeof(lookup_me)
35331.1Skamil	};
35341.1Skamil#if defined(TWAIT_HAVE_STATUS)
35351.1Skamil	int status;
35361.1Skamil#endif
35371.1Skamil
35381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35401.1Skamil	if (child == 0) {
35411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35431.1Skamil
35441.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35451.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35461.1Skamil
35471.13Schristos		DPRINTF("Before exiting of the child process\n");
35481.1Skamil		_exit(exitval);
35491.1Skamil	}
35501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35511.1Skamil
35521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35541.1Skamil
35551.1Skamil	validate_status_stopped(status, sigval);
35561.1Skamil
35571.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35581.1Skamil	    child, getpid());
35591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35601.1Skamil
35611.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35621.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
35631.1Skamil
35641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35651.1Skamil	    "without signal to be sent\n");
35661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35671.1Skamil
35681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35701.1Skamil
35711.1Skamil	validate_status_exited(status, exitval);
35721.1Skamil
35731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35741.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35751.1Skamil}
35761.1Skamil
35771.1SkamilATF_TC(io_read_i3);
35781.1SkamilATF_TC_HEAD(io_read_i3, tc)
35791.1Skamil{
35801.1Skamil	atf_tc_set_md_var(tc, "descr",
35811.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
35821.1Skamil}
35831.1Skamil
35841.1SkamilATF_TC_BODY(io_read_i3, tc)
35851.1Skamil{
35861.1Skamil	const int exitval = 5;
35871.1Skamil	const int sigval = SIGSTOP;
35881.1Skamil	pid_t child, wpid;
35891.1Skamil	uint32_t lookup_me = 0;
35901.1Skamil	uint32_t magic;
35911.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35921.1Skamil	struct ptrace_io_desc io = {
35931.1Skamil		.piod_op = PIOD_READ_I,
35941.1Skamil		.piod_offs = dummy_fn1,
35951.1Skamil		.piod_addr = &lookup_me,
35961.1Skamil		.piod_len = sizeof(lookup_me)
35971.1Skamil	};
35981.1Skamil#if defined(TWAIT_HAVE_STATUS)
35991.1Skamil	int status;
36001.1Skamil#endif
36011.1Skamil
36021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36041.1Skamil	if (child == 0) {
36051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36071.1Skamil
36081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36101.1Skamil
36111.13Schristos		DPRINTF("Before exiting of the child process\n");
36121.1Skamil		_exit(exitval);
36131.1Skamil	}
36141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36151.1Skamil
36161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36181.1Skamil
36191.1Skamil	validate_status_stopped(status, sigval);
36201.1Skamil
36211.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36221.1Skamil	    child, getpid());
36231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36241.1Skamil
36251.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36261.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
36271.1Skamil
36281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36291.1Skamil	    "without signal to be sent\n");
36301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36311.1Skamil
36321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36341.1Skamil
36351.1Skamil	validate_status_exited(status, exitval);
36361.1Skamil
36371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36391.1Skamil}
36401.1Skamil
36411.1SkamilATF_TC(io_read_i4);
36421.1SkamilATF_TC_HEAD(io_read_i4, tc)
36431.1Skamil{
36441.1Skamil	atf_tc_set_md_var(tc, "descr",
36451.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
36461.1Skamil}
36471.1Skamil
36481.1SkamilATF_TC_BODY(io_read_i4, tc)
36491.1Skamil{
36501.1Skamil	const int exitval = 5;
36511.1Skamil	const int sigval = SIGSTOP;
36521.1Skamil	pid_t child, wpid;
36531.1Skamil	uint64_t lookup_me = 0;
36541.1Skamil	uint64_t magic;
36551.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36561.1Skamil	struct ptrace_io_desc io = {
36571.1Skamil		.piod_op = PIOD_READ_I,
36581.1Skamil		.piod_offs = dummy_fn1,
36591.1Skamil		.piod_addr = &lookup_me,
36601.1Skamil		.piod_len = sizeof(lookup_me)
36611.1Skamil	};
36621.1Skamil#if defined(TWAIT_HAVE_STATUS)
36631.1Skamil	int status;
36641.1Skamil#endif
36651.1Skamil
36661.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36671.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36681.1Skamil	if (child == 0) {
36691.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36701.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36711.1Skamil
36721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36741.1Skamil
36751.13Schristos		DPRINTF("Before exiting of the child process\n");
36761.1Skamil		_exit(exitval);
36771.1Skamil	}
36781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36791.1Skamil
36801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36821.1Skamil
36831.1Skamil	validate_status_stopped(status, sigval);
36841.1Skamil
36851.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36861.1Skamil	    child, getpid());
36871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36881.1Skamil
36891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36901.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
36911.1Skamil
36921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36931.1Skamil	    "without signal to be sent\n");
36941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36951.1Skamil
36961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36981.1Skamil
36991.1Skamil	validate_status_exited(status, exitval);
37001.1Skamil
37011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37021.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37031.1Skamil}
37041.1Skamil
37051.1SkamilATF_TC(read_i1);
37061.1SkamilATF_TC_HEAD(read_i1, tc)
37071.1Skamil{
37081.1Skamil	atf_tc_set_md_var(tc, "descr",
37091.1Skamil	    "Verify PT_READ_I called once");
37101.1Skamil}
37111.1Skamil
37121.1SkamilATF_TC_BODY(read_i1, tc)
37131.1Skamil{
37141.1Skamil	const int exitval = 5;
37151.1Skamil	const int sigval = SIGSTOP;
37161.1Skamil	pid_t child, wpid;
37171.1Skamil	int lookup_me = 0;
37181.1Skamil	int magic;
37191.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
37201.1Skamil#if defined(TWAIT_HAVE_STATUS)
37211.1Skamil	int status;
37221.1Skamil#endif
37231.1Skamil
37241.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37251.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37261.1Skamil	if (child == 0) {
37271.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37281.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37291.1Skamil
37301.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37311.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37321.1Skamil
37331.13Schristos		DPRINTF("Before exiting of the child process\n");
37341.1Skamil		_exit(exitval);
37351.1Skamil	}
37361.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37371.1Skamil
37381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37401.1Skamil
37411.1Skamil	validate_status_stopped(status, sigval);
37421.1Skamil
37431.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37441.1Skamil	    child, getpid());
37451.1Skamil	errno = 0;
37461.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
37471.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37481.1Skamil
37491.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37501.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
37511.1Skamil
37521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37531.1Skamil	    "without signal to be sent\n");
37541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37551.1Skamil
37561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37581.1Skamil
37591.1Skamil	validate_status_exited(status, exitval);
37601.1Skamil
37611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37631.1Skamil}
37641.1Skamil
37651.1SkamilATF_TC(read_i2);
37661.1SkamilATF_TC_HEAD(read_i2, tc)
37671.1Skamil{
37681.1Skamil	atf_tc_set_md_var(tc, "descr",
37691.1Skamil	    "Verify PT_READ_I called twice");
37701.1Skamil}
37711.1Skamil
37721.1SkamilATF_TC_BODY(read_i2, tc)
37731.1Skamil{
37741.1Skamil	const int exitval = 5;
37751.1Skamil	const int sigval = SIGSTOP;
37761.1Skamil	pid_t child, wpid;
37771.1Skamil	int lookup_me1 = 0;
37781.1Skamil	int lookup_me2 = 0;
37791.1Skamil	int magic1;
37801.1Skamil	int magic2;
37811.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37821.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37831.1Skamil#if defined(TWAIT_HAVE_STATUS)
37841.1Skamil	int status;
37851.1Skamil#endif
37861.1Skamil
37871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37891.1Skamil	if (child == 0) {
37901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37921.1Skamil
37931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37951.1Skamil
37961.13Schristos		DPRINTF("Before exiting of the child process\n");
37971.1Skamil		_exit(exitval);
37981.1Skamil	}
37991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38001.1Skamil
38011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38031.1Skamil
38041.1Skamil	validate_status_stopped(status, sigval);
38051.1Skamil
38061.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38071.1Skamil	    child, getpid());
38081.1Skamil	errno = 0;
38091.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38101.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38111.1Skamil
38121.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38131.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38141.1Skamil
38151.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38161.1Skamil	    child, getpid());
38171.1Skamil	errno = 0;
38181.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38191.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38201.1Skamil
38211.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38221.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38231.1Skamil
38241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38251.1Skamil	    "without signal to be sent\n");
38261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38271.1Skamil
38281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38301.1Skamil
38311.1Skamil	validate_status_exited(status, exitval);
38321.1Skamil
38331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38351.1Skamil}
38361.1Skamil
38371.1SkamilATF_TC(read_i3);
38381.1SkamilATF_TC_HEAD(read_i3, tc)
38391.1Skamil{
38401.1Skamil	atf_tc_set_md_var(tc, "descr",
38411.1Skamil	    "Verify PT_READ_I called three times");
38421.1Skamil}
38431.1Skamil
38441.1SkamilATF_TC_BODY(read_i3, tc)
38451.1Skamil{
38461.1Skamil	const int exitval = 5;
38471.1Skamil	const int sigval = SIGSTOP;
38481.1Skamil	pid_t child, wpid;
38491.1Skamil	int lookup_me1 = 0;
38501.1Skamil	int lookup_me2 = 0;
38511.1Skamil	int lookup_me3 = 0;
38521.1Skamil	int magic1;
38531.1Skamil	int magic2;
38541.1Skamil	int magic3;
38551.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
38561.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
38571.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
38581.1Skamil#if defined(TWAIT_HAVE_STATUS)
38591.1Skamil	int status;
38601.1Skamil#endif
38611.1Skamil
38621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38641.1Skamil	if (child == 0) {
38651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38671.1Skamil
38681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38701.1Skamil
38711.13Schristos		DPRINTF("Before exiting of the child process\n");
38721.1Skamil		_exit(exitval);
38731.1Skamil	}
38741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38751.1Skamil
38761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38781.1Skamil
38791.1Skamil	validate_status_stopped(status, sigval);
38801.1Skamil
38811.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38821.1Skamil	    child, getpid());
38831.1Skamil	errno = 0;
38841.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38851.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38861.1Skamil
38871.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38881.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38891.1Skamil
38901.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38911.1Skamil	    child, getpid());
38921.1Skamil	errno = 0;
38931.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38941.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
38951.1Skamil
38961.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38971.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38981.1Skamil
38991.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39001.1Skamil	    child, getpid());
39011.1Skamil	errno = 0;
39021.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39031.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39041.1Skamil
39051.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39061.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39071.1Skamil
39081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39091.1Skamil	    "without signal to be sent\n");
39101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39111.1Skamil
39121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39141.1Skamil
39151.1Skamil	validate_status_exited(status, exitval);
39161.1Skamil
39171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39191.1Skamil}
39201.1Skamil
39211.1SkamilATF_TC(read_i4);
39221.1SkamilATF_TC_HEAD(read_i4, tc)
39231.1Skamil{
39241.1Skamil	atf_tc_set_md_var(tc, "descr",
39251.1Skamil	    "Verify PT_READ_I called four times");
39261.1Skamil}
39271.1Skamil
39281.1SkamilATF_TC_BODY(read_i4, tc)
39291.1Skamil{
39301.1Skamil	const int exitval = 5;
39311.1Skamil	const int sigval = SIGSTOP;
39321.1Skamil	pid_t child, wpid;
39331.1Skamil	int lookup_me1 = 0;
39341.1Skamil	int lookup_me2 = 0;
39351.1Skamil	int lookup_me3 = 0;
39361.1Skamil	int lookup_me4 = 0;
39371.1Skamil	int magic1;
39381.1Skamil	int magic2;
39391.1Skamil	int magic3;
39401.1Skamil	int magic4;
39411.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
39421.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
39431.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
39441.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
39451.1Skamil#if defined(TWAIT_HAVE_STATUS)
39461.1Skamil	int status;
39471.1Skamil#endif
39481.1Skamil
39491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39511.1Skamil	if (child == 0) {
39521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39541.1Skamil
39551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39571.1Skamil
39581.13Schristos		DPRINTF("Before exiting of the child process\n");
39591.1Skamil		_exit(exitval);
39601.1Skamil	}
39611.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39621.1Skamil
39631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39651.1Skamil
39661.1Skamil	validate_status_stopped(status, sigval);
39671.1Skamil
39681.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
39691.1Skamil	    child, getpid());
39701.1Skamil	errno = 0;
39711.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39721.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39731.1Skamil
39741.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39751.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39761.1Skamil
39771.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39781.1Skamil	    child, getpid());
39791.1Skamil	errno = 0;
39801.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39811.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39821.1Skamil
39831.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39841.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39851.1Skamil
39861.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39871.1Skamil	    child, getpid());
39881.1Skamil	errno = 0;
39891.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39901.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
39911.1Skamil
39921.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39931.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39941.1Skamil
39951.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
39961.1Skamil	    child, getpid());
39971.1Skamil	errno = 0;
39981.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
39991.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
40001.1Skamil
40011.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
40021.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
40031.1Skamil
40041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40051.1Skamil	    "without signal to be sent\n");
40061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40071.1Skamil
40081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40101.1Skamil
40111.1Skamil	validate_status_exited(status, exitval);
40121.1Skamil
40131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40151.1Skamil}
40161.1Skamil
40171.1Skamil#if defined(HAVE_GPREGS)
40181.1SkamilATF_TC(regs1);
40191.1SkamilATF_TC_HEAD(regs1, tc)
40201.1Skamil{
40211.1Skamil	atf_tc_set_md_var(tc, "descr",
40221.1Skamil	    "Verify plain PT_GETREGS call without further steps");
40231.1Skamil}
40241.1Skamil
40251.1SkamilATF_TC_BODY(regs1, tc)
40261.1Skamil{
40271.1Skamil	const int exitval = 5;
40281.1Skamil	const int sigval = SIGSTOP;
40291.1Skamil	pid_t child, wpid;
40301.1Skamil#if defined(TWAIT_HAVE_STATUS)
40311.1Skamil	int status;
40321.1Skamil#endif
40331.1Skamil	struct reg r;
40341.1Skamil
40351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40371.1Skamil	if (child == 0) {
40381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40401.1Skamil
40411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40431.1Skamil
40441.13Schristos		DPRINTF("Before exiting of the child process\n");
40451.1Skamil		_exit(exitval);
40461.1Skamil	}
40471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40481.1Skamil
40491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40511.1Skamil
40521.1Skamil	validate_status_stopped(status, sigval);
40531.1Skamil
40541.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40561.1Skamil
40571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40581.1Skamil	    "without signal to be sent\n");
40591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40601.1Skamil
40611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40631.1Skamil
40641.1Skamil	validate_status_exited(status, exitval);
40651.1Skamil
40661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40681.1Skamil}
40691.1Skamil#endif
40701.1Skamil
40711.1Skamil#if defined(HAVE_GPREGS)
40721.1SkamilATF_TC(regs2);
40731.1SkamilATF_TC_HEAD(regs2, tc)
40741.1Skamil{
40751.1Skamil	atf_tc_set_md_var(tc, "descr",
40761.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
40771.1Skamil}
40781.1Skamil
40791.1SkamilATF_TC_BODY(regs2, tc)
40801.1Skamil{
40811.1Skamil	const int exitval = 5;
40821.1Skamil	const int sigval = SIGSTOP;
40831.1Skamil	pid_t child, wpid;
40841.1Skamil#if defined(TWAIT_HAVE_STATUS)
40851.1Skamil	int status;
40861.1Skamil#endif
40871.1Skamil	struct reg r;
40881.1Skamil
40891.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40901.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40911.1Skamil	if (child == 0) {
40921.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40931.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40941.1Skamil
40951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40971.1Skamil
40981.13Schristos		DPRINTF("Before exiting of the child process\n");
40991.1Skamil		_exit(exitval);
41001.1Skamil	}
41011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41021.1Skamil
41031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41051.1Skamil
41061.1Skamil	validate_status_stopped(status, sigval);
41071.1Skamil
41081.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41101.1Skamil
41111.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
41121.1Skamil
41131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41141.1Skamil	    "without signal to be sent\n");
41151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41161.1Skamil
41171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41191.1Skamil
41201.1Skamil	validate_status_exited(status, exitval);
41211.1Skamil
41221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41231.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41241.1Skamil}
41251.1Skamil#endif
41261.1Skamil
41271.1Skamil#if defined(HAVE_GPREGS)
41281.1SkamilATF_TC(regs3);
41291.1SkamilATF_TC_HEAD(regs3, tc)
41301.1Skamil{
41311.1Skamil	atf_tc_set_md_var(tc, "descr",
41321.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
41331.1Skamil}
41341.1Skamil
41351.1SkamilATF_TC_BODY(regs3, tc)
41361.1Skamil{
41371.1Skamil	const int exitval = 5;
41381.1Skamil	const int sigval = SIGSTOP;
41391.1Skamil	pid_t child, wpid;
41401.1Skamil#if defined(TWAIT_HAVE_STATUS)
41411.1Skamil	int status;
41421.1Skamil#endif
41431.1Skamil	struct reg r;
41441.1Skamil
41451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41471.1Skamil	if (child == 0) {
41481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41501.1Skamil
41511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41531.1Skamil
41541.13Schristos		DPRINTF("Before exiting of the child process\n");
41551.1Skamil		_exit(exitval);
41561.1Skamil	}
41571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41581.1Skamil
41591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41611.1Skamil
41621.1Skamil	validate_status_stopped(status, sigval);
41631.1Skamil
41641.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41661.1Skamil
41671.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
41681.1Skamil
41691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41701.1Skamil	    "without signal to be sent\n");
41711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41721.1Skamil
41731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41751.1Skamil
41761.1Skamil	validate_status_exited(status, exitval);
41771.1Skamil
41781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41801.1Skamil}
41811.1Skamil#endif
41821.1Skamil
41831.1Skamil#if defined(HAVE_GPREGS)
41841.1SkamilATF_TC(regs4);
41851.1SkamilATF_TC_HEAD(regs4, tc)
41861.1Skamil{
41871.1Skamil	atf_tc_set_md_var(tc, "descr",
41881.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
41891.1Skamil}
41901.1Skamil
41911.1SkamilATF_TC_BODY(regs4, tc)
41921.1Skamil{
41931.1Skamil	const int exitval = 5;
41941.1Skamil	const int sigval = SIGSTOP;
41951.1Skamil	pid_t child, wpid;
41961.1Skamil#if defined(TWAIT_HAVE_STATUS)
41971.1Skamil	int status;
41981.1Skamil#endif
41991.1Skamil	struct reg r;
42001.1Skamil
42011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42031.1Skamil	if (child == 0) {
42041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42061.1Skamil
42071.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42081.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42091.1Skamil
42101.13Schristos		DPRINTF("Before exiting of the child process\n");
42111.1Skamil		_exit(exitval);
42121.1Skamil	}
42131.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42141.1Skamil
42151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42171.1Skamil
42181.1Skamil	validate_status_stopped(status, sigval);
42191.1Skamil
42201.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42221.1Skamil
42231.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
42241.1Skamil
42251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42261.1Skamil	    "without signal to be sent\n");
42271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42281.1Skamil
42291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42311.1Skamil
42321.1Skamil	validate_status_exited(status, exitval);
42331.1Skamil
42341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42361.1Skamil}
42371.1Skamil#endif
42381.1Skamil
42391.1Skamil#if defined(HAVE_GPREGS)
42401.1SkamilATF_TC(regs5);
42411.1SkamilATF_TC_HEAD(regs5, tc)
42421.1Skamil{
42431.1Skamil	atf_tc_set_md_var(tc, "descr",
42441.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
42451.1Skamil}
42461.1Skamil
42471.1SkamilATF_TC_BODY(regs5, tc)
42481.1Skamil{
42491.1Skamil	const int exitval = 5;
42501.1Skamil	const int sigval = SIGSTOP;
42511.1Skamil	pid_t child, wpid;
42521.1Skamil#if defined(TWAIT_HAVE_STATUS)
42531.1Skamil	int status;
42541.1Skamil#endif
42551.1Skamil	struct reg r;
42561.1Skamil
42571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42591.1Skamil	if (child == 0) {
42601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42621.1Skamil
42631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42651.1Skamil
42661.13Schristos		DPRINTF("Before exiting of the child process\n");
42671.1Skamil		_exit(exitval);
42681.1Skamil	}
42691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42701.1Skamil
42711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42731.1Skamil
42741.1Skamil	validate_status_stopped(status, sigval);
42751.1Skamil
42761.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42781.1Skamil
42791.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
42801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42811.1Skamil
42821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42831.1Skamil	    "without signal to be sent\n");
42841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42851.1Skamil
42861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42881.1Skamil
42891.1Skamil	validate_status_exited(status, exitval);
42901.1Skamil
42911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42931.1Skamil}
42941.1Skamil#endif
42951.1Skamil
42961.1Skamil#if defined(HAVE_FPREGS)
42971.1SkamilATF_TC(fpregs1);
42981.1SkamilATF_TC_HEAD(fpregs1, tc)
42991.1Skamil{
43001.1Skamil	atf_tc_set_md_var(tc, "descr",
43011.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
43021.1Skamil}
43031.1Skamil
43041.1SkamilATF_TC_BODY(fpregs1, tc)
43051.1Skamil{
43061.1Skamil	const int exitval = 5;
43071.1Skamil	const int sigval = SIGSTOP;
43081.1Skamil	pid_t child, wpid;
43091.1Skamil#if defined(TWAIT_HAVE_STATUS)
43101.1Skamil	int status;
43111.1Skamil#endif
43121.1Skamil	struct fpreg r;
43131.1Skamil
43141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43161.1Skamil	if (child == 0) {
43171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43191.1Skamil
43201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43221.1Skamil
43231.13Schristos		DPRINTF("Before exiting of the child process\n");
43241.1Skamil		_exit(exitval);
43251.1Skamil	}
43261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43271.1Skamil
43281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43301.1Skamil
43311.1Skamil	validate_status_stopped(status, sigval);
43321.1Skamil
43331.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43351.1Skamil
43361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43371.1Skamil	    "without signal to be sent\n");
43381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43391.1Skamil
43401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43421.1Skamil
43431.1Skamil	validate_status_exited(status, exitval);
43441.1Skamil
43451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43471.1Skamil}
43481.1Skamil#endif
43491.1Skamil
43501.1Skamil#if defined(HAVE_FPREGS)
43511.1SkamilATF_TC(fpregs2);
43521.1SkamilATF_TC_HEAD(fpregs2, tc)
43531.1Skamil{
43541.1Skamil	atf_tc_set_md_var(tc, "descr",
43551.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
43561.1Skamil	    "regs");
43571.1Skamil}
43581.1Skamil
43591.1SkamilATF_TC_BODY(fpregs2, tc)
43601.1Skamil{
43611.1Skamil	const int exitval = 5;
43621.1Skamil	const int sigval = SIGSTOP;
43631.1Skamil	pid_t child, wpid;
43641.1Skamil#if defined(TWAIT_HAVE_STATUS)
43651.1Skamil	int status;
43661.1Skamil#endif
43671.1Skamil	struct fpreg r;
43681.1Skamil
43691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43711.1Skamil	if (child == 0) {
43721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43741.1Skamil
43751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43771.1Skamil
43781.13Schristos		DPRINTF("Before exiting of the child process\n");
43791.1Skamil		_exit(exitval);
43801.1Skamil	}
43811.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43821.1Skamil
43831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43851.1Skamil
43861.1Skamil	validate_status_stopped(status, sigval);
43871.1Skamil
43881.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43901.1Skamil
43911.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
43921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
43931.1Skamil
43941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43951.1Skamil	    "without signal to be sent\n");
43961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43971.1Skamil
43981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44001.1Skamil
44011.1Skamil	validate_status_exited(status, exitval);
44021.1Skamil
44031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44051.1Skamil}
44061.1Skamil#endif
44071.1Skamil
44081.1Skamil#if defined(PT_STEP)
44091.1Skamilstatic void
44101.2Skamilptrace_step(int N, int setstep)
44111.1Skamil{
44121.1Skamil	const int exitval = 5;
44131.1Skamil	const int sigval = SIGSTOP;
44141.1Skamil	pid_t child, wpid;
44151.1Skamil#if defined(TWAIT_HAVE_STATUS)
44161.1Skamil	int status;
44171.1Skamil#endif
44181.1Skamil	int happy;
44191.1Skamil
44201.1Skamil#if defined(__arm__)
44211.1Skamil	/* PT_STEP not supported on arm 32-bit */
44221.1Skamil	atf_tc_expect_fail("PR kern/52119");
44231.1Skamil#endif
44241.1Skamil
44251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44271.1Skamil	if (child == 0) {
44281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44301.1Skamil
44311.1Skamil		happy = check_happy(999);
44321.1Skamil
44331.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44341.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44351.1Skamil
44361.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
44371.1Skamil
44381.13Schristos		DPRINTF("Before exiting of the child process\n");
44391.1Skamil		_exit(exitval);
44401.1Skamil	}
44411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44421.1Skamil
44431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44451.1Skamil
44461.1Skamil	validate_status_stopped(status, sigval);
44471.1Skamil
44481.1Skamil	while (N --> 0) {
44491.2Skamil		if (setstep) {
44501.13Schristos			DPRINTF("Before resuming the child process where it "
44511.2Skamil			    "left off and without signal to be sent (use "
44521.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
44531.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
44541.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
44551.2Skamil			    != -1);
44561.2Skamil		} else {
44571.13Schristos			DPRINTF("Before resuming the child process where it "
44581.2Skamil			    "left off and without signal to be sent (use "
44591.2Skamil			    "PT_STEP)\n");
44601.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
44611.2Skamil			    != -1);
44621.2Skamil		}
44631.1Skamil
44641.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44651.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
44661.1Skamil		    child);
44671.1Skamil
44681.1Skamil		validate_status_stopped(status, SIGTRAP);
44691.2Skamil
44701.2Skamil		if (setstep) {
44711.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
44721.2Skamil		}
44731.1Skamil	}
44741.1Skamil
44751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44761.1Skamil	    "without signal to be sent\n");
44771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44781.1Skamil
44791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44811.1Skamil
44821.1Skamil	validate_status_exited(status, exitval);
44831.1Skamil
44841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44861.1Skamil}
44871.1Skamil#endif
44881.1Skamil
44891.1Skamil#if defined(PT_STEP)
44901.1SkamilATF_TC(step1);
44911.1SkamilATF_TC_HEAD(step1, tc)
44921.1Skamil{
44931.1Skamil	atf_tc_set_md_var(tc, "descr",
44941.1Skamil	    "Verify single PT_STEP call");
44951.1Skamil}
44961.1Skamil
44971.1SkamilATF_TC_BODY(step1, tc)
44981.1Skamil{
44991.2Skamil	ptrace_step(1, 0);
45001.1Skamil}
45011.1Skamil#endif
45021.1Skamil
45031.1Skamil#if defined(PT_STEP)
45041.1SkamilATF_TC(step2);
45051.1SkamilATF_TC_HEAD(step2, tc)
45061.1Skamil{
45071.1Skamil	atf_tc_set_md_var(tc, "descr",
45081.1Skamil	    "Verify PT_STEP called twice");
45091.1Skamil}
45101.1Skamil
45111.1SkamilATF_TC_BODY(step2, tc)
45121.1Skamil{
45131.2Skamil	ptrace_step(2, 0);
45141.1Skamil}
45151.1Skamil#endif
45161.1Skamil
45171.1Skamil#if defined(PT_STEP)
45181.1SkamilATF_TC(step3);
45191.1SkamilATF_TC_HEAD(step3, tc)
45201.1Skamil{
45211.1Skamil	atf_tc_set_md_var(tc, "descr",
45221.1Skamil	    "Verify PT_STEP called three times");
45231.1Skamil}
45241.1Skamil
45251.1SkamilATF_TC_BODY(step3, tc)
45261.1Skamil{
45271.2Skamil	ptrace_step(3, 0);
45281.1Skamil}
45291.1Skamil#endif
45301.1Skamil
45311.1Skamil#if defined(PT_STEP)
45321.1SkamilATF_TC(step4);
45331.1SkamilATF_TC_HEAD(step4, tc)
45341.1Skamil{
45351.1Skamil	atf_tc_set_md_var(tc, "descr",
45361.1Skamil	    "Verify PT_STEP called four times");
45371.1Skamil}
45381.1Skamil
45391.1SkamilATF_TC_BODY(step4, tc)
45401.1Skamil{
45411.2Skamil	ptrace_step(4, 0);
45421.2Skamil}
45431.2Skamil#endif
45441.2Skamil
45451.2Skamil#if defined(PT_STEP)
45461.2SkamilATF_TC(setstep1);
45471.2SkamilATF_TC_HEAD(setstep1, tc)
45481.2Skamil{
45491.2Skamil	atf_tc_set_md_var(tc, "descr",
45501.2Skamil	    "Verify single PT_SETSTEP call");
45511.2Skamil}
45521.2Skamil
45531.2SkamilATF_TC_BODY(setstep1, tc)
45541.2Skamil{
45551.2Skamil	ptrace_step(1, 1);
45561.2Skamil}
45571.2Skamil#endif
45581.2Skamil
45591.2Skamil#if defined(PT_STEP)
45601.2SkamilATF_TC(setstep2);
45611.2SkamilATF_TC_HEAD(setstep2, tc)
45621.2Skamil{
45631.2Skamil	atf_tc_set_md_var(tc, "descr",
45641.2Skamil	    "Verify PT_SETSTEP called twice");
45651.2Skamil}
45661.2Skamil
45671.2SkamilATF_TC_BODY(setstep2, tc)
45681.2Skamil{
45691.2Skamil	ptrace_step(2, 1);
45701.2Skamil}
45711.2Skamil#endif
45721.2Skamil
45731.2Skamil#if defined(PT_STEP)
45741.2SkamilATF_TC(setstep3);
45751.2SkamilATF_TC_HEAD(setstep3, tc)
45761.2Skamil{
45771.2Skamil	atf_tc_set_md_var(tc, "descr",
45781.2Skamil	    "Verify PT_SETSTEP called three times");
45791.2Skamil}
45801.2Skamil
45811.2SkamilATF_TC_BODY(setstep3, tc)
45821.2Skamil{
45831.2Skamil	ptrace_step(3, 1);
45841.2Skamil}
45851.2Skamil#endif
45861.2Skamil
45871.2Skamil#if defined(PT_STEP)
45881.2SkamilATF_TC(setstep4);
45891.2SkamilATF_TC_HEAD(setstep4, tc)
45901.2Skamil{
45911.2Skamil	atf_tc_set_md_var(tc, "descr",
45921.2Skamil	    "Verify PT_SETSTEP called four times");
45931.2Skamil}
45941.2Skamil
45951.2SkamilATF_TC_BODY(setstep4, tc)
45961.2Skamil{
45971.2Skamil	ptrace_step(4, 1);
45981.1Skamil}
45991.1Skamil#endif
46001.1Skamil
46011.1SkamilATF_TC(kill1);
46021.1SkamilATF_TC_HEAD(kill1, tc)
46031.1Skamil{
46041.1Skamil	atf_tc_set_md_var(tc, "descr",
46051.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
46061.1Skamil}
46071.1Skamil
46081.1SkamilATF_TC_BODY(kill1, tc)
46091.1Skamil{
46101.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
46111.1Skamil	pid_t child, wpid;
46121.1Skamil#if defined(TWAIT_HAVE_STATUS)
46131.1Skamil	int status;
46141.1Skamil#endif
46151.1Skamil
46161.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46171.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46181.1Skamil	if (child == 0) {
46191.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46201.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46211.1Skamil
46221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46241.1Skamil
46251.1Skamil		/* NOTREACHED */
46261.1Skamil		FORKEE_ASSERTX(0 &&
46271.1Skamil		    "Child should be terminated by a signal from its parent");
46281.1Skamil	}
46291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46301.1Skamil
46311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46331.1Skamil
46341.1Skamil	validate_status_stopped(status, sigval);
46351.1Skamil
46361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46371.1Skamil	    "without signal to be sent\n");
46381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
46391.1Skamil
46401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46421.1Skamil
46431.1Skamil	validate_status_signaled(status, sigsent, 0);
46441.1Skamil
46451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46471.1Skamil}
46481.1Skamil
46491.1SkamilATF_TC(kill2);
46501.1SkamilATF_TC_HEAD(kill2, tc)
46511.1Skamil{
46521.1Skamil	atf_tc_set_md_var(tc, "descr",
46531.1Skamil	    "Verify that PT_KILL terminates child");
46541.1Skamil}
46551.1Skamil
46561.1SkamilATF_TC_BODY(kill2, tc)
46571.1Skamil{
46581.1Skamil	const int sigval = SIGSTOP;
46591.1Skamil	pid_t child, wpid;
46601.1Skamil#if defined(TWAIT_HAVE_STATUS)
46611.1Skamil	int status;
46621.1Skamil#endif
46631.1Skamil
46641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46661.1Skamil	if (child == 0) {
46671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46691.1Skamil
46701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46721.1Skamil
46731.1Skamil		/* NOTREACHED */
46741.1Skamil		FORKEE_ASSERTX(0 &&
46751.1Skamil		    "Child should be terminated by a signal from its parent");
46761.1Skamil	}
46771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46781.1Skamil
46791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46811.1Skamil
46821.1Skamil	validate_status_stopped(status, sigval);
46831.1Skamil
46841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46851.1Skamil	    "without signal to be sent\n");
46861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
46871.1Skamil
46881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46901.1Skamil
46911.1Skamil	validate_status_signaled(status, SIGKILL, 0);
46921.1Skamil
46931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46941.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46951.1Skamil}
46961.1Skamil
46971.1SkamilATF_TC(lwpinfo1);
46981.1SkamilATF_TC_HEAD(lwpinfo1, tc)
46991.1Skamil{
47001.1Skamil	atf_tc_set_md_var(tc, "descr",
47011.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
47021.1Skamil}
47031.1Skamil
47041.1SkamilATF_TC_BODY(lwpinfo1, tc)
47051.1Skamil{
47061.1Skamil	const int exitval = 5;
47071.1Skamil	const int sigval = SIGSTOP;
47081.1Skamil	pid_t child, wpid;
47091.1Skamil#if defined(TWAIT_HAVE_STATUS)
47101.1Skamil	int status;
47111.1Skamil#endif
47121.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47131.1Skamil
47141.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47151.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47161.1Skamil	if (child == 0) {
47171.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47181.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47191.1Skamil
47201.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47211.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47221.1Skamil
47231.13Schristos		DPRINTF("Before exiting of the child process\n");
47241.1Skamil		_exit(exitval);
47251.1Skamil	}
47261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47271.1Skamil
47281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47301.1Skamil
47311.1Skamil	validate_status_stopped(status, sigval);
47321.1Skamil
47331.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47351.1Skamil
47361.13Schristos	DPRINTF("Assert that there exists a thread\n");
47371.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
47381.1Skamil
47391.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
47401.1Skamil	    info.pl_lwpid);
47411.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
47421.1Skamil	    "Received event %d != expected event %d",
47431.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
47441.1Skamil
47451.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47471.1Skamil
47481.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
47491.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
47501.1Skamil
47511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47521.1Skamil	    "without signal to be sent\n");
47531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47541.1Skamil
47551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47571.1Skamil
47581.1Skamil	validate_status_exited(status, exitval);
47591.1Skamil
47601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47611.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47621.1Skamil}
47631.1Skamil
47641.1Skamil#if defined(TWAIT_HAVE_PID)
47651.1SkamilATF_TC(lwpinfo2);
47661.1SkamilATF_TC_HEAD(lwpinfo2, tc)
47671.1Skamil{
47681.1Skamil	atf_tc_set_md_var(tc, "descr",
47691.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
47701.1Skamil	    "tracer)");
47711.1Skamil}
47721.1Skamil
47731.1SkamilATF_TC_BODY(lwpinfo2, tc)
47741.1Skamil{
47751.1Skamil	struct msg_fds parent_tracee, parent_tracer;
47761.1Skamil	const int exitval_tracee = 5;
47771.1Skamil	const int exitval_tracer = 10;
47781.1Skamil	pid_t tracee, tracer, wpid;
47791.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
47801.1Skamil#if defined(TWAIT_HAVE_STATUS)
47811.1Skamil	int status;
47821.1Skamil#endif
47831.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47841.1Skamil
47851.13Schristos	DPRINTF("Spawn tracee\n");
47861.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
47871.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
47881.1Skamil	tracee = atf_utils_fork();
47891.1Skamil	if (tracee == 0) {
47901.1Skamil
47911.1Skamil		/* Wait for message from the parent */
47921.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
47931.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
47941.1Skamil
47951.1Skamil		_exit(exitval_tracee);
47961.1Skamil	}
47971.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
47981.1Skamil
47991.13Schristos	DPRINTF("Spawn debugger\n");
48001.1Skamil	tracer = atf_utils_fork();
48011.1Skamil	if (tracer == 0) {
48021.1Skamil		/* No IPC to communicate with the child */
48031.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
48041.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
48051.1Skamil
48061.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
48071.1Skamil		FORKEE_REQUIRE_SUCCESS(
48081.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48091.1Skamil
48101.1Skamil		forkee_status_stopped(status, SIGSTOP);
48111.1Skamil
48121.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48131.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48141.1Skamil		    != -1);
48151.1Skamil
48161.13Schristos		DPRINTF("Assert that there exists a thread\n");
48171.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
48181.1Skamil
48191.13Schristos		DPRINTF("Assert that lwp thread %d received event "
48201.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
48211.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
48221.1Skamil
48231.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48241.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48251.1Skamil		    != -1);
48261.1Skamil
48271.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
48281.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
48291.1Skamil
48301.1Skamil		/* Resume tracee with PT_CONTINUE */
48311.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
48321.1Skamil
48331.1Skamil		/* Inform parent that tracer has attached to tracee */
48341.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
48351.1Skamil		/* Wait for parent */
48361.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
48371.1Skamil
48381.1Skamil		/* Wait for tracee and assert that it exited */
48391.1Skamil		FORKEE_REQUIRE_SUCCESS(
48401.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48411.1Skamil
48421.1Skamil		forkee_status_exited(status, exitval_tracee);
48431.1Skamil
48441.13Schristos		DPRINTF("Before exiting of the tracer process\n");
48451.1Skamil		_exit(exitval_tracer);
48461.1Skamil	}
48471.1Skamil
48481.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
48491.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
48501.1Skamil
48511.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
48521.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
48531.1Skamil
48541.13Schristos	DPRINTF("Detect that tracee is zombie\n");
48551.1Skamil	await_zombie(tracee);
48561.1Skamil
48571.13Schristos	DPRINTF("Assert that there is no status about tracee - "
48581.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
48591.1Skamil	TWAIT_REQUIRE_SUCCESS(
48601.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
48611.1Skamil
48621.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
48631.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
48641.1Skamil
48651.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
48661.1Skamil	    TWAIT_FNAME);
48671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
48681.1Skamil	    tracer);
48691.1Skamil
48701.1Skamil	validate_status_exited(status, exitval_tracer);
48711.1Skamil
48721.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
48731.1Skamil	    TWAIT_FNAME);
48741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
48751.1Skamil	    tracee);
48761.1Skamil
48771.1Skamil	validate_status_exited(status, exitval_tracee);
48781.1Skamil
48791.1Skamil	msg_close(&parent_tracer);
48801.1Skamil	msg_close(&parent_tracee);
48811.1Skamil}
48821.1Skamil#endif
48831.1Skamil
48841.1SkamilATF_TC(siginfo1);
48851.1SkamilATF_TC_HEAD(siginfo1, tc)
48861.1Skamil{
48871.1Skamil	atf_tc_set_md_var(tc, "descr",
48881.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
48891.1Skamil}
48901.1Skamil
48911.1SkamilATF_TC_BODY(siginfo1, tc)
48921.1Skamil{
48931.1Skamil	const int exitval = 5;
48941.1Skamil	const int sigval = SIGTRAP;
48951.1Skamil	pid_t child, wpid;
48961.1Skamil#if defined(TWAIT_HAVE_STATUS)
48971.1Skamil	int status;
48981.1Skamil#endif
48991.1Skamil	struct ptrace_siginfo info;
49001.1Skamil	memset(&info, 0, sizeof(info));
49011.1Skamil
49021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49041.1Skamil	if (child == 0) {
49051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49071.1Skamil
49081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49101.1Skamil
49111.13Schristos		DPRINTF("Before exiting of the child process\n");
49121.1Skamil		_exit(exitval);
49131.1Skamil	}
49141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49151.1Skamil
49161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49181.1Skamil
49191.1Skamil	validate_status_stopped(status, sigval);
49201.1Skamil
49211.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49231.1Skamil
49241.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49251.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49261.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49271.1Skamil	    info.psi_siginfo.si_errno);
49281.1Skamil
49291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49301.1Skamil	    "without signal to be sent\n");
49311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49321.1Skamil
49331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49351.1Skamil
49361.1Skamil	validate_status_exited(status, exitval);
49371.1Skamil
49381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49401.1Skamil}
49411.1Skamil
49421.1SkamilATF_TC(siginfo2);
49431.1SkamilATF_TC_HEAD(siginfo2, tc)
49441.1Skamil{
49451.1Skamil	atf_tc_set_md_var(tc, "descr",
49461.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
49471.1Skamil	    "modification of SIGINT from tracee");
49481.1Skamil}
49491.1Skamil
49501.1Skamilstatic int siginfo2_caught = 0;
49511.1Skamil
49521.1Skamilstatic void
49531.1Skamilsiginfo2_sighandler(int sig)
49541.1Skamil{
49551.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
49561.1Skamil
49571.1Skamil	++siginfo2_caught;
49581.1Skamil}
49591.1Skamil
49601.1SkamilATF_TC_BODY(siginfo2, tc)
49611.1Skamil{
49621.1Skamil	const int exitval = 5;
49631.1Skamil	const int sigval = SIGINT;
49641.1Skamil	pid_t child, wpid;
49651.1Skamil	struct sigaction sa;
49661.1Skamil#if defined(TWAIT_HAVE_STATUS)
49671.1Skamil	int status;
49681.1Skamil#endif
49691.1Skamil	struct ptrace_siginfo info;
49701.1Skamil	memset(&info, 0, sizeof(info));
49711.1Skamil
49721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49741.1Skamil	if (child == 0) {
49751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49771.1Skamil
49781.1Skamil		sa.sa_handler = siginfo2_sighandler;
49791.1Skamil		sa.sa_flags = SA_SIGINFO;
49801.1Skamil		sigemptyset(&sa.sa_mask);
49811.1Skamil
49821.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
49831.1Skamil
49841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49861.1Skamil
49871.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
49881.1Skamil
49891.13Schristos		DPRINTF("Before exiting of the child process\n");
49901.1Skamil		_exit(exitval);
49911.1Skamil	}
49921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49931.1Skamil
49941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49961.1Skamil
49971.1Skamil	validate_status_stopped(status, sigval);
49981.1Skamil
49991.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50011.1Skamil
50021.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50031.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50041.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50051.1Skamil	    info.psi_siginfo.si_errno);
50061.1Skamil
50071.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50091.1Skamil
50101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50111.1Skamil	    "without signal to be sent\n");
50121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
50131.1Skamil
50141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50161.1Skamil
50171.1Skamil	validate_status_exited(status, exitval);
50181.1Skamil
50191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50211.1Skamil}
50221.1Skamil
50231.1SkamilATF_TC(siginfo3);
50241.1SkamilATF_TC_HEAD(siginfo3, tc)
50251.1Skamil{
50261.1Skamil	atf_tc_set_md_var(tc, "descr",
50271.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
50281.1Skamil	    "setting signal to new value");
50291.1Skamil}
50301.1Skamil
50311.1Skamilstatic int siginfo3_caught = 0;
50321.1Skamil
50331.1Skamilstatic void
50341.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
50351.1Skamil{
50361.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
50371.1Skamil
50381.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
50391.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
50401.1Skamil
50411.1Skamil	++siginfo3_caught;
50421.1Skamil}
50431.1Skamil
50441.1SkamilATF_TC_BODY(siginfo3, tc)
50451.1Skamil{
50461.1Skamil	const int exitval = 5;
50471.1Skamil	const int sigval = SIGINT;
50481.1Skamil	const int sigfaked = SIGTRAP;
50491.1Skamil	const int sicodefaked = TRAP_BRKPT;
50501.1Skamil	pid_t child, wpid;
50511.1Skamil	struct sigaction sa;
50521.1Skamil#if defined(TWAIT_HAVE_STATUS)
50531.1Skamil	int status;
50541.1Skamil#endif
50551.1Skamil	struct ptrace_siginfo info;
50561.1Skamil	memset(&info, 0, sizeof(info));
50571.1Skamil
50581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50601.1Skamil	if (child == 0) {
50611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50631.1Skamil
50641.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
50651.1Skamil		sa.sa_flags = SA_SIGINFO;
50661.1Skamil		sigemptyset(&sa.sa_mask);
50671.1Skamil
50681.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
50691.1Skamil
50701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50721.1Skamil
50731.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
50741.1Skamil
50751.13Schristos		DPRINTF("Before exiting of the child process\n");
50761.1Skamil		_exit(exitval);
50771.1Skamil	}
50781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50791.1Skamil
50801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50821.1Skamil
50831.1Skamil	validate_status_stopped(status, sigval);
50841.1Skamil
50851.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50871.1Skamil
50881.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50891.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50901.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50911.1Skamil	    info.psi_siginfo.si_errno);
50921.1Skamil
50931.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
50941.1Skamil	    sigfaked, sicodefaked);
50951.1Skamil	info.psi_siginfo.si_signo = sigfaked;
50961.1Skamil	info.psi_siginfo.si_code = sicodefaked;
50971.1Skamil
50981.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
51001.1Skamil
51011.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51031.1Skamil
51041.13Schristos	DPRINTF("Before checking siginfo_t\n");
51051.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
51061.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
51071.1Skamil
51081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51091.1Skamil	    "without signal to be sent\n");
51101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
51111.1Skamil
51121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51141.1Skamil
51151.1Skamil	validate_status_exited(status, exitval);
51161.1Skamil
51171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51181.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51191.1Skamil}
51201.1Skamil
51211.1SkamilATF_TC(siginfo4);
51221.1SkamilATF_TC_HEAD(siginfo4, tc)
51231.1Skamil{
51241.1Skamil	atf_tc_set_md_var(tc, "descr",
51251.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
51261.1Skamil}
51271.1Skamil
51281.1SkamilATF_TC_BODY(siginfo4, tc)
51291.1Skamil{
51301.1Skamil	const int sigval = SIGTRAP;
51311.1Skamil	pid_t child, wpid;
51321.1Skamil#if defined(TWAIT_HAVE_STATUS)
51331.1Skamil	int status;
51341.1Skamil#endif
51351.1Skamil
51361.1Skamil	struct ptrace_siginfo info;
51371.1Skamil	memset(&info, 0, sizeof(info));
51381.1Skamil
51391.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51401.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51411.1Skamil	if (child == 0) {
51421.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51431.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51441.1Skamil
51451.13Schristos		DPRINTF("Before calling execve(2) from child\n");
51461.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
51471.1Skamil
51481.1Skamil		FORKEE_ASSERT(0 && "Not reached");
51491.1Skamil	}
51501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51511.1Skamil
51521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51541.1Skamil
51551.1Skamil	validate_status_stopped(status, sigval);
51561.1Skamil
51571.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51591.1Skamil
51601.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51611.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51621.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51631.1Skamil	    info.psi_siginfo.si_errno);
51641.1Skamil
51651.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51661.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
51671.1Skamil
51681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51691.1Skamil	    "without signal to be sent\n");
51701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51711.1Skamil
51721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51741.1Skamil
51751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51761.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51771.1Skamil}
51781.1Skamil
51791.1Skamil#if defined(TWAIT_HAVE_PID)
51801.1SkamilATF_TC(siginfo5);
51811.1SkamilATF_TC_HEAD(siginfo5, tc)
51821.1Skamil{
51831.1Skamil	atf_tc_set_md_var(tc, "descr",
51841.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
51851.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
51861.1Skamil}
51871.1Skamil
51881.1SkamilATF_TC_BODY(siginfo5, tc)
51891.1Skamil{
51901.1Skamil	const int exitval = 5;
51911.1Skamil	const int exitval2 = 15;
51921.1Skamil	const int sigval = SIGSTOP;
51931.1Skamil	pid_t child, child2, wpid;
51941.1Skamil#if defined(TWAIT_HAVE_STATUS)
51951.1Skamil	int status;
51961.1Skamil#endif
51971.1Skamil	ptrace_state_t state;
51981.1Skamil	const int slen = sizeof(state);
51991.1Skamil	ptrace_event_t event;
52001.1Skamil	const int elen = sizeof(event);
52011.1Skamil	struct ptrace_siginfo info;
52021.1Skamil
52031.1Skamil	memset(&info, 0, sizeof(info));
52041.1Skamil
52051.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52061.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52071.1Skamil	if (child == 0) {
52081.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52091.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52101.1Skamil
52111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52131.1Skamil
52141.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
52151.1Skamil
52161.1Skamil		if (child2 == 0)
52171.1Skamil			_exit(exitval2);
52181.1Skamil
52191.1Skamil		FORKEE_REQUIRE_SUCCESS
52201.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
52211.1Skamil
52221.1Skamil		forkee_status_exited(status, exitval2);
52231.1Skamil
52241.13Schristos		DPRINTF("Before exiting of the child process\n");
52251.1Skamil		_exit(exitval);
52261.1Skamil	}
52271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52281.1Skamil
52291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52311.1Skamil
52321.1Skamil	validate_status_stopped(status, sigval);
52331.1Skamil
52341.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52361.1Skamil
52371.13Schristos	DPRINTF("Before checking siginfo_t\n");
52381.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
52391.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
52401.1Skamil
52411.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
52421.1Skamil	event.pe_set_event = PTRACE_FORK;
52431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52441.1Skamil
52451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52461.1Skamil	    "without signal to be sent\n");
52471.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
52481.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
52491.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
52501.1Skamil                "state.pe_other_pid=child)\n", child);
52511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52521.1Skamil
52531.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
52541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52551.1Skamil
52561.1Skamil	validate_status_stopped(status, SIGTRAP);
52571.1Skamil
52581.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52601.1Skamil
52611.13Schristos	DPRINTF("Before checking siginfo_t\n");
52621.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52631.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52641.1Skamil
52651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52661.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52671.1Skamil
52681.1Skamil	child2 = state.pe_other_pid;
52691.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
52701.1Skamil
52711.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
52721.1Skamil	    TWAIT_FNAME, child2, child);
52731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52741.1Skamil	    child2);
52751.1Skamil
52761.1Skamil	validate_status_stopped(status, SIGTRAP);
52771.1Skamil
52781.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52801.1Skamil
52811.13Schristos	DPRINTF("Before checking siginfo_t\n");
52821.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52831.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52841.1Skamil
52851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
52861.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52871.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
52881.1Skamil
52891.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
52901.1Skamil	    "without signal to be sent\n");
52911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
52921.1Skamil
52931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52941.1Skamil	    "without signal to be sent\n");
52951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52961.1Skamil
52971.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
52981.1Skamil	    TWAIT_FNAME);
52991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
53001.1Skamil	    child2);
53011.1Skamil
53021.1Skamil	validate_status_exited(status, exitval2);
53031.1Skamil
53041.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
53051.1Skamil	    TWAIT_FNAME);
53061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
53071.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
53081.1Skamil
53091.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53101.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
53111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53121.1Skamil
53131.1Skamil	validate_status_stopped(status, SIGCHLD);
53141.1Skamil
53151.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53171.1Skamil
53181.13Schristos	DPRINTF("Before checking siginfo_t\n");
53191.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
53201.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
53211.1Skamil
53221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53231.1Skamil	    "without signal to be sent\n");
53241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53251.1Skamil
53261.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53271.1Skamil	    TWAIT_FNAME);
53281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53291.1Skamil
53301.1Skamil	validate_status_exited(status, exitval);
53311.1Skamil
53321.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53331.1Skamil	    TWAIT_FNAME);
53341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53351.1Skamil}
53361.1Skamil#endif
53371.1Skamil
53381.1Skamil#if defined(PT_STEP)
53391.1SkamilATF_TC(siginfo6);
53401.1SkamilATF_TC_HEAD(siginfo6, tc)
53411.1Skamil{
53421.1Skamil	atf_tc_set_md_var(tc, "descr",
53431.1Skamil	    "Verify single PT_STEP call with signal information check");
53441.1Skamil}
53451.1Skamil
53461.1SkamilATF_TC_BODY(siginfo6, tc)
53471.1Skamil{
53481.1Skamil	const int exitval = 5;
53491.1Skamil	const int sigval = SIGSTOP;
53501.1Skamil	pid_t child, wpid;
53511.1Skamil#if defined(TWAIT_HAVE_STATUS)
53521.1Skamil	int status;
53531.1Skamil#endif
53541.1Skamil	int happy;
53551.1Skamil	struct ptrace_siginfo info;
53561.1Skamil
53571.1Skamil#if defined(__arm__)
53581.1Skamil	/* PT_STEP not supported on arm 32-bit */
53591.1Skamil	atf_tc_expect_fail("PR kern/52119");
53601.1Skamil#endif
53611.1Skamil
53621.1Skamil	memset(&info, 0, sizeof(info));
53631.1Skamil
53641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53661.1Skamil	if (child == 0) {
53671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53691.1Skamil
53701.1Skamil		happy = check_happy(100);
53711.1Skamil
53721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53741.1Skamil
53751.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
53761.1Skamil
53771.13Schristos		DPRINTF("Before exiting of the child process\n");
53781.1Skamil		_exit(exitval);
53791.1Skamil	}
53801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53811.1Skamil
53821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53841.1Skamil
53851.1Skamil	validate_status_stopped(status, sigval);
53861.1Skamil
53871.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53891.1Skamil
53901.13Schristos	DPRINTF("Before checking siginfo_t\n");
53911.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
53921.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
53931.1Skamil
53941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53951.1Skamil	    "without signal to be sent (use PT_STEP)\n");
53961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
53971.1Skamil
53981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54001.1Skamil
54011.1Skamil	validate_status_stopped(status, SIGTRAP);
54021.1Skamil
54031.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
54041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
54051.1Skamil
54061.13Schristos	DPRINTF("Before checking siginfo_t\n");
54071.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
54081.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
54091.1Skamil
54101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54111.1Skamil	    "without signal to be sent\n");
54121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54131.1Skamil
54141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54161.1Skamil
54171.1Skamil	validate_status_exited(status, exitval);
54181.1Skamil
54191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54211.1Skamil}
54221.1Skamil#endif
54231.1Skamil
54241.1Skamilvolatile lwpid_t the_lwp_id = 0;
54251.1Skamil
54261.1Skamilstatic void
54271.1Skamillwp_main_func(void *arg)
54281.1Skamil{
54291.1Skamil	the_lwp_id = _lwp_self();
54301.1Skamil	_lwp_exit();
54311.1Skamil}
54321.1Skamil
54331.1SkamilATF_TC(lwp_create1);
54341.1SkamilATF_TC_HEAD(lwp_create1, tc)
54351.1Skamil{
54361.1Skamil	atf_tc_set_md_var(tc, "descr",
54371.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
54381.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
54391.1Skamil}
54401.1Skamil
54411.1SkamilATF_TC_BODY(lwp_create1, tc)
54421.1Skamil{
54431.1Skamil	const int exitval = 5;
54441.1Skamil	const int sigval = SIGSTOP;
54451.1Skamil	pid_t child, wpid;
54461.1Skamil#if defined(TWAIT_HAVE_STATUS)
54471.1Skamil	int status;
54481.1Skamil#endif
54491.1Skamil	ptrace_state_t state;
54501.1Skamil	const int slen = sizeof(state);
54511.1Skamil	ptrace_event_t event;
54521.1Skamil	const int elen = sizeof(event);
54531.1Skamil	ucontext_t uc;
54541.1Skamil	lwpid_t lid;
54551.1Skamil	static const size_t ssize = 16*1024;
54561.1Skamil	void *stack;
54571.1Skamil
54581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54601.1Skamil	if (child == 0) {
54611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54631.1Skamil
54641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54661.1Skamil
54671.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
54681.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
54691.1Skamil
54701.13Schristos		DPRINTF("Before making context for new lwp in child\n");
54711.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
54721.1Skamil
54731.13Schristos		DPRINTF("Before creating new in child\n");
54741.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
54751.1Skamil
54761.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
54771.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
54781.1Skamil
54791.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
54801.1Skamil		    "are the same\n", lid, the_lwp_id);
54811.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
54821.1Skamil
54831.13Schristos		DPRINTF("Before exiting of the child process\n");
54841.1Skamil		_exit(exitval);
54851.1Skamil	}
54861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54871.1Skamil
54881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54901.1Skamil
54911.1Skamil	validate_status_stopped(status, sigval);
54921.1Skamil
54931.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
54941.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
54951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
54961.1Skamil
54971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54981.1Skamil	    "without signal to be sent\n");
54991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55001.1Skamil
55011.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55021.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55041.1Skamil
55051.1Skamil	validate_status_stopped(status, SIGTRAP);
55061.1Skamil
55071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55081.1Skamil
55091.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
55101.1Skamil
55111.1Skamil	lid = state.pe_lwp;
55121.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
55131.1Skamil
55141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55151.1Skamil	    "without signal to be sent\n");
55161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55171.1Skamil
55181.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
55191.1Skamil	    TWAIT_FNAME);
55201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55211.1Skamil
55221.1Skamil	validate_status_exited(status, exitval);
55231.1Skamil
55241.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
55251.1Skamil	    TWAIT_FNAME);
55261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55271.1Skamil}
55281.1Skamil
55291.1SkamilATF_TC(lwp_exit1);
55301.1SkamilATF_TC_HEAD(lwp_exit1, tc)
55311.1Skamil{
55321.1Skamil	atf_tc_set_md_var(tc, "descr",
55331.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
55341.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
55351.1Skamil}
55361.1Skamil
55371.1SkamilATF_TC_BODY(lwp_exit1, tc)
55381.1Skamil{
55391.1Skamil	const int exitval = 5;
55401.1Skamil	const int sigval = SIGSTOP;
55411.1Skamil	pid_t child, wpid;
55421.1Skamil#if defined(TWAIT_HAVE_STATUS)
55431.1Skamil	int status;
55441.1Skamil#endif
55451.1Skamil	ptrace_state_t state;
55461.1Skamil	const int slen = sizeof(state);
55471.1Skamil	ptrace_event_t event;
55481.1Skamil	const int elen = sizeof(event);
55491.1Skamil	ucontext_t uc;
55501.1Skamil	lwpid_t lid;
55511.1Skamil	static const size_t ssize = 16*1024;
55521.1Skamil	void *stack;
55531.1Skamil
55541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55561.1Skamil	if (child == 0) {
55571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55591.1Skamil
55601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55621.1Skamil
55631.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
55641.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
55651.1Skamil
55661.13Schristos		DPRINTF("Before making context for new lwp in child\n");
55671.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
55681.1Skamil
55691.13Schristos		DPRINTF("Before creating new in child\n");
55701.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
55711.1Skamil
55721.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
55731.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
55741.1Skamil
55751.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
55761.1Skamil		    "are the same\n", lid, the_lwp_id);
55771.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
55781.1Skamil
55791.13Schristos		DPRINTF("Before exiting of the child process\n");
55801.1Skamil		_exit(exitval);
55811.1Skamil	}
55821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55831.1Skamil
55841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55861.1Skamil
55871.1Skamil	validate_status_stopped(status, sigval);
55881.1Skamil
55891.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55901.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
55911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55921.1Skamil
55931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55941.1Skamil	    "without signal to be sent\n");
55951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55961.1Skamil
55971.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55981.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56001.1Skamil
56011.1Skamil	validate_status_stopped(status, SIGTRAP);
56021.1Skamil
56031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
56041.1Skamil
56051.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
56061.1Skamil
56071.1Skamil	lid = state.pe_lwp;
56081.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
56091.1Skamil
56101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56111.1Skamil	    "without signal to be sent\n");
56121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56131.1Skamil
56141.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
56151.1Skamil	    TWAIT_FNAME);
56161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56171.1Skamil
56181.1Skamil	validate_status_exited(status, exitval);
56191.1Skamil
56201.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
56211.1Skamil	    TWAIT_FNAME);
56221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56231.1Skamil}
56241.1Skamil
56251.1SkamilATF_TC(signal1);
56261.1SkamilATF_TC_HEAD(signal1, tc)
56271.1Skamil{
56281.1Skamil	atf_tc_set_md_var(tc, "descr",
56291.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
56301.1Skamil	    "from catching other signals");
56311.1Skamil}
56321.1Skamil
56331.1SkamilATF_TC_BODY(signal1, tc)
56341.1Skamil{
56351.1Skamil	const int exitval = 5;
56361.1Skamil	const int sigval = SIGSTOP;
56371.1Skamil	const int sigmasked = SIGTRAP;
56381.1Skamil	const int signotmasked = SIGINT;
56391.1Skamil	pid_t child, wpid;
56401.1Skamil#if defined(TWAIT_HAVE_STATUS)
56411.1Skamil	int status;
56421.1Skamil#endif
56431.1Skamil	sigset_t intmask;
56441.1Skamil
56451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56471.1Skamil	if (child == 0) {
56481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56501.1Skamil
56511.1Skamil		sigemptyset(&intmask);
56521.1Skamil		sigaddset(&intmask, sigmasked);
56531.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56541.1Skamil
56551.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56561.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56571.1Skamil
56581.13Schristos		DPRINTF("Before raising %s from child\n",
56591.1Skamil		    strsignal(signotmasked));
56601.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
56611.1Skamil
56621.13Schristos		DPRINTF("Before exiting of the child process\n");
56631.1Skamil		_exit(exitval);
56641.1Skamil	}
56651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56661.1Skamil
56671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56691.1Skamil
56701.1Skamil	validate_status_stopped(status, sigval);
56711.1Skamil
56721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56731.1Skamil	    "without signal to be sent\n");
56741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56751.1Skamil
56761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56781.1Skamil
56791.1Skamil	validate_status_stopped(status, signotmasked);
56801.1Skamil
56811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56821.1Skamil	    "without signal to be sent\n");
56831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56841.1Skamil
56851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56871.1Skamil
56881.1Skamil	validate_status_exited(status, exitval);
56891.1Skamil
56901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56921.1Skamil}
56931.1Skamil
56941.1SkamilATF_TC(signal2);
56951.1SkamilATF_TC_HEAD(signal2, tc)
56961.1Skamil{
56971.1Skamil	atf_tc_set_md_var(tc, "descr",
56981.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
56991.1Skamil	    "catching this raised signal");
57001.1Skamil}
57011.1Skamil
57021.1SkamilATF_TC_BODY(signal2, tc)
57031.1Skamil{
57041.1Skamil	const int exitval = 5;
57051.1Skamil	const int sigval = SIGSTOP;
57061.1Skamil	const int sigmasked = SIGTRAP;
57071.1Skamil	pid_t child, wpid;
57081.1Skamil#if defined(TWAIT_HAVE_STATUS)
57091.1Skamil	int status;
57101.1Skamil#endif
57111.1Skamil	sigset_t intmask;
57121.1Skamil
57131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57151.1Skamil	if (child == 0) {
57161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57181.1Skamil
57191.1Skamil		sigemptyset(&intmask);
57201.1Skamil		sigaddset(&intmask, sigmasked);
57211.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57221.1Skamil
57231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57251.1Skamil
57261.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
57271.1Skamil		    strsignal(sigmasked));
57281.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
57291.1Skamil
57301.13Schristos		DPRINTF("Before exiting of the child process\n");
57311.1Skamil		_exit(exitval);
57321.1Skamil	}
57331.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57341.1Skamil
57351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57371.1Skamil
57381.1Skamil	validate_status_stopped(status, sigval);
57391.1Skamil
57401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57411.1Skamil	    "without signal to be sent\n");
57421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57431.1Skamil
57441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57461.1Skamil
57471.1Skamil	validate_status_exited(status, exitval);
57481.1Skamil
57491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57511.1Skamil}
57521.1Skamil
57531.1SkamilATF_TC(signal3);
57541.1SkamilATF_TC_HEAD(signal3, tc)
57551.1Skamil{
57561.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57571.1Skamil	atf_tc_set_md_var(tc, "descr",
57581.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57591.1Skamil	    "catching software breakpoints");
57601.1Skamil}
57611.1Skamil
57621.1SkamilATF_TC_BODY(signal3, tc)
57631.1Skamil{
57641.1Skamil	const int exitval = 5;
57651.1Skamil	const int sigval = SIGSTOP;
57661.1Skamil	const int sigmasked = SIGTRAP;
57671.1Skamil	pid_t child, wpid;
57681.1Skamil#if defined(TWAIT_HAVE_STATUS)
57691.1Skamil	int status;
57701.1Skamil#endif
57711.1Skamil	sigset_t intmask;
57721.1Skamil
57731.20Skamil	atf_tc_expect_fail("PR kern/51918");
57741.20Skamil
57751.20Skamil	// This test breaks now on some ports, temporarily disable it
57761.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
57771.20Skamil
57781.10Smartin#if defined(__sparc__)
57791.7Skamil	atf_tc_expect_timeout("PR kern/52167");
57801.7Skamil
57811.7Skamil	// timeout wins, failure still valid
57821.7Skamil	// atf_tc_expect_fail("PR kern/51918");
57831.7Skamil#endif
57841.1Skamil
57851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57871.1Skamil	if (child == 0) {
57881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57901.1Skamil
57911.1Skamil		sigemptyset(&intmask);
57921.1Skamil		sigaddset(&intmask, sigmasked);
57931.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57941.1Skamil
57951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57971.1Skamil
57981.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
57991.4Skamil
58001.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
58011.4Skamil		PTRACE_BREAKPOINT_ASM;
58021.1Skamil#else
58031.4Skamil		/* port me */
58041.1Skamil#endif
58051.1Skamil
58061.13Schristos		DPRINTF("Before exiting of the child process\n");
58071.1Skamil		_exit(exitval);
58081.1Skamil	}
58091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58101.1Skamil
58111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58131.1Skamil
58141.1Skamil	validate_status_stopped(status, sigval);
58151.1Skamil
58161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58171.1Skamil	    "without signal to be sent\n");
58181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58191.1Skamil
58201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58221.1Skamil
58231.1Skamil	validate_status_stopped(status, sigmasked);
58241.1Skamil
58251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58261.1Skamil	    "without signal to be sent\n");
58271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58281.1Skamil
58291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58311.1Skamil
58321.1Skamil	validate_status_exited(status, exitval);
58331.1Skamil
58341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58361.1Skamil}
58371.1Skamil
58381.1Skamil#if defined(PT_STEP)
58391.1SkamilATF_TC(signal4);
58401.1SkamilATF_TC_HEAD(signal4, tc)
58411.1Skamil{
58421.1Skamil	atf_tc_set_md_var(tc, "descr",
58431.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58441.1Skamil	    "catching single step trap");
58451.1Skamil}
58461.1Skamil
58471.1SkamilATF_TC_BODY(signal4, tc)
58481.1Skamil{
58491.1Skamil	const int exitval = 5;
58501.1Skamil	const int sigval = SIGSTOP;
58511.1Skamil	const int sigmasked = SIGTRAP;
58521.1Skamil	pid_t child, wpid;
58531.1Skamil#if defined(TWAIT_HAVE_STATUS)
58541.1Skamil	int status;
58551.1Skamil#endif
58561.1Skamil	sigset_t intmask;
58571.1Skamil	int happy;
58581.1Skamil
58591.1Skamil#if defined(__arm__)
58601.5Skamil	/* PT_STEP not supported on arm 32-bit */
58611.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
58621.1Skamil#endif
58631.1Skamil
58641.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58651.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58661.1Skamil	if (child == 0) {
58671.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58681.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58691.1Skamil
58701.1Skamil		happy = check_happy(100);
58711.1Skamil
58721.1Skamil		sigemptyset(&intmask);
58731.1Skamil		sigaddset(&intmask, sigmasked);
58741.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58751.1Skamil
58761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58781.1Skamil
58791.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
58801.1Skamil
58811.13Schristos		DPRINTF("Before exiting of the child process\n");
58821.1Skamil		_exit(exitval);
58831.1Skamil	}
58841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58851.1Skamil
58861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58881.1Skamil
58891.1Skamil	validate_status_stopped(status, sigval);
58901.1Skamil
58911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58921.1Skamil	    "without signal to be sent\n");
58931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
58941.1Skamil
58951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58971.1Skamil
58981.1Skamil	validate_status_stopped(status, sigmasked);
58991.1Skamil
59001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59011.1Skamil	    "without signal to be sent\n");
59021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59031.1Skamil
59041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59061.1Skamil
59071.1Skamil	validate_status_exited(status, exitval);
59081.1Skamil
59091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59111.1Skamil}
59121.1Skamil#endif
59131.1Skamil
59141.1SkamilATF_TC(signal5);
59151.1SkamilATF_TC_HEAD(signal5, tc)
59161.1Skamil{
59171.1Skamil	atf_tc_set_md_var(tc, "descr",
59181.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59191.1Skamil	    "catching exec() breakpoint");
59201.1Skamil}
59211.1Skamil
59221.1SkamilATF_TC_BODY(signal5, tc)
59231.1Skamil{
59241.1Skamil	const int exitval = 5;
59251.1Skamil	const int sigval = SIGSTOP;
59261.1Skamil	const int sigmasked = SIGTRAP;
59271.1Skamil	pid_t child, wpid;
59281.1Skamil#if defined(TWAIT_HAVE_STATUS)
59291.1Skamil	int status;
59301.1Skamil#endif
59311.1Skamil	sigset_t intmask;
59321.1Skamil
59331.14Schristos	atf_tc_expect_fail("wrong signal");
59341.14Schristos
59351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59371.1Skamil	if (child == 0) {
59381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59401.1Skamil
59411.1Skamil		sigemptyset(&intmask);
59421.1Skamil		sigaddset(&intmask, sigmasked);
59431.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59441.1Skamil
59451.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59461.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59471.1Skamil
59481.13Schristos		DPRINTF("Before calling execve(2) from child\n");
59491.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
59501.1Skamil
59511.13Schristos		DPRINTF("Before exiting of the child process\n");
59521.1Skamil		_exit(exitval);
59531.1Skamil	}
59541.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59551.1Skamil
59561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59581.1Skamil
59591.1Skamil	validate_status_stopped(status, sigval);
59601.1Skamil
59611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59621.1Skamil	    "without signal to be sent\n");
59631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59641.1Skamil
59651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59671.1Skamil
59681.1Skamil	validate_status_stopped(status, sigmasked);
59691.1Skamil
59701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59711.1Skamil	    "without signal to be sent\n");
59721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59731.1Skamil
59741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59761.1Skamil
59771.1Skamil	validate_status_exited(status, exitval);
59781.1Skamil
59791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59811.1Skamil}
59821.1Skamil
59831.1Skamil#if defined(TWAIT_HAVE_PID)
59841.1SkamilATF_TC(signal6);
59851.1SkamilATF_TC_HEAD(signal6, tc)
59861.1Skamil{
59871.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
59881.1Skamil	atf_tc_set_md_var(tc, "descr",
59891.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59901.1Skamil	    "catching PTRACE_FORK breakpoint");
59911.1Skamil}
59921.1Skamil
59931.1SkamilATF_TC_BODY(signal6, tc)
59941.1Skamil{
59951.1Skamil	const int exitval = 5;
59961.1Skamil	const int exitval2 = 15;
59971.1Skamil	const int sigval = SIGSTOP;
59981.1Skamil	const int sigmasked = SIGTRAP;
59991.1Skamil	pid_t child, child2, wpid;
60001.1Skamil#if defined(TWAIT_HAVE_STATUS)
60011.1Skamil	int status;
60021.1Skamil#endif
60031.1Skamil	sigset_t intmask;
60041.1Skamil	ptrace_state_t state;
60051.1Skamil	const int slen = sizeof(state);
60061.1Skamil	ptrace_event_t event;
60071.1Skamil	const int elen = sizeof(event);
60081.1Skamil
60091.14Schristos	atf_tc_expect_timeout("PR kern/51918");
60101.14Schristos
60111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60131.1Skamil	if (child == 0) {
60141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60161.1Skamil
60171.1Skamil		sigemptyset(&intmask);
60181.1Skamil		sigaddset(&intmask, sigmasked);
60191.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60201.1Skamil
60211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60231.1Skamil
60241.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
60251.1Skamil
60261.1Skamil		if (child2 == 0)
60271.1Skamil			_exit(exitval2);
60281.1Skamil
60291.1Skamil		FORKEE_REQUIRE_SUCCESS
60301.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60311.1Skamil
60321.1Skamil		forkee_status_exited(status, exitval2);
60331.1Skamil
60341.13Schristos		DPRINTF("Before exiting of the child process\n");
60351.1Skamil		_exit(exitval);
60361.1Skamil	}
60371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60381.1Skamil
60391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60411.1Skamil
60421.1Skamil	validate_status_stopped(status, sigval);
60431.1Skamil
60441.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
60451.1Skamil	event.pe_set_event = PTRACE_FORK;
60461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60471.1Skamil
60481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60491.1Skamil	    "without signal to be sent\n");
60501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60511.1Skamil
60521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60541.1Skamil
60551.1Skamil	validate_status_stopped(status, sigmasked);
60561.1Skamil
60571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60581.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60591.1Skamil
60601.1Skamil	child2 = state.pe_other_pid;
60611.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
60621.1Skamil
60631.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
60641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60651.1Skamil	    child2);
60661.1Skamil
60671.1Skamil	validate_status_stopped(status, SIGTRAP);
60681.1Skamil
60691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
60701.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60711.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
60721.1Skamil
60731.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
60741.1Skamil	    "without signal to be sent\n");
60751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
60761.1Skamil
60771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60781.1Skamil	    "without signal to be sent\n");
60791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60801.1Skamil
60811.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60821.1Skamil	    TWAIT_FNAME);
60831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60841.1Skamil	    child2);
60851.1Skamil
60861.1Skamil	validate_status_exited(status, exitval2);
60871.1Skamil
60881.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
60891.1Skamil	    TWAIT_FNAME);
60901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
60911.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
60921.1Skamil
60931.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60941.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
60951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60961.1Skamil
60971.1Skamil	validate_status_stopped(status, SIGCHLD);
60981.1Skamil
60991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61001.1Skamil	    "without signal to be sent\n");
61011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61021.1Skamil
61031.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61041.1Skamil	    TWAIT_FNAME);
61051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61061.1Skamil
61071.1Skamil	validate_status_exited(status, exitval);
61081.1Skamil
61091.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61101.1Skamil	    TWAIT_FNAME);
61111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61121.1Skamil}
61131.1Skamil#endif
61141.1Skamil
61151.1Skamil#if defined(TWAIT_HAVE_PID)
61161.1SkamilATF_TC(signal7);
61171.1SkamilATF_TC_HEAD(signal7, tc)
61181.1Skamil{
61191.1Skamil	atf_tc_set_md_var(tc, "descr",
61201.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61211.1Skamil	    "catching PTRACE_VFORK breakpoint");
61221.1Skamil}
61231.1Skamil
61241.1SkamilATF_TC_BODY(signal7, tc)
61251.1Skamil{
61261.1Skamil	const int exitval = 5;
61271.1Skamil	const int exitval2 = 15;
61281.1Skamil	const int sigval = SIGSTOP;
61291.1Skamil	const int sigmasked = SIGTRAP;
61301.1Skamil	pid_t child, child2, wpid;
61311.1Skamil#if defined(TWAIT_HAVE_STATUS)
61321.1Skamil	int status;
61331.1Skamil#endif
61341.1Skamil	sigset_t intmask;
61351.1Skamil	ptrace_state_t state;
61361.1Skamil	const int slen = sizeof(state);
61371.1Skamil	ptrace_event_t event;
61381.1Skamil	const int elen = sizeof(event);
61391.1Skamil
61401.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
61411.14Schristos
61421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61441.1Skamil	if (child == 0) {
61451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61471.1Skamil
61481.1Skamil		sigemptyset(&intmask);
61491.1Skamil		sigaddset(&intmask, sigmasked);
61501.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61511.1Skamil
61521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61541.1Skamil
61551.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
61561.1Skamil
61571.1Skamil		if (child2 == 0)
61581.1Skamil			_exit(exitval2);
61591.1Skamil
61601.1Skamil		FORKEE_REQUIRE_SUCCESS
61611.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
61621.1Skamil
61631.1Skamil		forkee_status_exited(status, exitval2);
61641.1Skamil
61651.13Schristos		DPRINTF("Before exiting of the child process\n");
61661.1Skamil		_exit(exitval);
61671.1Skamil	}
61681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61691.1Skamil
61701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61721.1Skamil
61731.1Skamil	validate_status_stopped(status, sigval);
61741.1Skamil
61751.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
61761.1Skamil	event.pe_set_event = PTRACE_VFORK;
61771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
61781.1Skamil
61791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61801.1Skamil	    "without signal to be sent\n");
61811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61821.1Skamil
61831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61851.1Skamil
61861.1Skamil	validate_status_stopped(status, sigmasked);
61871.1Skamil
61881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61891.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61901.1Skamil
61911.1Skamil	child2 = state.pe_other_pid;
61921.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
61931.1Skamil
61941.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
61951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
61961.1Skamil	    child2);
61971.1Skamil
61981.1Skamil	validate_status_stopped(status, SIGTRAP);
61991.1Skamil
62001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
62011.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
62021.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
62031.1Skamil
62041.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
62051.1Skamil	    "without signal to be sent\n");
62061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
62071.1Skamil
62081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62091.1Skamil	    "without signal to be sent\n");
62101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62111.1Skamil
62121.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
62131.1Skamil	    TWAIT_FNAME);
62141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62151.1Skamil	    child2);
62161.1Skamil
62171.1Skamil	validate_status_exited(status, exitval2);
62181.1Skamil
62191.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
62201.1Skamil	    TWAIT_FNAME);
62211.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
62221.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
62231.1Skamil
62241.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62251.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
62261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62271.1Skamil
62281.1Skamil	validate_status_stopped(status, SIGCHLD);
62291.1Skamil
62301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62311.1Skamil	    "without signal to be sent\n");
62321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62331.1Skamil
62341.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62351.1Skamil	    TWAIT_FNAME);
62361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62371.1Skamil
62381.1Skamil	validate_status_exited(status, exitval);
62391.1Skamil
62401.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62411.1Skamil	    TWAIT_FNAME);
62421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62431.1Skamil}
62441.1Skamil#endif
62451.1Skamil
62461.1SkamilATF_TC(signal8);
62471.1SkamilATF_TC_HEAD(signal8, tc)
62481.1Skamil{
62491.1Skamil	atf_tc_set_md_var(tc, "descr",
62501.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62511.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
62521.1Skamil}
62531.1Skamil
62541.1SkamilATF_TC_BODY(signal8, tc)
62551.1Skamil{
62561.1Skamil	const int exitval = 5;
62571.1Skamil	const int exitval2 = 15;
62581.1Skamil	const int sigval = SIGSTOP;
62591.1Skamil	const int sigmasked = SIGTRAP;
62601.1Skamil	pid_t child, child2, wpid;
62611.1Skamil#if defined(TWAIT_HAVE_STATUS)
62621.1Skamil	int status;
62631.1Skamil#endif
62641.1Skamil	sigset_t intmask;
62651.1Skamil	ptrace_state_t state;
62661.1Skamil	const int slen = sizeof(state);
62671.1Skamil	ptrace_event_t event;
62681.1Skamil	const int elen = sizeof(event);
62691.1Skamil
62701.14Schristos	atf_tc_expect_fail("PR kern/51918");
62711.14Schristos
62721.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62731.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62741.1Skamil	if (child == 0) {
62751.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62761.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62771.1Skamil
62781.1Skamil		sigemptyset(&intmask);
62791.1Skamil		sigaddset(&intmask, sigmasked);
62801.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62811.1Skamil
62821.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62831.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62841.1Skamil
62851.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
62861.1Skamil
62871.1Skamil		if (child2 == 0)
62881.1Skamil			_exit(exitval2);
62891.1Skamil
62901.1Skamil		FORKEE_REQUIRE_SUCCESS
62911.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
62921.1Skamil
62931.1Skamil		forkee_status_exited(status, exitval2);
62941.1Skamil
62951.13Schristos		DPRINTF("Before exiting of the child process\n");
62961.1Skamil		_exit(exitval);
62971.1Skamil	}
62981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62991.1Skamil
63001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63021.1Skamil
63031.1Skamil	validate_status_stopped(status, sigval);
63041.1Skamil
63051.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
63061.1Skamil	    child);
63071.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
63081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
63091.1Skamil
63101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63111.1Skamil	    "without signal to be sent\n");
63121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63131.1Skamil
63141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63161.1Skamil
63171.1Skamil	validate_status_stopped(status, sigmasked);
63181.1Skamil
63191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63201.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
63211.1Skamil
63221.1Skamil	child2 = state.pe_other_pid;
63231.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
63241.1Skamil
63251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63261.1Skamil	    "without signal to be sent\n");
63271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63281.1Skamil
63291.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63301.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
63311.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63321.1Skamil
63331.1Skamil	validate_status_stopped(status, SIGCHLD);
63341.1Skamil
63351.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63361.1Skamil	    "without signal to be sent\n");
63371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63381.1Skamil
63391.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63401.1Skamil	    TWAIT_FNAME);
63411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63421.1Skamil
63431.1Skamil	validate_status_exited(status, exitval);
63441.1Skamil
63451.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63461.1Skamil	    TWAIT_FNAME);
63471.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63481.1Skamil}
63491.1Skamil
63501.1SkamilATF_TC(signal9);
63511.1SkamilATF_TC_HEAD(signal9, tc)
63521.1Skamil{
63531.1Skamil	atf_tc_set_md_var(tc, "descr",
63541.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
63551.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
63561.1Skamil}
63571.1Skamil
63581.1SkamilATF_TC_BODY(signal9, tc)
63591.1Skamil{
63601.1Skamil	const int exitval = 5;
63611.1Skamil	const int sigval = SIGSTOP;
63621.1Skamil	const int sigmasked = SIGTRAP;
63631.1Skamil	pid_t child, wpid;
63641.1Skamil#if defined(TWAIT_HAVE_STATUS)
63651.1Skamil	int status;
63661.1Skamil#endif
63671.1Skamil	sigset_t intmask;
63681.1Skamil	ptrace_state_t state;
63691.1Skamil	const int slen = sizeof(state);
63701.1Skamil	ptrace_event_t event;
63711.1Skamil	const int elen = sizeof(event);
63721.1Skamil	ucontext_t uc;
63731.1Skamil	lwpid_t lid;
63741.1Skamil	static const size_t ssize = 16*1024;
63751.1Skamil	void *stack;
63761.1Skamil
63771.14Schristos	atf_tc_expect_fail("PR kern/51918");
63781.14Schristos
63791.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63801.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63811.1Skamil	if (child == 0) {
63821.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63831.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63841.1Skamil
63851.1Skamil		sigemptyset(&intmask);
63861.1Skamil		sigaddset(&intmask, sigmasked);
63871.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
63881.1Skamil
63891.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63901.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63911.1Skamil
63921.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63931.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
63941.1Skamil
63951.13Schristos		DPRINTF("Before making context for new lwp in child\n");
63961.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
63971.1Skamil
63981.13Schristos		DPRINTF("Before creating new in child\n");
63991.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64001.1Skamil
64011.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64021.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64031.1Skamil
64041.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64051.1Skamil		    "are the same\n", lid, the_lwp_id);
64061.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64071.1Skamil
64081.13Schristos		DPRINTF("Before exiting of the child process\n");
64091.1Skamil		_exit(exitval);
64101.1Skamil	}
64111.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64121.1Skamil
64131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64151.1Skamil
64161.1Skamil	validate_status_stopped(status, sigval);
64171.1Skamil
64181.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
64191.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
64201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
64211.1Skamil
64221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64231.1Skamil	    "without signal to be sent\n");
64241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64251.1Skamil
64261.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64271.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64291.1Skamil
64301.1Skamil	validate_status_stopped(status, sigmasked);
64311.1Skamil
64321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
64331.1Skamil
64341.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
64351.1Skamil
64361.1Skamil	lid = state.pe_lwp;
64371.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
64381.1Skamil
64391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64401.1Skamil	    "without signal to be sent\n");
64411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64421.1Skamil
64431.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64441.1Skamil	    TWAIT_FNAME);
64451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64461.1Skamil
64471.1Skamil	validate_status_exited(status, exitval);
64481.1Skamil
64491.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64501.1Skamil	    TWAIT_FNAME);
64511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64521.1Skamil}
64531.1Skamil
64541.1SkamilATF_TC(signal10);
64551.1SkamilATF_TC_HEAD(signal10, tc)
64561.1Skamil{
64571.1Skamil	atf_tc_set_md_var(tc, "descr",
64581.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
64591.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
64601.1Skamil}
64611.1Skamil
64621.1SkamilATF_TC_BODY(signal10, tc)
64631.1Skamil{
64641.1Skamil	const int exitval = 5;
64651.1Skamil	const int sigval = SIGSTOP;
64661.1Skamil	const int sigmasked = SIGTRAP;
64671.1Skamil	pid_t child, wpid;
64681.1Skamil#if defined(TWAIT_HAVE_STATUS)
64691.1Skamil	int status;
64701.1Skamil#endif
64711.1Skamil	sigset_t intmask;
64721.1Skamil	ptrace_state_t state;
64731.1Skamil	const int slen = sizeof(state);
64741.1Skamil	ptrace_event_t event;
64751.1Skamil	const int elen = sizeof(event);
64761.1Skamil	ucontext_t uc;
64771.1Skamil	lwpid_t lid;
64781.1Skamil	static const size_t ssize = 16*1024;
64791.1Skamil	void *stack;
64801.1Skamil
64811.14Schristos	atf_tc_expect_fail("PR kern/51918");
64821.14Schristos
64831.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64841.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64851.1Skamil	if (child == 0) {
64861.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64871.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64881.1Skamil
64891.1Skamil		sigemptyset(&intmask);
64901.1Skamil		sigaddset(&intmask, sigmasked);
64911.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
64921.1Skamil
64931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64951.1Skamil
64961.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64971.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64981.1Skamil
64991.13Schristos		DPRINTF("Before making context for new lwp in child\n");
65001.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
65011.1Skamil
65021.13Schristos		DPRINTF("Before creating new in child\n");
65031.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
65041.1Skamil
65051.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
65061.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
65071.1Skamil
65081.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
65091.1Skamil		    "are the same\n", lid, the_lwp_id);
65101.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
65111.1Skamil
65121.13Schristos		DPRINTF("Before exiting of the child process\n");
65131.1Skamil		_exit(exitval);
65141.1Skamil	}
65151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65161.1Skamil
65171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65191.1Skamil
65201.1Skamil	validate_status_stopped(status, sigval);
65211.1Skamil
65221.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
65231.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
65241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
65251.1Skamil
65261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65271.1Skamil	    "without signal to be sent\n");
65281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65291.1Skamil
65301.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65311.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65331.1Skamil
65341.1Skamil	validate_status_stopped(status, sigmasked);
65351.1Skamil
65361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
65371.1Skamil
65381.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
65391.1Skamil
65401.1Skamil	lid = state.pe_lwp;
65411.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
65421.1Skamil
65431.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65441.1Skamil	    "without signal to be sent\n");
65451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65461.1Skamil
65471.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65481.1Skamil	    TWAIT_FNAME);
65491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65501.1Skamil
65511.1Skamil	validate_status_exited(status, exitval);
65521.1Skamil
65531.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65541.1Skamil	    TWAIT_FNAME);
65551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65561.1Skamil}
65571.1Skamil
65581.1Skamilstatic void
65591.1Skamillwp_main_stop(void *arg)
65601.1Skamil{
65611.1Skamil	the_lwp_id = _lwp_self();
65621.1Skamil
65631.1Skamil	raise(SIGTRAP);
65641.1Skamil
65651.1Skamil	_lwp_exit();
65661.1Skamil}
65671.1Skamil
65681.1SkamilATF_TC(suspend1);
65691.1SkamilATF_TC_HEAD(suspend1, tc)
65701.1Skamil{
65711.1Skamil	atf_tc_set_md_var(tc, "descr",
65721.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
65731.1Skamil	    "resumed by a tracee");
65741.1Skamil}
65751.1Skamil
65761.1SkamilATF_TC_BODY(suspend1, tc)
65771.1Skamil{
65781.1Skamil	const int exitval = 5;
65791.1Skamil	const int sigval = SIGSTOP;
65801.1Skamil	pid_t child, wpid;
65811.1Skamil#if defined(TWAIT_HAVE_STATUS)
65821.1Skamil	int status;
65831.1Skamil#endif
65841.1Skamil	ucontext_t uc;
65851.1Skamil	lwpid_t lid;
65861.1Skamil	static const size_t ssize = 16*1024;
65871.1Skamil	void *stack;
65881.1Skamil	struct ptrace_lwpinfo pl;
65891.1Skamil	struct ptrace_siginfo psi;
65901.1Skamil	volatile int go = 0;
65911.1Skamil
65921.17Skamil	// Feature pending for refactoring
65931.17Skamil	atf_tc_expect_fail("PR kern/51995");
65941.17Skamil
65951.16Skamil	// Hangs with qemu
65961.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
65971.16Skamil
65981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66001.1Skamil	if (child == 0) {
66011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66031.1Skamil
66041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66061.1Skamil
66071.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
66081.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
66091.1Skamil
66101.13Schristos		DPRINTF("Before making context for new lwp in child\n");
66111.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
66121.1Skamil
66131.13Schristos		DPRINTF("Before creating new in child\n");
66141.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
66151.1Skamil
66161.1Skamil		while (go == 0)
66171.1Skamil			continue;
66181.1Skamil
66191.1Skamil		raise(SIGINT);
66201.1Skamil
66211.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
66221.1Skamil
66231.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
66241.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
66251.1Skamil
66261.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
66271.1Skamil		    "are the same\n", lid, the_lwp_id);
66281.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
66291.1Skamil
66301.13Schristos		DPRINTF("Before exiting of the child process\n");
66311.1Skamil		_exit(exitval);
66321.1Skamil	}
66331.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66341.1Skamil
66351.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66361.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66371.1Skamil
66381.1Skamil	validate_status_stopped(status, sigval);
66391.1Skamil
66401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66411.1Skamil	    "without signal to be sent\n");
66421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66431.1Skamil
66441.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66451.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
66461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66471.1Skamil
66481.1Skamil	validate_status_stopped(status, SIGTRAP);
66491.1Skamil
66501.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
66511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
66521.1Skamil
66531.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
66541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
66551.1Skamil
66561.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
66571.1Skamil	    child, getpid());
66581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
66591.1Skamil
66601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66611.1Skamil	    "without signal to be sent\n");
66621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66631.1Skamil
66641.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66651.1Skamil	    "SIGINT\n", TWAIT_FNAME);
66661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66671.1Skamil
66681.1Skamil	validate_status_stopped(status, SIGINT);
66691.1Skamil
66701.1Skamil	pl.pl_lwpid = 0;
66711.1Skamil
66721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66731.1Skamil	while (pl.pl_lwpid != 0) {
66741.1Skamil
66751.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66761.1Skamil		switch (pl.pl_lwpid) {
66771.1Skamil		case 1:
66781.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
66791.1Skamil			break;
66801.1Skamil		case 2:
66811.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
66821.1Skamil			break;
66831.1Skamil		}
66841.1Skamil	}
66851.1Skamil
66861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66871.1Skamil	    "without signal to be sent\n");
66881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66891.1Skamil
66901.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
66911.1Skamil	    TWAIT_FNAME);
66921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66931.1Skamil
66941.1Skamil	validate_status_exited(status, exitval);
66951.1Skamil
66961.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
66971.1Skamil	    TWAIT_FNAME);
66981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66991.1Skamil}
67001.1Skamil
67011.1SkamilATF_TC(suspend2);
67021.1SkamilATF_TC_HEAD(suspend2, tc)
67031.1Skamil{
67041.1Skamil	atf_tc_set_md_var(tc, "descr",
67051.1Skamil	    "Verify that the while the only thread within a process is "
67061.1Skamil	    "suspended, the whole process cannot be unstopped");
67071.1Skamil}
67081.1Skamil
67091.1SkamilATF_TC_BODY(suspend2, tc)
67101.1Skamil{
67111.1Skamil	const int exitval = 5;
67121.1Skamil	const int sigval = SIGSTOP;
67131.1Skamil	pid_t child, wpid;
67141.1Skamil#if defined(TWAIT_HAVE_STATUS)
67151.1Skamil	int status;
67161.1Skamil#endif
67171.1Skamil	struct ptrace_siginfo psi;
67181.1Skamil
67191.17Skamil	// Feature pending for refactoring
67201.17Skamil	atf_tc_expect_fail("PR kern/51995");
67211.17Skamil
67221.16Skamil	// Hangs with qemu
67231.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
67241.16Skamil
67251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67271.1Skamil	if (child == 0) {
67281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67301.1Skamil
67311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67331.1Skamil
67341.13Schristos		DPRINTF("Before exiting of the child process\n");
67351.1Skamil		_exit(exitval);
67361.1Skamil	}
67371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67381.1Skamil
67391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67411.1Skamil
67421.1Skamil	validate_status_stopped(status, sigval);
67431.1Skamil
67441.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
67451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
67461.1Skamil
67471.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
67481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
67491.1Skamil
67501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67511.1Skamil	    "without signal to be sent\n");
67521.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
67531.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
67541.1Skamil
67551.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
67561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
67571.1Skamil
67581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67591.1Skamil	    "without signal to be sent\n");
67601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67611.1Skamil
67621.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
67631.1Skamil	    TWAIT_FNAME);
67641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67651.1Skamil
67661.1Skamil	validate_status_exited(status, exitval);
67671.1Skamil
67681.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
67691.1Skamil	    TWAIT_FNAME);
67701.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67711.1Skamil}
67721.1Skamil
67731.1SkamilATF_TC(resume1);
67741.1SkamilATF_TC_HEAD(resume1, tc)
67751.1Skamil{
67761.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
67771.1Skamil	atf_tc_set_md_var(tc, "descr",
67781.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
67791.1Skamil	    "resumed by the debugger");
67801.1Skamil}
67811.1Skamil
67821.1SkamilATF_TC_BODY(resume1, tc)
67831.1Skamil{
67841.1Skamil	struct msg_fds fds;
67851.1Skamil	const int exitval = 5;
67861.1Skamil	const int sigval = SIGSTOP;
67871.1Skamil	pid_t child, wpid;
67881.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
67891.1Skamil#if defined(TWAIT_HAVE_STATUS)
67901.1Skamil	int status;
67911.1Skamil#endif
67921.1Skamil	ucontext_t uc;
67931.1Skamil	lwpid_t lid;
67941.1Skamil	static const size_t ssize = 16*1024;
67951.1Skamil	void *stack;
67961.1Skamil	struct ptrace_lwpinfo pl;
67971.1Skamil	struct ptrace_siginfo psi;
67981.1Skamil
67991.17Skamil	// Feature pending for refactoring
68001.17Skamil	atf_tc_expect_fail("PR kern/51995");
68011.17Skamil
68021.15Schristos	// Hangs with qemu
68031.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
68041.1Skamil
68051.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
68061.1Skamil
68071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
68081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
68091.1Skamil	if (child == 0) {
68101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68121.1Skamil
68131.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68141.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68151.1Skamil
68161.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
68171.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
68181.1Skamil
68191.13Schristos		DPRINTF("Before making context for new lwp in child\n");
68201.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
68211.1Skamil
68221.13Schristos		DPRINTF("Before creating new in child\n");
68231.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
68241.1Skamil
68251.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
68261.1Skamil
68271.1Skamil		raise(SIGINT);
68281.1Skamil
68291.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
68301.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
68311.1Skamil
68321.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
68331.1Skamil		    "are the same\n", lid, the_lwp_id);
68341.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
68351.1Skamil
68361.13Schristos		DPRINTF("Before exiting of the child process\n");
68371.1Skamil		_exit(exitval);
68381.1Skamil	}
68391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68401.1Skamil
68411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68431.1Skamil
68441.1Skamil	validate_status_stopped(status, sigval);
68451.1Skamil
68461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68471.1Skamil	    "without signal to be sent\n");
68481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68491.1Skamil
68501.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68511.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
68521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68531.1Skamil
68541.1Skamil	validate_status_stopped(status, SIGTRAP);
68551.1Skamil
68561.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
68571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
68581.1Skamil
68591.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
68601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
68611.1Skamil
68621.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
68631.1Skamil
68641.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68651.1Skamil	    "without signal to be sent\n");
68661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68671.1Skamil
68681.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
68691.1Skamil	    "SIGINT\n", TWAIT_FNAME);
68701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68711.1Skamil
68721.1Skamil	validate_status_stopped(status, SIGINT);
68731.1Skamil
68741.1Skamil	pl.pl_lwpid = 0;
68751.1Skamil
68761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68771.1Skamil	while (pl.pl_lwpid != 0) {
68781.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
68791.1Skamil		switch (pl.pl_lwpid) {
68801.1Skamil		case 1:
68811.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
68821.1Skamil			break;
68831.1Skamil		case 2:
68841.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
68851.1Skamil			break;
68861.1Skamil		}
68871.1Skamil	}
68881.1Skamil
68891.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
68901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
68911.1Skamil
68921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68931.1Skamil	    "without signal to be sent\n");
68941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68951.1Skamil
68961.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
68971.1Skamil	    TWAIT_FNAME);
68981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68991.1Skamil
69001.1Skamil	validate_status_exited(status, exitval);
69011.1Skamil
69021.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
69031.1Skamil	    TWAIT_FNAME);
69041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69051.1Skamil
69061.1Skamil	msg_close(&fds);
69071.1Skamil
69081.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
69091.1Skamil	sleep(10);
69101.1Skamil}
69111.1Skamil
69121.1SkamilATF_TC(syscall1);
69131.1SkamilATF_TC_HEAD(syscall1, tc)
69141.1Skamil{
69151.1Skamil	atf_tc_set_md_var(tc, "descr",
69161.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
69171.1Skamil}
69181.1Skamil
69191.1SkamilATF_TC_BODY(syscall1, tc)
69201.1Skamil{
69211.1Skamil	const int exitval = 5;
69221.1Skamil	const int sigval = SIGSTOP;
69231.1Skamil	pid_t child, wpid;
69241.1Skamil#if defined(TWAIT_HAVE_STATUS)
69251.1Skamil	int status;
69261.1Skamil#endif
69271.1Skamil	struct ptrace_siginfo info;
69281.1Skamil	memset(&info, 0, sizeof(info));
69291.1Skamil
69301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69321.1Skamil	if (child == 0) {
69331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69351.1Skamil
69361.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69371.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
69381.1Skamil
69391.1Skamil		syscall(SYS_getpid);
69401.1Skamil
69411.13Schristos		DPRINTF("Before exiting of the child process\n");
69421.1Skamil		_exit(exitval);
69431.1Skamil	}
69441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
69451.1Skamil
69461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69481.1Skamil
69491.1Skamil	validate_status_stopped(status, sigval);
69501.1Skamil
69511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69521.1Skamil	    "without signal to be sent\n");
69531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69541.1Skamil
69551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69571.1Skamil
69581.1Skamil	validate_status_stopped(status, SIGTRAP);
69591.1Skamil
69601.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69621.1Skamil
69631.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69641.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
69651.1Skamil
69661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69671.1Skamil	    "without signal to be sent\n");
69681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
69691.1Skamil
69701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69721.1Skamil
69731.1Skamil	validate_status_stopped(status, SIGTRAP);
69741.1Skamil
69751.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
69761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
69771.1Skamil
69781.13Schristos	DPRINTF("Before checking siginfo_t\n");
69791.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
69801.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
69811.1Skamil
69821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69831.1Skamil	    "without signal to be sent\n");
69841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69851.1Skamil
69861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69881.1Skamil
69891.1Skamil	validate_status_exited(status, exitval);
69901.1Skamil
69911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69931.1Skamil}
69941.1Skamil
69951.1SkamilATF_TC(syscallemu1);
69961.1SkamilATF_TC_HEAD(syscallemu1, tc)
69971.1Skamil{
69981.1Skamil	atf_tc_set_md_var(tc, "descr",
69991.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
70001.1Skamil}
70011.1Skamil
70021.1SkamilATF_TC_BODY(syscallemu1, tc)
70031.1Skamil{
70041.1Skamil	const int exitval = 5;
70051.1Skamil	const int sigval = SIGSTOP;
70061.1Skamil	pid_t child, wpid;
70071.1Skamil#if defined(TWAIT_HAVE_STATUS)
70081.1Skamil	int status;
70091.1Skamil#endif
70101.1Skamil
70111.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
70121.6Skamil	/* syscallemu does not work on sparc (32-bit) */
70131.6Skamil	atf_tc_expect_fail("PR kern/52166");
70141.6Skamil#endif
70151.6Skamil
70161.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
70171.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
70181.1Skamil	if (child == 0) {
70191.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
70201.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
70211.1Skamil
70221.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70231.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70241.1Skamil
70251.1Skamil		syscall(SYS_exit, 100);
70261.1Skamil
70271.13Schristos		DPRINTF("Before exiting of the child process\n");
70281.1Skamil		_exit(exitval);
70291.1Skamil	}
70301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70311.1Skamil
70321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70341.1Skamil
70351.1Skamil	validate_status_stopped(status, sigval);
70361.1Skamil
70371.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70381.1Skamil	    "without signal to be sent\n");
70391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70401.1Skamil
70411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70431.1Skamil
70441.1Skamil	validate_status_stopped(status, SIGTRAP);
70451.1Skamil
70461.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
70471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
70481.1Skamil
70491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70501.1Skamil	    "without signal to be sent\n");
70511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
70521.1Skamil
70531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70551.1Skamil
70561.1Skamil	validate_status_stopped(status, SIGTRAP);
70571.1Skamil
70581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70591.1Skamil	    "without signal to be sent\n");
70601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70611.1Skamil
70621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70641.1Skamil
70651.1Skamil	validate_status_exited(status, exitval);
70661.1Skamil
70671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70691.1Skamil}
70701.1Skamil
70711.1Skamil#include "t_ptrace_amd64_wait.h"
70721.1Skamil#include "t_ptrace_i386_wait.h"
70731.1Skamil#include "t_ptrace_x86_wait.h"
70741.1Skamil
70751.1SkamilATF_TP_ADD_TCS(tp)
70761.1Skamil{
70771.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
70781.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
70791.1Skamil	ATF_TP_ADD_TC(tp, traceme1);
70801.1Skamil	ATF_TP_ADD_TC(tp, traceme2);
70811.1Skamil	ATF_TP_ADD_TC(tp, traceme3);
70821.1Skamil	ATF_TP_ADD_TC(tp, traceme4);
70831.1Skamil
70841.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
70851.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
70861.1Skamil	ATF_TP_ADD_TC(tp, attach3);
70871.1Skamil	ATF_TP_ADD_TC(tp, attach4);
70881.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
70891.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
70901.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
70911.1Skamil
70921.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
70931.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
70941.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
70951.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
70961.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
70971.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
70981.1Skamil
70991.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork1);
71001.1Skamil	ATF_TP_ADD_TC(tp, fork2);
71011.1Skamil
71021.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork1);
71031.1Skamil	ATF_TP_ADD_TC(tp, vfork2);
71041.1Skamil
71051.1Skamil	ATF_TP_ADD_TC(tp, vforkdone1);
71061.1Skamil	ATF_TP_ADD_TC(tp, vforkdone2);
71071.1Skamil
71081.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
71091.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
71101.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
71111.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
71121.1Skamil
71131.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
71141.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
71151.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
71161.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
71171.1Skamil
71181.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
71191.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
71201.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
71211.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
71221.1Skamil
71231.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
71241.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
71251.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
71261.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
71271.1Skamil
71281.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
71291.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
71301.1Skamil
71311.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
71321.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
71331.1Skamil
71341.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
71351.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
71361.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
71371.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
71381.1Skamil
71391.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
71401.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
71411.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
71421.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
71431.1Skamil
71441.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
71451.1Skamil
71461.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
71471.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
71481.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
71491.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
71501.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
71511.1Skamil
71521.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
71531.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
71541.1Skamil
71551.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
71561.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
71571.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
71581.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
71591.1Skamil
71601.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
71611.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
71621.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
71631.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
71641.2Skamil
71651.1Skamil	ATF_TP_ADD_TC(tp, kill1);
71661.1Skamil	ATF_TP_ADD_TC(tp, kill2);
71671.1Skamil
71681.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
71691.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
71701.1Skamil
71711.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
71721.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
71731.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
71741.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
71751.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
71761.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
71771.1Skamil
71781.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
71791.1Skamil
71801.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
71811.1Skamil
71821.1Skamil	ATF_TP_ADD_TC(tp, signal1);
71831.1Skamil	ATF_TP_ADD_TC(tp, signal2);
71841.1Skamil	ATF_TP_ADD_TC(tp, signal3);
71851.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
71861.1Skamil	ATF_TP_ADD_TC(tp, signal5);
71871.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
71881.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
71891.1Skamil	ATF_TP_ADD_TC(tp, signal8);
71901.1Skamil	ATF_TP_ADD_TC(tp, signal9);
71911.1Skamil	ATF_TP_ADD_TC(tp, signal10);
71921.1Skamil
71931.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
71941.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
71951.1Skamil
71961.1Skamil	ATF_TP_ADD_TC(tp, resume1);
71971.1Skamil
71981.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
71991.1Skamil
72001.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
72011.1Skamil
72021.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
72031.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
72041.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
72051.1Skamil
72061.1Skamil	return atf_no_error();
72071.1Skamil}
7208