t_ptrace_wait.c revision 1.14
11.14Schristos/*	$NetBSD: t_ptrace_wait.c,v 1.14 2017/12/16 14:45:25 christos Exp $	*/
21.1Skamil
31.1Skamil/*-
41.1Skamil * Copyright (c) 2016 The NetBSD Foundation, Inc.
51.1Skamil * All rights reserved.
61.1Skamil *
71.1Skamil * Redistribution and use in source and binary forms, with or without
81.1Skamil * modification, are permitted provided that the following conditions
91.1Skamil * are met:
101.1Skamil * 1. Redistributions of source code must retain the above copyright
111.1Skamil *    notice, this list of conditions and the following disclaimer.
121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright
131.1Skamil *    notice, this list of conditions and the following disclaimer in the
141.1Skamil *    documentation and/or other materials provided with the distribution.
151.1Skamil *
161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Skamil * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Skamil * POSSIBILITY OF SUCH DAMAGE.
271.1Skamil */
281.1Skamil
291.1Skamil#include <sys/cdefs.h>
301.14Schristos__RCSID("$NetBSD: t_ptrace_wait.c,v 1.14 2017/12/16 14:45:25 christos Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/types.h>
341.1Skamil#include <sys/ptrace.h>
351.1Skamil#include <sys/resource.h>
361.1Skamil#include <sys/stat.h>
371.1Skamil#include <sys/syscall.h>
381.1Skamil#include <sys/sysctl.h>
391.1Skamil#include <sys/wait.h>
401.1Skamil#include <machine/reg.h>
411.1Skamil#include <elf.h>
421.1Skamil#include <err.h>
431.1Skamil#include <errno.h>
441.1Skamil#include <lwp.h>
451.1Skamil#include <sched.h>
461.1Skamil#include <signal.h>
471.1Skamil#include <stdint.h>
481.1Skamil#include <stdio.h>
491.1Skamil#include <stdlib.h>
501.1Skamil#include <strings.h>
511.1Skamil#include <unistd.h>
521.1Skamil
531.1Skamil#include <atf-c.h>
541.1Skamil
551.1Skamil#include "h_macros.h"
561.1Skamil
571.1Skamil#include "t_ptrace_wait.h"
581.1Skamil#include "msg.h"
591.1Skamil
601.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
611.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
621.1Skamil
631.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
641.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
651.1Skamil
661.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
671.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
681.1Skamil
691.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
701.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
711.13Schristos
721.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
731.13Schristos    strerror(errno))
741.13Schristos
751.13Schristosstatic int debug = 0;
761.13Schristos
771.13Schristos#define DPRINTF(a, ...)	do  \
781.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
791.13Schristos    while (/*CONSTCOND*/0)
801.1Skamil
811.1Skamil
821.1SkamilATF_TC(traceme1);
831.1SkamilATF_TC_HEAD(traceme1, tc)
841.1Skamil{
851.1Skamil	atf_tc_set_md_var(tc, "descr",
861.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
871.1Skamil}
881.1Skamil
891.1SkamilATF_TC_BODY(traceme1, tc)
901.1Skamil{
911.1Skamil	const int exitval = 5;
921.1Skamil	const int sigval = SIGSTOP;
931.1Skamil	pid_t child, wpid;
941.1Skamil#if defined(TWAIT_HAVE_STATUS)
951.1Skamil	int status;
961.1Skamil#endif
971.1Skamil
981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1001.1Skamil	if (child == 0) {
1011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1031.1Skamil
1041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1061.1Skamil
1071.13Schristos		DPRINTF("Before exiting of the child process\n");
1081.1Skamil		_exit(exitval);
1091.1Skamil	}
1101.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1111.1Skamil
1121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1141.1Skamil
1151.1Skamil	validate_status_stopped(status, sigval);
1161.1Skamil
1171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
1181.1Skamil	    "without signal to be sent\n");
1191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1201.1Skamil
1211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1231.1Skamil
1241.1Skamil	validate_status_exited(status, exitval);
1251.1Skamil
1261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1281.1Skamil}
1291.1Skamil
1301.1SkamilATF_TC(traceme2);
1311.1SkamilATF_TC_HEAD(traceme2, tc)
1321.1Skamil{
1331.1Skamil	atf_tc_set_md_var(tc, "descr",
1341.1Skamil	    "Verify SIGSTOP followed by _exit(2) in a child");
1351.1Skamil}
1361.1Skamil
1371.1Skamilstatic int traceme2_caught = 0;
1381.1Skamil
1391.1Skamilstatic void
1401.1Skamiltraceme2_sighandler(int sig)
1411.1Skamil{
1421.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
1431.1Skamil
1441.1Skamil	++traceme2_caught;
1451.1Skamil}
1461.1Skamil
1471.1SkamilATF_TC_BODY(traceme2, tc)
1481.1Skamil{
1491.1Skamil	const int exitval = 5;
1501.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT;
1511.1Skamil	pid_t child, wpid;
1521.1Skamil	struct sigaction sa;
1531.1Skamil#if defined(TWAIT_HAVE_STATUS)
1541.1Skamil	int status;
1551.1Skamil#endif
1561.1Skamil
1571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1591.1Skamil	if (child == 0) {
1601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1621.1Skamil
1631.1Skamil		sa.sa_handler = traceme2_sighandler;
1641.1Skamil		sa.sa_flags = SA_SIGINFO;
1651.1Skamil		sigemptyset(&sa.sa_mask);
1661.1Skamil
1671.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1681.1Skamil
1691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1711.1Skamil
1721.1Skamil		FORKEE_ASSERT_EQ(traceme2_caught, 1);
1731.1Skamil
1741.13Schristos		DPRINTF("Before exiting of the child process\n");
1751.1Skamil		_exit(exitval);
1761.1Skamil	}
1771.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1781.1Skamil
1791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1811.1Skamil
1821.1Skamil	validate_status_stopped(status, sigval);
1831.1Skamil
1841.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
1851.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
1861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1871.1Skamil
1881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1901.1Skamil
1911.1Skamil	validate_status_exited(status, exitval);
1921.1Skamil
1931.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1941.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1951.1Skamil}
1961.1Skamil
1971.1SkamilATF_TC(traceme3);
1981.1SkamilATF_TC_HEAD(traceme3, tc)
1991.1Skamil{
2001.1Skamil	atf_tc_set_md_var(tc, "descr",
2011.1Skamil	    "Verify SIGSTOP followed by termination by a signal in a child");
2021.1Skamil}
2031.1Skamil
2041.1SkamilATF_TC_BODY(traceme3, tc)
2051.1Skamil{
2061.1Skamil	const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
2071.1Skamil	pid_t child, wpid;
2081.1Skamil#if defined(TWAIT_HAVE_STATUS)
2091.1Skamil	int status;
2101.1Skamil#endif
2111.1Skamil
2121.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2131.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2141.1Skamil	if (child == 0) {
2151.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2161.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2171.1Skamil
2181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2201.1Skamil
2211.1Skamil		/* NOTREACHED */
2221.1Skamil		FORKEE_ASSERTX(0 &&
2231.1Skamil		    "Child should be terminated by a signal from its parent");
2241.1Skamil	}
2251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2261.1Skamil
2271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2291.1Skamil
2301.1Skamil	validate_status_stopped(status, sigval);
2311.1Skamil
2321.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2331.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2351.1Skamil
2361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2381.1Skamil
2391.1Skamil	validate_status_signaled(status, sigsent, 0);
2401.1Skamil
2411.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2431.1Skamil}
2441.1Skamil
2451.1SkamilATF_TC(traceme4);
2461.1SkamilATF_TC_HEAD(traceme4, tc)
2471.1Skamil{
2481.1Skamil	atf_tc_set_md_var(tc, "descr",
2491.1Skamil	    "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child");
2501.1Skamil}
2511.1Skamil
2521.1SkamilATF_TC_BODY(traceme4, tc)
2531.1Skamil{
2541.1Skamil	const int exitval = 5;
2551.1Skamil	const int sigval = SIGSTOP, sigsent = SIGCONT;
2561.1Skamil	pid_t child, wpid;
2571.1Skamil#if defined(TWAIT_HAVE_STATUS)
2581.1Skamil	int status;
2591.1Skamil#endif
2601.1Skamil
2611.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2621.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2631.1Skamil	if (child == 0) {
2641.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2651.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2661.1Skamil
2671.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2681.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2691.1Skamil
2701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigsent));
2711.1Skamil		FORKEE_ASSERT(raise(sigsent) == 0);
2721.1Skamil
2731.13Schristos		DPRINTF("Before exiting of the child process\n");
2741.1Skamil		_exit(exitval);
2751.1Skamil	}
2761.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),child);
2771.1Skamil
2781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2801.1Skamil
2811.1Skamil	validate_status_stopped(status, sigval);
2821.1Skamil
2831.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2841.1Skamil	    "without signal to be sent\n");
2851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2861.1Skamil
2871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2891.1Skamil
2901.1Skamil	validate_status_stopped(status, sigsent);
2911.1Skamil
2921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
2931.1Skamil	    "without signal to be sent\n");
2941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2951.1Skamil
2961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2981.1Skamil
2991.1Skamil	validate_status_exited(status, exitval);
3001.1Skamil
3011.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
3021.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3031.1Skamil}
3041.1Skamil
3051.1Skamil#if defined(TWAIT_HAVE_PID)
3061.1SkamilATF_TC(attach1);
3071.1SkamilATF_TC_HEAD(attach1, tc)
3081.1Skamil{
3091.1Skamil	atf_tc_set_md_var(tc, "descr",
3101.1Skamil	    "Assert that tracer sees process termination before the parent");
3111.1Skamil}
3121.1Skamil
3131.1SkamilATF_TC_BODY(attach1, tc)
3141.1Skamil{
3151.1Skamil	struct msg_fds parent_tracee, parent_tracer;
3161.1Skamil	const int exitval_tracee = 5;
3171.1Skamil	const int exitval_tracer = 10;
3181.1Skamil	pid_t tracee, tracer, wpid;
3191.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3201.1Skamil#if defined(TWAIT_HAVE_STATUS)
3211.1Skamil	int status;
3221.1Skamil#endif
3231.1Skamil
3241.13Schristos	DPRINTF("Spawn tracee\n");
3251.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3261.1Skamil	tracee = atf_utils_fork();
3271.1Skamil	if (tracee == 0) {
3281.1Skamil		// Wait for parent to let us exit
3291.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3301.1Skamil		_exit(exitval_tracee);
3311.1Skamil	}
3321.1Skamil
3331.13Schristos	DPRINTF("Spawn debugger\n");
3341.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3351.1Skamil	tracer = atf_utils_fork();
3361.1Skamil	if (tracer == 0) {
3371.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3381.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3391.1Skamil
3401.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3411.1Skamil		FORKEE_REQUIRE_SUCCESS(
3421.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3431.1Skamil
3441.1Skamil		forkee_status_stopped(status, SIGSTOP);
3451.1Skamil
3461.1Skamil		/* Resume tracee with PT_CONTINUE */
3471.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3481.1Skamil
3491.1Skamil		/* Inform parent that tracer has attached to tracee */
3501.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3511.1Skamil
3521.1Skamil		/* Wait for parent to tell use that tracee should have exited */
3531.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3541.1Skamil
3551.1Skamil		/* Wait for tracee and assert that it exited */
3561.1Skamil		FORKEE_REQUIRE_SUCCESS(
3571.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3581.1Skamil
3591.1Skamil		forkee_status_exited(status, exitval_tracee);
3601.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
3611.1Skamil
3621.13Schristos		DPRINTF("Before exiting of the tracer process\n");
3631.1Skamil		_exit(exitval_tracer);
3641.1Skamil	}
3651.1Skamil
3661.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
3671.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3681.1Skamil
3691.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
3701.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3711.1Skamil
3721.13Schristos	DPRINTF("Detect that tracee is zombie\n");
3731.1Skamil	await_zombie(tracee);
3741.1Skamil
3751.1Skamil
3761.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
3771.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
3781.1Skamil	    TWAIT_FNAME);
3791.1Skamil	TWAIT_REQUIRE_SUCCESS(
3801.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
3811.1Skamil
3821.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
3831.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
3841.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3851.1Skamil	    TWAIT_FNAME);
3861.1Skamil
3871.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
3881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3891.1Skamil	    tracer);
3901.1Skamil
3911.1Skamil	validate_status_exited(status, exitval_tracer);
3921.1Skamil
3931.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
3941.1Skamil	    TWAIT_FNAME);
3951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
3961.1Skamil	    tracee);
3971.1Skamil
3981.1Skamil	validate_status_exited(status, exitval_tracee);
3991.1Skamil
4001.1Skamil	msg_close(&parent_tracer);
4011.1Skamil	msg_close(&parent_tracee);
4021.1Skamil}
4031.1Skamil#endif
4041.1Skamil
4051.1Skamil#if defined(TWAIT_HAVE_PID)
4061.1SkamilATF_TC(attach2);
4071.1SkamilATF_TC_HEAD(attach2, tc)
4081.1Skamil{
4091.1Skamil	atf_tc_set_md_var(tc, "descr",
4101.1Skamil	    "Assert that any tracer sees process termination before its "
4111.1Skamil	    "parent");
4121.1Skamil}
4131.1Skamil
4141.1SkamilATF_TC_BODY(attach2, tc)
4151.1Skamil{
4161.1Skamil	struct msg_fds parent_tracer, parent_tracee;
4171.1Skamil	const int exitval_tracee = 5;
4181.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
4191.1Skamil	pid_t tracee, tracer, wpid;
4201.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4211.1Skamil#if defined(TWAIT_HAVE_STATUS)
4221.1Skamil	int status;
4231.1Skamil#endif
4241.1Skamil
4251.13Schristos	DPRINTF("Spawn tracee\n");
4261.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4271.1Skamil	tracee = atf_utils_fork();
4281.1Skamil	if (tracee == 0) {
4291.1Skamil		/* Wait for message from the parent */
4301.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
4311.1Skamil		_exit(exitval_tracee);
4321.1Skamil	}
4331.1Skamil
4341.13Schristos	DPRINTF("Spawn debugger\n");
4351.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4361.1Skamil	tracer = atf_utils_fork();
4371.1Skamil	if (tracer == 0) {
4381.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
4391.1Skamil		tracer = atf_utils_fork();
4401.1Skamil		if (tracer != 0)
4411.1Skamil			_exit(exitval_tracer1);
4421.1Skamil
4431.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4441.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4451.1Skamil
4461.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4471.1Skamil		FORKEE_REQUIRE_SUCCESS(
4481.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4491.1Skamil
4501.1Skamil		forkee_status_stopped(status, SIGSTOP);
4511.1Skamil
4521.1Skamil		/* Resume tracee with PT_CONTINUE */
4531.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4541.1Skamil
4551.1Skamil		/* Inform parent that tracer has attached to tracee */
4561.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
4571.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
4581.1Skamil
4591.1Skamil		/* Wait for tracee and assert that it exited */
4601.1Skamil		FORKEE_REQUIRE_SUCCESS(
4611.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4621.1Skamil
4631.1Skamil		forkee_status_exited(status, exitval_tracee);
4641.1Skamil
4651.13Schristos		DPRINTF("Before exiting of the tracer process\n");
4661.1Skamil		_exit(exitval_tracer2);
4671.1Skamil	}
4681.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
4691.1Skamil	    "%s()\n", TWAIT_FNAME);
4701.1Skamil	TWAIT_REQUIRE_SUCCESS(
4711.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4721.1Skamil
4731.1Skamil	validate_status_exited(status, exitval_tracer1);
4741.1Skamil
4751.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4761.1Skamil	    TWAIT_FNAME);
4771.1Skamil	TWAIT_REQUIRE_SUCCESS(
4781.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4791.1Skamil
4801.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
4811.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
4821.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
4831.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
4841.1Skamil
4851.13Schristos	DPRINTF("Detect that tracee is zombie\n");
4861.1Skamil	await_zombie(tracee);
4871.1Skamil
4881.13Schristos	DPRINTF("Assert that there is no status about tracee - "
4891.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4901.1Skamil	TWAIT_REQUIRE_SUCCESS(
4911.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4921.1Skamil
4931.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
4941.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
4951.1Skamil
4961.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4971.1Skamil	    TWAIT_FNAME);
4981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4991.1Skamil	    tracee);
5001.1Skamil
5011.1Skamil	validate_status_exited(status, exitval_tracee);
5021.1Skamil
5031.1Skamil	msg_close(&parent_tracer);
5041.1Skamil	msg_close(&parent_tracee);
5051.1Skamil
5061.1Skamil}
5071.1Skamil#endif
5081.1Skamil
5091.1SkamilATF_TC(attach3);
5101.1SkamilATF_TC_HEAD(attach3, tc)
5111.1Skamil{
5121.1Skamil	atf_tc_set_md_var(tc, "descr",
5131.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
5141.1Skamil}
5151.1Skamil
5161.1SkamilATF_TC_BODY(attach3, tc)
5171.1Skamil{
5181.1Skamil	struct msg_fds parent_tracee;
5191.1Skamil	const int exitval_tracee = 5;
5201.1Skamil	pid_t tracee, wpid;
5211.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5221.1Skamil#if defined(TWAIT_HAVE_STATUS)
5231.1Skamil	int status;
5241.1Skamil#endif
5251.1Skamil
5261.13Schristos	DPRINTF("Spawn tracee\n");
5271.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5281.1Skamil	tracee = atf_utils_fork();
5291.1Skamil	if (tracee == 0) {
5301.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5311.13Schristos		DPRINTF("Parent should now attach to tracee\n");
5321.1Skamil
5331.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
5341.1Skamil		/* Wait for message from the parent */
5351.1Skamil		_exit(exitval_tracee);
5361.1Skamil	}
5371.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
5381.1Skamil
5391.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
5401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5411.1Skamil
5421.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
5431.1Skamil	    TWAIT_FNAME);
5441.1Skamil	TWAIT_REQUIRE_SUCCESS(
5451.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5461.1Skamil
5471.1Skamil	validate_status_stopped(status, SIGSTOP);
5481.1Skamil
5491.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
5501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5511.1Skamil
5521.13Schristos	DPRINTF("Let the tracee exit now\n");
5531.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
5541.1Skamil
5551.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
5561.1Skamil	TWAIT_REQUIRE_SUCCESS(
5571.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5581.1Skamil
5591.1Skamil	validate_status_exited(status, exitval_tracee);
5601.1Skamil
5611.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
5621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
5631.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
5641.1Skamil
5651.1Skamil	msg_close(&parent_tracee);
5661.1Skamil}
5671.1Skamil
5681.1SkamilATF_TC(attach4);
5691.1SkamilATF_TC_HEAD(attach4, tc)
5701.1Skamil{
5711.1Skamil	atf_tc_set_md_var(tc, "descr",
5721.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
5731.1Skamil}
5741.1Skamil
5751.1SkamilATF_TC_BODY(attach4, tc)
5761.1Skamil{
5771.1Skamil	struct msg_fds parent_tracee;
5781.1Skamil	const int exitval_tracer = 5;
5791.1Skamil	pid_t tracer, wpid;
5801.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5811.1Skamil#if defined(TWAIT_HAVE_STATUS)
5821.1Skamil	int status;
5831.1Skamil#endif
5841.1Skamil
5851.13Schristos	DPRINTF("Spawn tracer\n");
5861.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5871.1Skamil	tracer = atf_utils_fork();
5881.1Skamil	if (tracer == 0) {
5891.1Skamil
5901.1Skamil		/* Wait for message from the parent */
5911.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5921.1Skamil
5931.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
5941.1Skamil		    getppid());
5951.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
5961.1Skamil
5971.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
5981.1Skamil		    TWAIT_FNAME);
5991.1Skamil		FORKEE_REQUIRE_SUCCESS(
6001.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
6011.1Skamil
6021.1Skamil		forkee_status_stopped(status, SIGSTOP);
6031.1Skamil
6041.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
6051.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
6061.1Skamil		    != -1);
6071.1Skamil
6081.1Skamil		/* Tell parent we are ready */
6091.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
6101.1Skamil
6111.1Skamil		_exit(exitval_tracer);
6121.1Skamil	}
6131.1Skamil
6141.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
6151.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6161.13Schristos	DPRINTF("Allow the tracer to exit now\n");
6171.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
6181.1Skamil
6191.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
6201.1Skamil	TWAIT_REQUIRE_SUCCESS(
6211.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6221.1Skamil
6231.1Skamil	validate_status_exited(status, exitval_tracer);
6241.1Skamil
6251.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
6261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
6271.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
6281.1Skamil
6291.1Skamil	msg_close(&parent_tracee);
6301.1Skamil}
6311.1Skamil
6321.1Skamil#if defined(TWAIT_HAVE_PID)
6331.1SkamilATF_TC(attach5);
6341.1SkamilATF_TC_HEAD(attach5, tc)
6351.1Skamil{
6361.1Skamil	atf_tc_set_md_var(tc, "descr",
6371.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
6381.1Skamil	    "(check getppid(2))");
6391.1Skamil}
6401.1Skamil
6411.1SkamilATF_TC_BODY(attach5, tc)
6421.1Skamil{
6431.1Skamil	struct msg_fds parent_tracer, parent_tracee;
6441.1Skamil	const int exitval_tracee = 5;
6451.1Skamil	const int exitval_tracer = 10;
6461.1Skamil	pid_t parent, tracee, tracer, wpid;
6471.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6481.1Skamil#if defined(TWAIT_HAVE_STATUS)
6491.1Skamil	int status;
6501.1Skamil#endif
6511.1Skamil
6521.13Schristos	DPRINTF("Spawn tracee\n");
6531.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6541.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6551.1Skamil	tracee = atf_utils_fork();
6561.1Skamil	if (tracee == 0) {
6571.1Skamil		parent = getppid();
6581.1Skamil
6591.1Skamil		/* Emit message to the parent */
6601.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
6611.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
6621.1Skamil
6631.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
6641.1Skamil
6651.1Skamil		_exit(exitval_tracee);
6661.1Skamil	}
6671.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
6681.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
6691.1Skamil
6701.13Schristos	DPRINTF("Spawn debugger\n");
6711.1Skamil	tracer = atf_utils_fork();
6721.1Skamil	if (tracer == 0) {
6731.1Skamil		/* No IPC to communicate with the child */
6741.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6751.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6761.1Skamil
6771.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6781.1Skamil		FORKEE_REQUIRE_SUCCESS(
6791.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6801.1Skamil
6811.1Skamil		forkee_status_stopped(status, SIGSTOP);
6821.1Skamil
6831.1Skamil		/* Resume tracee with PT_CONTINUE */
6841.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6851.1Skamil
6861.1Skamil		/* Inform parent that tracer has attached to tracee */
6871.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
6881.1Skamil
6891.1Skamil		/* Wait for parent to tell use that tracee should have exited */
6901.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
6911.1Skamil
6921.1Skamil		/* Wait for tracee and assert that it exited */
6931.1Skamil		FORKEE_REQUIRE_SUCCESS(
6941.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6951.1Skamil
6961.1Skamil		forkee_status_exited(status, exitval_tracee);
6971.1Skamil
6981.13Schristos		DPRINTF("Before exiting of the tracer process\n");
6991.1Skamil		_exit(exitval_tracer);
7001.1Skamil	}
7011.1Skamil
7021.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
7031.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
7041.1Skamil
7051.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
7061.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
7071.1Skamil
7081.13Schristos	DPRINTF("Detect that tracee is zombie\n");
7091.1Skamil	await_zombie(tracee);
7101.1Skamil
7111.13Schristos	DPRINTF("Assert that there is no status about tracee - "
7121.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
7131.1Skamil	TWAIT_REQUIRE_SUCCESS(
7141.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
7151.1Skamil
7161.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
7171.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
7181.1Skamil
7191.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
7201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
7211.1Skamil	    tracer);
7221.1Skamil
7231.1Skamil	validate_status_exited(status, exitval_tracer);
7241.1Skamil
7251.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
7261.1Skamil	    TWAIT_FNAME);
7271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
7281.1Skamil	    tracee);
7291.1Skamil
7301.1Skamil	validate_status_exited(status, exitval_tracee);
7311.1Skamil
7321.1Skamil	msg_close(&parent_tracer);
7331.1Skamil	msg_close(&parent_tracee);
7341.1Skamil}
7351.1Skamil#endif
7361.1Skamil
7371.1Skamil#if defined(TWAIT_HAVE_PID)
7381.1SkamilATF_TC(attach6);
7391.1SkamilATF_TC_HEAD(attach6, tc)
7401.1Skamil{
7411.1Skamil	atf_tc_set_md_var(tc, "descr",
7421.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
7431.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
7441.1Skamil}
7451.1Skamil
7461.1SkamilATF_TC_BODY(attach6, tc)
7471.1Skamil{
7481.1Skamil	struct msg_fds parent_tracee, parent_tracer;
7491.1Skamil	const int exitval_tracee = 5;
7501.1Skamil	const int exitval_tracer = 10;
7511.1Skamil	pid_t parent, tracee, tracer, wpid;
7521.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7531.1Skamil#if defined(TWAIT_HAVE_STATUS)
7541.1Skamil	int status;
7551.1Skamil#endif
7561.1Skamil	int name[CTL_MAXNAME];
7571.1Skamil	struct kinfo_proc2 kp;
7581.1Skamil	size_t len = sizeof(kp);
7591.1Skamil	unsigned int namelen;
7601.1Skamil
7611.13Schristos	DPRINTF("Spawn tracee\n");
7621.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7631.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
7641.1Skamil	tracee = atf_utils_fork();
7651.1Skamil	if (tracee == 0) {
7661.1Skamil		parent = getppid();
7671.1Skamil
7681.1Skamil		/* Emit message to the parent */
7691.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7701.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
7711.1Skamil
7721.1Skamil		namelen = 0;
7731.1Skamil		name[namelen++] = CTL_KERN;
7741.1Skamil		name[namelen++] = KERN_PROC2;
7751.1Skamil		name[namelen++] = KERN_PROC_PID;
7761.1Skamil		name[namelen++] = getpid();
7771.1Skamil		name[namelen++] = len;
7781.1Skamil		name[namelen++] = 1;
7791.1Skamil
7801.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
7811.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
7821.1Skamil
7831.1Skamil		_exit(exitval_tracee);
7841.1Skamil	}
7851.1Skamil
7861.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
7871.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
7881.1Skamil
7891.13Schristos	DPRINTF("Spawn debugger\n");
7901.1Skamil	tracer = atf_utils_fork();
7911.1Skamil	if (tracer == 0) {
7921.1Skamil		/* No IPC to communicate with the child */
7931.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
7941.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7951.1Skamil
7961.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
7971.1Skamil		FORKEE_REQUIRE_SUCCESS(
7981.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7991.1Skamil
8001.1Skamil		forkee_status_stopped(status, SIGSTOP);
8011.1Skamil
8021.1Skamil		/* Resume tracee with PT_CONTINUE */
8031.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8041.1Skamil
8051.1Skamil		/* Inform parent that tracer has attached to tracee */
8061.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
8071.1Skamil
8081.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
8091.1Skamil
8101.1Skamil		/* Wait for tracee and assert that it exited */
8111.1Skamil		FORKEE_REQUIRE_SUCCESS(
8121.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8131.1Skamil
8141.1Skamil		forkee_status_exited(status, exitval_tracee);
8151.1Skamil
8161.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8171.1Skamil		_exit(exitval_tracer);
8181.1Skamil	}
8191.1Skamil
8201.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8211.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
8221.1Skamil
8231.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8241.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
8251.1Skamil
8261.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8271.1Skamil	await_zombie(tracee);
8281.1Skamil
8291.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8301.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8311.1Skamil	TWAIT_REQUIRE_SUCCESS(
8321.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8331.1Skamil
8341.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
8351.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
8361.1Skamil
8371.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
8381.1Skamil	    TWAIT_FNAME);
8391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8401.1Skamil	    tracer);
8411.1Skamil
8421.1Skamil	validate_status_exited(status, exitval_tracer);
8431.1Skamil
8441.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8451.1Skamil	    TWAIT_FNAME);
8461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8471.1Skamil	    tracee);
8481.1Skamil
8491.1Skamil	validate_status_exited(status, exitval_tracee);
8501.1Skamil
8511.1Skamil	msg_close(&parent_tracee);
8521.1Skamil	msg_close(&parent_tracer);
8531.1Skamil}
8541.1Skamil#endif
8551.1Skamil
8561.1Skamil#if defined(TWAIT_HAVE_PID)
8571.1SkamilATF_TC(attach7);
8581.1SkamilATF_TC_HEAD(attach7, tc)
8591.1Skamil{
8601.1Skamil	atf_tc_set_md_var(tc, "descr",
8611.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8621.1Skamil	    "(check /proc/curproc/status 3rd column)");
8631.1Skamil}
8641.1Skamil
8651.1SkamilATF_TC_BODY(attach7, tc)
8661.1Skamil{
8671.1Skamil	struct msg_fds parent_tracee, parent_tracer;
8681.1Skamil	int rv;
8691.1Skamil	const int exitval_tracee = 5;
8701.1Skamil	const int exitval_tracer = 10;
8711.1Skamil	pid_t parent, tracee, tracer, wpid;
8721.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8731.1Skamil#if defined(TWAIT_HAVE_STATUS)
8741.1Skamil	int status;
8751.1Skamil#endif
8761.1Skamil	FILE *fp;
8771.1Skamil	struct stat st;
8781.1Skamil	const char *fname = "/proc/curproc/status";
8791.1Skamil	char s_executable[MAXPATHLEN];
8801.1Skamil	int s_pid, s_ppid;
8811.1Skamil	/*
8821.1Skamil	 * Format:
8831.1Skamil	 *  EXECUTABLE PID PPID ...
8841.1Skamil	 */
8851.1Skamil
8861.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
8871.1Skamil	if (rv != 0) {
8881.1Skamil		atf_tc_skip("/proc/curproc/status not found");
8891.1Skamil	}
8901.1Skamil
8911.13Schristos	DPRINTF("Spawn tracee\n");
8921.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8931.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8941.1Skamil	tracee = atf_utils_fork();
8951.1Skamil	if (tracee == 0) {
8961.1Skamil		parent = getppid();
8971.1Skamil
8981.1Skamil		// Wait for parent to let us exit
8991.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
9001.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
9011.1Skamil
9021.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
9031.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
9041.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
9051.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
9061.1Skamil
9071.1Skamil		_exit(exitval_tracee);
9081.1Skamil	}
9091.1Skamil
9101.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9111.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
9121.1Skamil
9131.13Schristos	DPRINTF("Spawn debugger\n");
9141.1Skamil	tracer = atf_utils_fork();
9151.1Skamil	if (tracer == 0) {
9161.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9171.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9181.1Skamil
9191.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9201.1Skamil		FORKEE_REQUIRE_SUCCESS(
9211.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9221.1Skamil
9231.1Skamil		forkee_status_stopped(status, SIGSTOP);
9241.1Skamil
9251.1Skamil		/* Resume tracee with PT_CONTINUE */
9261.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9271.1Skamil
9281.1Skamil		/* Inform parent that tracer has attached to tracee */
9291.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
9301.1Skamil
9311.1Skamil		/* Wait for parent to tell use that tracee should have exited */
9321.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
9331.1Skamil
9341.1Skamil		/* Wait for tracee and assert that it exited */
9351.1Skamil		FORKEE_REQUIRE_SUCCESS(
9361.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9371.1Skamil
9381.1Skamil		forkee_status_exited(status, exitval_tracee);
9391.1Skamil
9401.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9411.1Skamil		_exit(exitval_tracer);
9421.1Skamil	}
9431.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9441.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
9451.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9461.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
9471.1Skamil
9481.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9491.1Skamil	await_zombie(tracee);
9501.1Skamil
9511.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9521.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9531.1Skamil	TWAIT_REQUIRE_SUCCESS(
9541.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9551.1Skamil
9561.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9571.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
9581.1Skamil
9591.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
9601.1Skamil	    TWAIT_FNAME);
9611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
9621.1Skamil	    tracer);
9631.1Skamil
9641.1Skamil	validate_status_exited(status, exitval_tracer);
9651.1Skamil
9661.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
9671.1Skamil	    TWAIT_FNAME);
9681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
9691.1Skamil	    tracee);
9701.1Skamil
9711.1Skamil	validate_status_exited(status, exitval_tracee);
9721.1Skamil
9731.1Skamil	msg_close(&parent_tracee);
9741.1Skamil	msg_close(&parent_tracer);
9751.1Skamil}
9761.1Skamil#endif
9771.1Skamil
9781.1SkamilATF_TC(eventmask1);
9791.1SkamilATF_TC_HEAD(eventmask1, tc)
9801.1Skamil{
9811.1Skamil	atf_tc_set_md_var(tc, "descr",
9821.1Skamil	    "Verify that empty EVENT_MASK is preserved");
9831.1Skamil}
9841.1Skamil
9851.1SkamilATF_TC_BODY(eventmask1, tc)
9861.1Skamil{
9871.1Skamil	const int exitval = 5;
9881.1Skamil	const int sigval = SIGSTOP;
9891.1Skamil	pid_t child, wpid;
9901.1Skamil#if defined(TWAIT_HAVE_STATUS)
9911.1Skamil	int status;
9921.1Skamil#endif
9931.1Skamil	ptrace_event_t set_event, get_event;
9941.1Skamil	const int len = sizeof(ptrace_event_t);
9951.1Skamil
9961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
9971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
9981.1Skamil	if (child == 0) {
9991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10011.1Skamil
10021.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10031.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10041.1Skamil
10051.13Schristos		DPRINTF("Before exiting of the child process\n");
10061.1Skamil		_exit(exitval);
10071.1Skamil	}
10081.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10091.1Skamil
10101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10121.1Skamil
10131.1Skamil	validate_status_stopped(status, sigval);
10141.1Skamil
10151.1Skamil	set_event.pe_set_event = 0;
10161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10181.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10191.1Skamil
10201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10211.1Skamil	    "without signal to be sent\n");
10221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10231.1Skamil
10241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10261.1Skamil
10271.1Skamil	validate_status_exited(status, exitval);
10281.1Skamil
10291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10311.1Skamil}
10321.1Skamil
10331.1SkamilATF_TC(eventmask2);
10341.1SkamilATF_TC_HEAD(eventmask2, tc)
10351.1Skamil{
10361.1Skamil	atf_tc_set_md_var(tc, "descr",
10371.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
10381.1Skamil}
10391.1Skamil
10401.1SkamilATF_TC_BODY(eventmask2, tc)
10411.1Skamil{
10421.1Skamil	const int exitval = 5;
10431.1Skamil	const int sigval = SIGSTOP;
10441.1Skamil	pid_t child, wpid;
10451.1Skamil#if defined(TWAIT_HAVE_STATUS)
10461.1Skamil	int status;
10471.1Skamil#endif
10481.1Skamil	ptrace_event_t set_event, get_event;
10491.1Skamil	const int len = sizeof(ptrace_event_t);
10501.1Skamil
10511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
10521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
10531.1Skamil	if (child == 0) {
10541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
10551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
10561.1Skamil
10571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
10581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
10591.1Skamil
10601.13Schristos		DPRINTF("Before exiting of the child process\n");
10611.1Skamil		_exit(exitval);
10621.1Skamil	}
10631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
10641.1Skamil
10651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10671.1Skamil
10681.1Skamil	validate_status_stopped(status, sigval);
10691.1Skamil
10701.1Skamil	set_event.pe_set_event = PTRACE_FORK;
10711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
10721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
10731.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
10741.1Skamil
10751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
10761.1Skamil	    "without signal to be sent\n");
10771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
10781.1Skamil
10791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
10811.1Skamil
10821.1Skamil	validate_status_exited(status, exitval);
10831.1Skamil
10841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
10851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
10861.1Skamil}
10871.1Skamil
10881.1SkamilATF_TC(eventmask3);
10891.1SkamilATF_TC_HEAD(eventmask3, tc)
10901.1Skamil{
10911.1Skamil	atf_tc_set_md_var(tc, "descr",
10921.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
10931.1Skamil}
10941.1Skamil
10951.1SkamilATF_TC_BODY(eventmask3, tc)
10961.1Skamil{
10971.1Skamil	const int exitval = 5;
10981.1Skamil	const int sigval = SIGSTOP;
10991.1Skamil	pid_t child, wpid;
11001.1Skamil#if defined(TWAIT_HAVE_STATUS)
11011.1Skamil	int status;
11021.1Skamil#endif
11031.1Skamil	ptrace_event_t set_event, get_event;
11041.1Skamil	const int len = sizeof(ptrace_event_t);
11051.1Skamil
11061.14Schristos	atf_tc_expect_fail("PR kern/51630");
11071.14Schristos
11081.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11091.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11101.1Skamil	if (child == 0) {
11111.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11121.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11131.1Skamil
11141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11161.1Skamil
11171.13Schristos		DPRINTF("Before exiting of the child process\n");
11181.1Skamil		_exit(exitval);
11191.1Skamil	}
11201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11211.1Skamil
11221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11241.1Skamil
11251.1Skamil	validate_status_stopped(status, sigval);
11261.1Skamil
11271.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
11281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1 || errno == ENOTSUP);
11291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11301.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11311.1Skamil
11321.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11331.1Skamil	    "without signal to be sent\n");
11341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11351.1Skamil
11361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11381.1Skamil
11391.1Skamil	validate_status_exited(status, exitval);
11401.1Skamil
11411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11421.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11431.1Skamil}
11441.1Skamil
11451.1SkamilATF_TC(eventmask4);
11461.1SkamilATF_TC_HEAD(eventmask4, tc)
11471.1Skamil{
11481.1Skamil	atf_tc_set_md_var(tc, "descr",
11491.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
11501.1Skamil}
11511.1Skamil
11521.1SkamilATF_TC_BODY(eventmask4, tc)
11531.1Skamil{
11541.1Skamil	const int exitval = 5;
11551.1Skamil	const int sigval = SIGSTOP;
11561.1Skamil	pid_t child, wpid;
11571.1Skamil#if defined(TWAIT_HAVE_STATUS)
11581.1Skamil	int status;
11591.1Skamil#endif
11601.1Skamil	ptrace_event_t set_event, get_event;
11611.1Skamil	const int len = sizeof(ptrace_event_t);
11621.1Skamil
11631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11651.1Skamil	if (child == 0) {
11661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11681.1Skamil
11691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11711.1Skamil
11721.13Schristos		DPRINTF("Before exiting of the child process\n");
11731.1Skamil		_exit(exitval);
11741.1Skamil	}
11751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11761.1Skamil
11771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11791.1Skamil
11801.1Skamil	validate_status_stopped(status, sigval);
11811.1Skamil
11821.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
11831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11851.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11861.1Skamil
11871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11881.1Skamil	    "without signal to be sent\n");
11891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11901.1Skamil
11911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11931.1Skamil
11941.1Skamil	validate_status_exited(status, exitval);
11951.1Skamil
11961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11981.1Skamil}
11991.1Skamil
12001.1SkamilATF_TC(eventmask5);
12011.1SkamilATF_TC_HEAD(eventmask5, tc)
12021.1Skamil{
12031.1Skamil	atf_tc_set_md_var(tc, "descr",
12041.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
12051.1Skamil}
12061.1Skamil
12071.1SkamilATF_TC_BODY(eventmask5, tc)
12081.1Skamil{
12091.1Skamil	const int exitval = 5;
12101.1Skamil	const int sigval = SIGSTOP;
12111.1Skamil	pid_t child, wpid;
12121.1Skamil#if defined(TWAIT_HAVE_STATUS)
12131.1Skamil	int status;
12141.1Skamil#endif
12151.1Skamil	ptrace_event_t set_event, get_event;
12161.1Skamil	const int len = sizeof(ptrace_event_t);
12171.1Skamil
12181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12201.1Skamil	if (child == 0) {
12211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12231.1Skamil
12241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12261.1Skamil
12271.13Schristos		DPRINTF("Before exiting of the child process\n");
12281.1Skamil		_exit(exitval);
12291.1Skamil	}
12301.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12311.1Skamil
12321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12341.1Skamil
12351.1Skamil	validate_status_stopped(status, sigval);
12361.1Skamil
12371.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
12381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12401.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12411.1Skamil
12421.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12431.1Skamil	    "without signal to be sent\n");
12441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12451.1Skamil
12461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12481.1Skamil
12491.1Skamil	validate_status_exited(status, exitval);
12501.1Skamil
12511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12521.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12531.1Skamil}
12541.1Skamil
12551.1SkamilATF_TC(eventmask6);
12561.1SkamilATF_TC_HEAD(eventmask6, tc)
12571.1Skamil{
12581.1Skamil	atf_tc_set_md_var(tc, "descr",
12591.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
12601.1Skamil}
12611.1Skamil
12621.1SkamilATF_TC_BODY(eventmask6, tc)
12631.1Skamil{
12641.1Skamil	const int exitval = 5;
12651.1Skamil	const int sigval = SIGSTOP;
12661.1Skamil	pid_t child, wpid;
12671.1Skamil#if defined(TWAIT_HAVE_STATUS)
12681.1Skamil	int status;
12691.1Skamil#endif
12701.1Skamil	ptrace_event_t set_event, get_event;
12711.1Skamil	const int len = sizeof(ptrace_event_t);
12721.1Skamil
12731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12751.1Skamil	if (child == 0) {
12761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12781.1Skamil
12791.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12801.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12811.1Skamil
12821.13Schristos		DPRINTF("Before exiting of the child process\n");
12831.1Skamil		_exit(exitval);
12841.1Skamil	}
12851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12861.1Skamil
12871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12891.1Skamil
12901.1Skamil	validate_status_stopped(status, sigval);
12911.1Skamil
12921.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
12931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12951.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12961.1Skamil
12971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12981.1Skamil	    "without signal to be sent\n");
12991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13001.1Skamil
13011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13031.1Skamil
13041.1Skamil	validate_status_exited(status, exitval);
13051.1Skamil
13061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13081.1Skamil}
13091.1Skamil
13101.1Skamil#if defined(TWAIT_HAVE_PID)
13111.1SkamilATF_TC(fork1);
13121.1SkamilATF_TC_HEAD(fork1, tc)
13131.1Skamil{
13141.1Skamil	atf_tc_set_md_var(tc, "descr",
13151.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
13161.1Skamil	    "set to PTRACE_FORK");
13171.1Skamil}
13181.1Skamil
13191.1SkamilATF_TC_BODY(fork1, tc)
13201.1Skamil{
13211.1Skamil	const int exitval = 5;
13221.1Skamil	const int exitval2 = 15;
13231.1Skamil	const int sigval = SIGSTOP;
13241.1Skamil	pid_t child, child2, wpid;
13251.1Skamil#if defined(TWAIT_HAVE_STATUS)
13261.1Skamil	int status;
13271.1Skamil#endif
13281.1Skamil	ptrace_state_t state;
13291.1Skamil	const int slen = sizeof(state);
13301.1Skamil	ptrace_event_t event;
13311.1Skamil	const int elen = sizeof(event);
13321.1Skamil
13331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13351.1Skamil	if (child == 0) {
13361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13381.1Skamil
13391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13411.1Skamil
13421.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
13431.1Skamil
13441.1Skamil		if (child2 == 0)
13451.1Skamil			_exit(exitval2);
13461.1Skamil
13471.1Skamil		FORKEE_REQUIRE_SUCCESS
13481.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
13491.1Skamil
13501.1Skamil		forkee_status_exited(status, exitval2);
13511.1Skamil
13521.13Schristos		DPRINTF("Before exiting of the child process\n");
13531.1Skamil		_exit(exitval);
13541.1Skamil	}
13551.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13561.1Skamil
13571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13591.1Skamil
13601.1Skamil	validate_status_stopped(status, sigval);
13611.1Skamil
13621.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
13631.1Skamil	event.pe_set_event = PTRACE_FORK;
13641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
13651.1Skamil
13661.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13671.1Skamil	    "without signal to be sent\n");
13681.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
13691.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
13701.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
13711.1Skamil                "state.pe_other_pid=child)\n", child);
13721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13731.1Skamil
13741.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
13751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13761.1Skamil
13771.1Skamil	validate_status_stopped(status, SIGTRAP);
13781.1Skamil
13791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
13801.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
13811.1Skamil
13821.1Skamil	child2 = state.pe_other_pid;
13831.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
13841.1Skamil
13851.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
13861.1Skamil	    TWAIT_FNAME, child2, child);
13871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
13881.1Skamil	    child2);
13891.1Skamil
13901.1Skamil	validate_status_stopped(status, SIGTRAP);
13911.1Skamil
13921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
13931.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
13941.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
13951.1Skamil
13961.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
13971.1Skamil	    "without signal to be sent\n");
13981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
13991.1Skamil
14001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14011.1Skamil	    "without signal to be sent\n");
14021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14031.1Skamil
14041.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
14051.1Skamil	    TWAIT_FNAME);
14061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
14071.1Skamil	    child2);
14081.1Skamil
14091.1Skamil	validate_status_exited(status, exitval2);
14101.1Skamil
14111.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
14121.1Skamil	    TWAIT_FNAME);
14131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
14141.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
14151.1Skamil
14161.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14171.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14191.1Skamil
14201.1Skamil	validate_status_stopped(status, SIGCHLD);
14211.1Skamil
14221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14231.1Skamil	    "without signal to be sent\n");
14241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14251.1Skamil
14261.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
14271.1Skamil	    TWAIT_FNAME);
14281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14291.1Skamil
14301.1Skamil	validate_status_exited(status, exitval);
14311.1Skamil
14321.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
14331.1Skamil	    TWAIT_FNAME);
14341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14351.1Skamil}
14361.1Skamil#endif
14371.1Skamil
14381.1SkamilATF_TC(fork2);
14391.1SkamilATF_TC_HEAD(fork2, tc)
14401.1Skamil{
14411.1Skamil	atf_tc_set_md_var(tc, "descr",
14421.1Skamil	    "Verify that fork(2) is not intercepted by ptrace(2) with empty "
14431.1Skamil	    "EVENT_MASK");
14441.1Skamil}
14451.1Skamil
14461.1SkamilATF_TC_BODY(fork2, tc)
14471.1Skamil{
14481.1Skamil	const int exitval = 5;
14491.1Skamil	const int exitval2 = 15;
14501.1Skamil	const int sigval = SIGSTOP;
14511.1Skamil	pid_t child, child2, wpid;
14521.1Skamil#if defined(TWAIT_HAVE_STATUS)
14531.1Skamil	int status;
14541.1Skamil#endif
14551.1Skamil	ptrace_event_t event;
14561.1Skamil	const int elen = sizeof(event);
14571.1Skamil
14581.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14591.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14601.1Skamil	if (child == 0) {
14611.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14621.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14631.1Skamil
14641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14661.1Skamil
14671.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
14681.1Skamil
14691.1Skamil		if (child2 == 0)
14701.1Skamil			_exit(exitval2);
14711.1Skamil
14721.1Skamil		FORKEE_REQUIRE_SUCCESS
14731.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
14741.1Skamil
14751.1Skamil		forkee_status_exited(status, exitval2);
14761.1Skamil
14771.13Schristos		DPRINTF("Before exiting of the child process\n");
14781.1Skamil		_exit(exitval);
14791.1Skamil	}
14801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14811.1Skamil
14821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14841.1Skamil
14851.1Skamil	validate_status_stopped(status, sigval);
14861.1Skamil
14871.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
14881.1Skamil	event.pe_set_event = 0;
14891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
14901.1Skamil
14911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14921.1Skamil	    "without signal to be sent\n");
14931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14941.1Skamil
14951.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
14961.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
14971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14981.1Skamil
14991.1Skamil	validate_status_stopped(status, SIGCHLD);
15001.1Skamil
15011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15021.1Skamil	    "without signal to be sent\n");
15031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15041.1Skamil
15051.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
15061.1Skamil	    TWAIT_FNAME);
15071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15081.1Skamil
15091.1Skamil	validate_status_exited(status, exitval);
15101.1Skamil
15111.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
15121.1Skamil	    TWAIT_FNAME);
15131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
15141.1Skamil}
15151.1Skamil
15161.1Skamil#if defined(TWAIT_HAVE_PID)
15171.1SkamilATF_TC(vfork1);
15181.1SkamilATF_TC_HEAD(vfork1, tc)
15191.1Skamil{
15201.1Skamil	atf_tc_set_md_var(tc, "descr",
15211.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
15221.1Skamil	    "set to PTRACE_VFORK");
15231.1Skamil}
15241.1Skamil
15251.1SkamilATF_TC_BODY(vfork1, tc)
15261.1Skamil{
15271.1Skamil	const int exitval = 5;
15281.1Skamil	const int exitval2 = 15;
15291.1Skamil	const int sigval = SIGSTOP;
15301.1Skamil	pid_t child, child2, wpid;
15311.1Skamil#if defined(TWAIT_HAVE_STATUS)
15321.1Skamil	int status;
15331.1Skamil#endif
15341.1Skamil	ptrace_state_t state;
15351.1Skamil	const int slen = sizeof(state);
15361.1Skamil	ptrace_event_t event;
15371.1Skamil	const int elen = sizeof(event);
15381.1Skamil
15391.1Skamil	atf_tc_expect_fail("PR kern/51630");
15401.1Skamil
15411.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
15421.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
15431.1Skamil	if (child == 0) {
15441.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
15451.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
15461.1Skamil
15471.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
15481.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
15491.1Skamil
15501.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
15511.1Skamil
15521.1Skamil		if (child2 == 0)
15531.1Skamil			_exit(exitval2);
15541.1Skamil
15551.1Skamil		FORKEE_REQUIRE_SUCCESS
15561.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
15571.1Skamil
15581.1Skamil		forkee_status_exited(status, exitval2);
15591.1Skamil
15601.13Schristos		DPRINTF("Before exiting of the child process\n");
15611.1Skamil		_exit(exitval);
15621.1Skamil	}
15631.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15641.1Skamil
15651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15671.1Skamil
15681.1Skamil	validate_status_stopped(status, sigval);
15691.1Skamil
15701.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
15711.1Skamil	event.pe_set_event = PTRACE_VFORK;
15721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
15731.1Skamil
15741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15751.1Skamil	    "without signal to be sent\n");
15761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15771.1Skamil
15781.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
15791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15801.1Skamil
15811.1Skamil	validate_status_stopped(status, SIGTRAP);
15821.1Skamil
15831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
15841.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
15851.1Skamil
15861.1Skamil	child2 = state.pe_other_pid;
15871.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
15881.1Skamil
15891.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
15901.1Skamil	    TWAIT_FNAME, child2, child);
15911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
15921.1Skamil	    child2);
15931.1Skamil
15941.1Skamil	validate_status_stopped(status, SIGTRAP);
15951.1Skamil
15961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
15971.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
15981.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
15991.1Skamil
16001.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
16011.1Skamil	    "without signal to be sent\n");
16021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
16031.1Skamil
16041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16051.1Skamil	    "without signal to be sent\n");
16061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16071.1Skamil
16081.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
16091.1Skamil	    TWAIT_FNAME);
16101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
16111.1Skamil	    child2);
16121.1Skamil
16131.1Skamil	validate_status_exited(status, exitval2);
16141.1Skamil
16151.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
16161.1Skamil	    TWAIT_FNAME);
16171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
16181.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
16191.1Skamil
16201.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
16211.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
16221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16231.1Skamil
16241.1Skamil	validate_status_stopped(status, SIGCHLD);
16251.1Skamil
16261.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16271.1Skamil	    "without signal to be sent\n");
16281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16291.1Skamil
16301.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
16311.1Skamil	    TWAIT_FNAME);
16321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16331.1Skamil
16341.1Skamil	validate_status_exited(status, exitval);
16351.1Skamil
16361.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
16371.1Skamil	    TWAIT_FNAME);
16381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16391.1Skamil}
16401.1Skamil#endif
16411.1Skamil
16421.1SkamilATF_TC(vfork2);
16431.1SkamilATF_TC_HEAD(vfork2, tc)
16441.1Skamil{
16451.1Skamil	atf_tc_set_md_var(tc, "descr",
16461.1Skamil	    "Verify that vfork(2) is not intercepted by ptrace(2) with empty "
16471.1Skamil	    "EVENT_MASK");
16481.1Skamil}
16491.1Skamil
16501.1SkamilATF_TC_BODY(vfork2, tc)
16511.1Skamil{
16521.1Skamil	const int exitval = 5;
16531.1Skamil	const int exitval2 = 15;
16541.1Skamil	const int sigval = SIGSTOP;
16551.1Skamil	pid_t child, child2, wpid;
16561.1Skamil#if defined(TWAIT_HAVE_STATUS)
16571.1Skamil	int status;
16581.1Skamil#endif
16591.1Skamil	ptrace_event_t event;
16601.1Skamil	const int elen = sizeof(event);
16611.1Skamil
16621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
16631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
16641.1Skamil	if (child == 0) {
16651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
16661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
16671.1Skamil
16681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
16691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
16701.1Skamil
16711.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
16721.1Skamil
16731.1Skamil		if (child2 == 0)
16741.1Skamil			_exit(exitval2);
16751.1Skamil
16761.1Skamil		FORKEE_REQUIRE_SUCCESS
16771.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
16781.1Skamil
16791.1Skamil		forkee_status_exited(status, exitval2);
16801.1Skamil
16811.13Schristos		DPRINTF("Before exiting of the child process\n");
16821.1Skamil		_exit(exitval);
16831.1Skamil	}
16841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
16851.1Skamil
16861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
16871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16881.1Skamil
16891.1Skamil	validate_status_stopped(status, sigval);
16901.1Skamil
16911.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
16921.1Skamil	event.pe_set_event = 0;
16931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
16941.1Skamil
16951.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16961.1Skamil	    "without signal to be sent\n");
16971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16981.1Skamil
16991.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
17001.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
17011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17021.1Skamil
17031.1Skamil	validate_status_stopped(status, SIGCHLD);
17041.1Skamil
17051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17061.1Skamil	    "without signal to be sent\n");
17071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17081.1Skamil
17091.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
17101.1Skamil	    TWAIT_FNAME);
17111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17121.1Skamil
17131.1Skamil	validate_status_exited(status, exitval);
17141.1Skamil
17151.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
17161.1Skamil	    TWAIT_FNAME);
17171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17181.1Skamil}
17191.1Skamil
17201.1SkamilATF_TC(vforkdone1);
17211.1SkamilATF_TC_HEAD(vforkdone1, tc)
17221.1Skamil{
17231.1Skamil	atf_tc_set_md_var(tc, "descr",
17241.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
17251.1Skamil	    "set to PTRACE_VFORK_DONE");
17261.1Skamil}
17271.1Skamil
17281.1SkamilATF_TC_BODY(vforkdone1, tc)
17291.1Skamil{
17301.1Skamil	const int exitval = 5;
17311.1Skamil	const int exitval2 = 15;
17321.1Skamil	const int sigval = SIGSTOP;
17331.1Skamil	pid_t child, child2, wpid;
17341.1Skamil#if defined(TWAIT_HAVE_STATUS)
17351.1Skamil	int status;
17361.1Skamil#endif
17371.1Skamil	ptrace_state_t state;
17381.1Skamil	const int slen = sizeof(state);
17391.1Skamil	ptrace_event_t event;
17401.1Skamil	const int elen = sizeof(event);
17411.1Skamil
17421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17441.1Skamil	if (child == 0) {
17451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17471.1Skamil
17481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17501.1Skamil
17511.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
17521.1Skamil
17531.1Skamil		if (child2 == 0)
17541.1Skamil			_exit(exitval2);
17551.1Skamil
17561.1Skamil		FORKEE_REQUIRE_SUCCESS
17571.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
17581.1Skamil
17591.1Skamil		forkee_status_exited(status, exitval2);
17601.1Skamil
17611.13Schristos		DPRINTF("Before exiting of the child process\n");
17621.1Skamil		_exit(exitval);
17631.1Skamil	}
17641.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17651.1Skamil
17661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17681.1Skamil
17691.1Skamil	validate_status_stopped(status, sigval);
17701.1Skamil
17711.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
17721.1Skamil	    child);
17731.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
17741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
17751.1Skamil
17761.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17771.1Skamil	    "without signal to be sent\n");
17781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17791.1Skamil
17801.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
17811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17821.1Skamil
17831.1Skamil	validate_status_stopped(status, SIGTRAP);
17841.1Skamil
17851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
17861.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
17871.1Skamil
17881.1Skamil	child2 = state.pe_other_pid;
17891.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
17901.1Skamil
17911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17921.1Skamil	    "without signal to be sent\n");
17931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17941.1Skamil
17951.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
17961.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
17971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17981.1Skamil
17991.1Skamil	validate_status_stopped(status, SIGCHLD);
18001.1Skamil
18011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18021.1Skamil	    "without signal to be sent\n");
18031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18041.1Skamil
18051.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
18061.1Skamil	    TWAIT_FNAME);
18071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18081.1Skamil
18091.1Skamil	validate_status_exited(status, exitval);
18101.1Skamil
18111.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
18121.1Skamil	    TWAIT_FNAME);
18131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18141.1Skamil}
18151.1Skamil
18161.1SkamilATF_TC(vforkdone2);
18171.1SkamilATF_TC_HEAD(vforkdone2, tc)
18181.1Skamil{
18191.1Skamil	atf_tc_set_md_var(tc, "descr",
18201.1Skamil	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
18211.1Skamil	    "set to PTRACE_FORK | PTRACE_VFORK_DONE");
18221.1Skamil}
18231.1Skamil
18241.1SkamilATF_TC_BODY(vforkdone2, tc)
18251.1Skamil{
18261.1Skamil	const int exitval = 5;
18271.1Skamil	const int exitval2 = 15;
18281.1Skamil	const int sigval = SIGSTOP;
18291.1Skamil	pid_t child, child2, wpid;
18301.1Skamil#if defined(TWAIT_HAVE_STATUS)
18311.1Skamil	int status;
18321.1Skamil#endif
18331.1Skamil	ptrace_state_t state;
18341.1Skamil	const int slen = sizeof(state);
18351.1Skamil	ptrace_event_t event;
18361.1Skamil	const int elen = sizeof(event);
18371.1Skamil
18381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18401.1Skamil	if (child == 0) {
18411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18431.1Skamil
18441.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18451.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18461.1Skamil
18471.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
18481.1Skamil
18491.1Skamil		if (child2 == 0)
18501.1Skamil			_exit(exitval2);
18511.1Skamil
18521.1Skamil		FORKEE_REQUIRE_SUCCESS
18531.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
18541.1Skamil
18551.1Skamil		forkee_status_exited(status, exitval2);
18561.1Skamil
18571.13Schristos		DPRINTF("Before exiting of the child process\n");
18581.1Skamil		_exit(exitval);
18591.1Skamil	}
18601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18611.1Skamil
18621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18641.1Skamil
18651.1Skamil	validate_status_stopped(status, sigval);
18661.1Skamil
18671.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
18681.1Skamil	event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE;
18691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
18701.1Skamil
18711.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18721.1Skamil	    "without signal to be sent\n");
18731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18741.1Skamil
18751.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
18761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18771.1Skamil
18781.1Skamil	validate_status_stopped(status, SIGTRAP);
18791.1Skamil
18801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
18811.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
18821.1Skamil
18831.1Skamil	child2 = state.pe_other_pid;
18841.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
18851.1Skamil
18861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18871.1Skamil	    "without signal to be sent\n");
18881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18891.1Skamil
18901.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
18911.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
18921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18931.1Skamil
18941.1Skamil	validate_status_stopped(status, SIGCHLD);
18951.1Skamil
18961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18971.1Skamil	    "without signal to be sent\n");
18981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18991.1Skamil
19001.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
19011.1Skamil	    TWAIT_FNAME);
19021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19031.1Skamil
19041.1Skamil	validate_status_exited(status, exitval);
19051.1Skamil
19061.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
19071.1Skamil	    TWAIT_FNAME);
19081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19091.1Skamil}
19101.1Skamil
19111.1SkamilATF_TC(io_read_d1);
19121.1SkamilATF_TC_HEAD(io_read_d1, tc)
19131.1Skamil{
19141.1Skamil	atf_tc_set_md_var(tc, "descr",
19151.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
19161.1Skamil}
19171.1Skamil
19181.1SkamilATF_TC_BODY(io_read_d1, tc)
19191.1Skamil{
19201.1Skamil	const int exitval = 5;
19211.1Skamil	const int sigval = SIGSTOP;
19221.1Skamil	pid_t child, wpid;
19231.1Skamil	uint8_t lookup_me = 0;
19241.1Skamil	const uint8_t magic = 0xab;
19251.1Skamil	struct ptrace_io_desc io = {
19261.1Skamil		.piod_op = PIOD_READ_D,
19271.1Skamil		.piod_offs = &lookup_me,
19281.1Skamil		.piod_addr = &lookup_me,
19291.1Skamil		.piod_len = sizeof(lookup_me)
19301.1Skamil	};
19311.1Skamil#if defined(TWAIT_HAVE_STATUS)
19321.1Skamil	int status;
19331.1Skamil#endif
19341.1Skamil
19351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19371.1Skamil	if (child == 0) {
19381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19401.1Skamil
19411.1Skamil		lookup_me = magic;
19421.1Skamil
19431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19451.1Skamil
19461.13Schristos		DPRINTF("Before exiting of the child process\n");
19471.1Skamil		_exit(exitval);
19481.1Skamil	}
19491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19501.1Skamil
19511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19531.1Skamil
19541.1Skamil	validate_status_stopped(status, sigval);
19551.1Skamil
19561.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19571.1Skamil	    child, getpid());
19581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19591.1Skamil
19601.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19611.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
19621.1Skamil
19631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19641.1Skamil	    "without signal to be sent\n");
19651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19661.1Skamil
19671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19691.1Skamil
19701.1Skamil	validate_status_exited(status, exitval);
19711.1Skamil
19721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19741.1Skamil}
19751.1Skamil
19761.1SkamilATF_TC(io_read_d2);
19771.1SkamilATF_TC_HEAD(io_read_d2, tc)
19781.1Skamil{
19791.1Skamil	atf_tc_set_md_var(tc, "descr",
19801.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
19811.1Skamil}
19821.1Skamil
19831.1SkamilATF_TC_BODY(io_read_d2, tc)
19841.1Skamil{
19851.1Skamil	const int exitval = 5;
19861.1Skamil	const int sigval = SIGSTOP;
19871.1Skamil	pid_t child, wpid;
19881.1Skamil	uint16_t lookup_me = 0;
19891.1Skamil	const uint16_t magic = 0x1234;
19901.1Skamil	struct ptrace_io_desc io = {
19911.1Skamil		.piod_op = PIOD_READ_D,
19921.1Skamil		.piod_offs = &lookup_me,
19931.1Skamil		.piod_addr = &lookup_me,
19941.1Skamil		.piod_len = sizeof(lookup_me)
19951.1Skamil	};
19961.1Skamil#if defined(TWAIT_HAVE_STATUS)
19971.1Skamil	int status;
19981.1Skamil#endif
19991.1Skamil
20001.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20011.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20021.1Skamil	if (child == 0) {
20031.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20041.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20051.1Skamil
20061.1Skamil		lookup_me = magic;
20071.1Skamil
20081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20101.1Skamil
20111.13Schristos		DPRINTF("Before exiting of the child process\n");
20121.1Skamil		_exit(exitval);
20131.1Skamil	}
20141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20151.1Skamil
20161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20181.1Skamil
20191.1Skamil	validate_status_stopped(status, sigval);
20201.1Skamil
20211.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20221.1Skamil	    child, getpid());
20231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20241.1Skamil
20251.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20261.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
20271.1Skamil
20281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20291.1Skamil	    "without signal to be sent\n");
20301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20311.1Skamil
20321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20341.1Skamil
20351.1Skamil	validate_status_exited(status, exitval);
20361.1Skamil
20371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20391.1Skamil}
20401.1Skamil
20411.1SkamilATF_TC(io_read_d3);
20421.1SkamilATF_TC_HEAD(io_read_d3, tc)
20431.1Skamil{
20441.1Skamil	atf_tc_set_md_var(tc, "descr",
20451.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
20461.1Skamil}
20471.1Skamil
20481.1SkamilATF_TC_BODY(io_read_d3, tc)
20491.1Skamil{
20501.1Skamil	const int exitval = 5;
20511.1Skamil	const int sigval = SIGSTOP;
20521.1Skamil	pid_t child, wpid;
20531.1Skamil	uint32_t lookup_me = 0;
20541.1Skamil	const uint32_t magic = 0x1234abcd;
20551.1Skamil	struct ptrace_io_desc io = {
20561.1Skamil		.piod_op = PIOD_READ_D,
20571.1Skamil		.piod_offs = &lookup_me,
20581.1Skamil		.piod_addr = &lookup_me,
20591.1Skamil		.piod_len = sizeof(lookup_me)
20601.1Skamil	};
20611.1Skamil#if defined(TWAIT_HAVE_STATUS)
20621.1Skamil	int status;
20631.1Skamil#endif
20641.1Skamil
20651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20671.1Skamil	if (child == 0) {
20681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20701.1Skamil
20711.1Skamil		lookup_me = magic;
20721.1Skamil
20731.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20741.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20751.1Skamil
20761.13Schristos		DPRINTF("Before exiting of the child process\n");
20771.1Skamil		_exit(exitval);
20781.1Skamil	}
20791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20801.1Skamil
20811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20831.1Skamil
20841.1Skamil	validate_status_stopped(status, sigval);
20851.1Skamil
20861.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
20871.1Skamil	    child, getpid());
20881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20891.1Skamil
20901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
20911.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
20921.1Skamil
20931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20941.1Skamil	    "without signal to be sent\n");
20951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20961.1Skamil
20971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20991.1Skamil
21001.1Skamil	validate_status_exited(status, exitval);
21011.1Skamil
21021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21041.1Skamil}
21051.1Skamil
21061.1SkamilATF_TC(io_read_d4);
21071.1SkamilATF_TC_HEAD(io_read_d4, tc)
21081.1Skamil{
21091.1Skamil	atf_tc_set_md_var(tc, "descr",
21101.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
21111.1Skamil}
21121.1Skamil
21131.1SkamilATF_TC_BODY(io_read_d4, tc)
21141.1Skamil{
21151.1Skamil	const int exitval = 5;
21161.1Skamil	const int sigval = SIGSTOP;
21171.1Skamil	pid_t child, wpid;
21181.1Skamil	uint64_t lookup_me = 0;
21191.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
21201.1Skamil	struct ptrace_io_desc io = {
21211.1Skamil		.piod_op = PIOD_READ_D,
21221.1Skamil		.piod_offs = &lookup_me,
21231.1Skamil		.piod_addr = &lookup_me,
21241.1Skamil		.piod_len = sizeof(lookup_me)
21251.1Skamil	};
21261.1Skamil#if defined(TWAIT_HAVE_STATUS)
21271.1Skamil	int status;
21281.1Skamil#endif
21291.1Skamil
21301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21321.1Skamil	if (child == 0) {
21331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21351.1Skamil
21361.1Skamil		lookup_me = magic;
21371.1Skamil
21381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21401.1Skamil
21411.13Schristos		DPRINTF("Before exiting of the child process\n");
21421.1Skamil		_exit(exitval);
21431.1Skamil	}
21441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21451.1Skamil
21461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21481.1Skamil
21491.1Skamil	validate_status_stopped(status, sigval);
21501.1Skamil
21511.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
21521.1Skamil	    child, getpid());
21531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21541.1Skamil
21551.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
21561.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
21571.1Skamil
21581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21591.1Skamil	    "without signal to be sent\n");
21601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21611.1Skamil
21621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21641.1Skamil
21651.1Skamil	validate_status_exited(status, exitval);
21661.1Skamil
21671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21691.1Skamil}
21701.1Skamil
21711.1SkamilATF_TC(io_write_d1);
21721.1SkamilATF_TC_HEAD(io_write_d1, tc)
21731.1Skamil{
21741.1Skamil	atf_tc_set_md_var(tc, "descr",
21751.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
21761.1Skamil}
21771.1Skamil
21781.1SkamilATF_TC_BODY(io_write_d1, tc)
21791.1Skamil{
21801.1Skamil	const int exitval = 5;
21811.1Skamil	const int sigval = SIGSTOP;
21821.1Skamil	pid_t child, wpid;
21831.1Skamil	uint8_t lookup_me = 0;
21841.1Skamil	const uint8_t magic = 0xab;
21851.1Skamil	struct ptrace_io_desc io = {
21861.1Skamil		.piod_op = PIOD_WRITE_D,
21871.1Skamil		.piod_offs = &lookup_me,
21881.1Skamil		.piod_addr = &lookup_me,
21891.1Skamil		.piod_len = sizeof(lookup_me)
21901.1Skamil	};
21911.1Skamil#if defined(TWAIT_HAVE_STATUS)
21921.1Skamil	int status;
21931.1Skamil#endif
21941.1Skamil
21951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21971.1Skamil	if (child == 0) {
21981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22001.1Skamil
22011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22031.1Skamil
22041.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22051.1Skamil
22061.13Schristos		DPRINTF("Before exiting of the child process\n");
22071.1Skamil		_exit(exitval);
22081.1Skamil	}
22091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22101.1Skamil
22111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22131.1Skamil
22141.1Skamil	validate_status_stopped(status, sigval);
22151.1Skamil
22161.1Skamil	lookup_me = magic;
22171.1Skamil
22181.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22191.1Skamil	    child, getpid());
22201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22211.1Skamil
22221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22231.1Skamil	    "without signal to be sent\n");
22241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22251.1Skamil
22261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22281.1Skamil
22291.1Skamil	validate_status_exited(status, exitval);
22301.1Skamil
22311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22331.1Skamil}
22341.1Skamil
22351.1SkamilATF_TC(io_write_d2);
22361.1SkamilATF_TC_HEAD(io_write_d2, tc)
22371.1Skamil{
22381.1Skamil	atf_tc_set_md_var(tc, "descr",
22391.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
22401.1Skamil}
22411.1Skamil
22421.1SkamilATF_TC_BODY(io_write_d2, tc)
22431.1Skamil{
22441.1Skamil	const int exitval = 5;
22451.1Skamil	const int sigval = SIGSTOP;
22461.1Skamil	pid_t child, wpid;
22471.1Skamil	uint16_t lookup_me = 0;
22481.1Skamil	const uint16_t magic = 0xab12;
22491.1Skamil	struct ptrace_io_desc io = {
22501.1Skamil		.piod_op = PIOD_WRITE_D,
22511.1Skamil		.piod_offs = &lookup_me,
22521.1Skamil		.piod_addr = &lookup_me,
22531.1Skamil		.piod_len = sizeof(lookup_me)
22541.1Skamil	};
22551.1Skamil#if defined(TWAIT_HAVE_STATUS)
22561.1Skamil	int status;
22571.1Skamil#endif
22581.1Skamil
22591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22611.1Skamil	if (child == 0) {
22621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22641.1Skamil
22651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22671.1Skamil
22681.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
22691.1Skamil
22701.13Schristos		DPRINTF("Before exiting of the child process\n");
22711.1Skamil		_exit(exitval);
22721.1Skamil	}
22731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22741.1Skamil
22751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22771.1Skamil
22781.1Skamil	validate_status_stopped(status, sigval);
22791.1Skamil
22801.1Skamil	lookup_me = magic;
22811.1Skamil
22821.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22831.1Skamil	    child, getpid());
22841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22851.1Skamil
22861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22871.1Skamil	    "without signal to be sent\n");
22881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22891.1Skamil
22901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22921.1Skamil
22931.1Skamil	validate_status_exited(status, exitval);
22941.1Skamil
22951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22961.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22971.1Skamil}
22981.1Skamil
22991.1SkamilATF_TC(io_write_d3);
23001.1SkamilATF_TC_HEAD(io_write_d3, tc)
23011.1Skamil{
23021.1Skamil	atf_tc_set_md_var(tc, "descr",
23031.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
23041.1Skamil}
23051.1Skamil
23061.1SkamilATF_TC_BODY(io_write_d3, tc)
23071.1Skamil{
23081.1Skamil	const int exitval = 5;
23091.1Skamil	const int sigval = SIGSTOP;
23101.1Skamil	pid_t child, wpid;
23111.1Skamil	uint32_t lookup_me = 0;
23121.1Skamil	const uint32_t magic = 0xab127643;
23131.1Skamil	struct ptrace_io_desc io = {
23141.1Skamil		.piod_op = PIOD_WRITE_D,
23151.1Skamil		.piod_offs = &lookup_me,
23161.1Skamil		.piod_addr = &lookup_me,
23171.1Skamil		.piod_len = sizeof(lookup_me)
23181.1Skamil	};
23191.1Skamil#if defined(TWAIT_HAVE_STATUS)
23201.1Skamil	int status;
23211.1Skamil#endif
23221.1Skamil
23231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23251.1Skamil	if (child == 0) {
23261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23281.1Skamil
23291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23311.1Skamil
23321.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23331.1Skamil
23341.13Schristos		DPRINTF("Before exiting of the child process\n");
23351.1Skamil		_exit(exitval);
23361.1Skamil	}
23371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23381.1Skamil
23391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23411.1Skamil
23421.1Skamil	validate_status_stopped(status, sigval);
23431.1Skamil
23441.1Skamil	lookup_me = magic;
23451.1Skamil
23461.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
23471.1Skamil	    child, getpid());
23481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
23491.1Skamil
23501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23511.1Skamil	    "without signal to be sent\n");
23521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23531.1Skamil
23541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23561.1Skamil
23571.1Skamil	validate_status_exited(status, exitval);
23581.1Skamil
23591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23611.1Skamil}
23621.1Skamil
23631.1SkamilATF_TC(io_write_d4);
23641.1SkamilATF_TC_HEAD(io_write_d4, tc)
23651.1Skamil{
23661.1Skamil	atf_tc_set_md_var(tc, "descr",
23671.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
23681.1Skamil}
23691.1Skamil
23701.1SkamilATF_TC_BODY(io_write_d4, tc)
23711.1Skamil{
23721.1Skamil	const int exitval = 5;
23731.1Skamil	const int sigval = SIGSTOP;
23741.1Skamil	pid_t child, wpid;
23751.1Skamil	uint64_t lookup_me = 0;
23761.1Skamil	const uint64_t magic = 0xab12764376490123;
23771.1Skamil	struct ptrace_io_desc io = {
23781.1Skamil		.piod_op = PIOD_WRITE_D,
23791.1Skamil		.piod_offs = &lookup_me,
23801.1Skamil		.piod_addr = &lookup_me,
23811.1Skamil		.piod_len = sizeof(lookup_me)
23821.1Skamil	};
23831.1Skamil#if defined(TWAIT_HAVE_STATUS)
23841.1Skamil	int status;
23851.1Skamil#endif
23861.1Skamil
23871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23891.1Skamil	if (child == 0) {
23901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23921.1Skamil
23931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23951.1Skamil
23961.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
23971.1Skamil
23981.13Schristos		DPRINTF("Before exiting of the child process\n");
23991.1Skamil		_exit(exitval);
24001.1Skamil	}
24011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24021.1Skamil
24031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24051.1Skamil
24061.1Skamil	validate_status_stopped(status, sigval);
24071.1Skamil
24081.1Skamil	lookup_me = magic;
24091.1Skamil
24101.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
24111.1Skamil	    child, getpid());
24121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24131.1Skamil
24141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24151.1Skamil	    "without signal to be sent\n");
24161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24171.1Skamil
24181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24201.1Skamil
24211.1Skamil	validate_status_exited(status, exitval);
24221.1Skamil
24231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24251.1Skamil}
24261.1Skamil
24271.1SkamilATF_TC(io_read_auxv1);
24281.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
24291.1Skamil{
24301.1Skamil	atf_tc_set_md_var(tc, "descr",
24311.1Skamil	    "Verify PT_READ_AUXV called for tracee");
24321.1Skamil}
24331.1Skamil
24341.1SkamilATF_TC_BODY(io_read_auxv1, tc)
24351.1Skamil{
24361.1Skamil	const int exitval = 5;
24371.1Skamil	const int sigval = SIGSTOP;
24381.1Skamil	pid_t child, wpid;
24391.1Skamil#if defined(TWAIT_HAVE_STATUS)
24401.1Skamil	int status;
24411.1Skamil#endif
24421.1Skamil	AuxInfo ai[100], *aip;
24431.1Skamil	struct ptrace_io_desc io = {
24441.1Skamil		.piod_op = PIOD_READ_AUXV,
24451.1Skamil		.piod_offs = 0,
24461.1Skamil		.piod_addr = ai,
24471.1Skamil		.piod_len = sizeof(ai)
24481.1Skamil	};
24491.1Skamil
24501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24521.1Skamil	if (child == 0) {
24531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24551.1Skamil
24561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24581.1Skamil
24591.13Schristos		DPRINTF("Before exiting of the child process\n");
24601.1Skamil		_exit(exitval);
24611.1Skamil	}
24621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24631.1Skamil
24641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24661.1Skamil
24671.1Skamil	validate_status_stopped(status, sigval);
24681.1Skamil
24691.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
24701.1Skamil	    child, getpid());
24711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
24721.1Skamil
24731.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
24741.1Skamil	ATF_REQUIRE(io.piod_len > 0);
24751.1Skamil
24761.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
24771.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
24781.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
24791.1Skamil
24801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24811.1Skamil	    "without signal to be sent\n");
24821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24831.1Skamil
24841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24861.1Skamil
24871.1Skamil	validate_status_exited(status, exitval);
24881.1Skamil
24891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24911.1Skamil}
24921.1Skamil
24931.1SkamilATF_TC(read_d1);
24941.1SkamilATF_TC_HEAD(read_d1, tc)
24951.1Skamil{
24961.1Skamil	atf_tc_set_md_var(tc, "descr",
24971.1Skamil	    "Verify PT_READ_D called once");
24981.1Skamil}
24991.1Skamil
25001.1SkamilATF_TC_BODY(read_d1, tc)
25011.1Skamil{
25021.1Skamil	const int exitval = 5;
25031.1Skamil	const int sigval = SIGSTOP;
25041.1Skamil	pid_t child, wpid;
25051.1Skamil	int lookup_me = 0;
25061.1Skamil	const int magic = (int)random();
25071.1Skamil#if defined(TWAIT_HAVE_STATUS)
25081.1Skamil	int status;
25091.1Skamil#endif
25101.1Skamil
25111.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25121.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25131.1Skamil	if (child == 0) {
25141.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25151.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25161.1Skamil
25171.1Skamil		lookup_me = magic;
25181.1Skamil
25191.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25201.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25211.1Skamil
25221.13Schristos		DPRINTF("Before exiting of the child process\n");
25231.1Skamil		_exit(exitval);
25241.1Skamil	}
25251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25261.1Skamil
25271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25291.1Skamil
25301.1Skamil	validate_status_stopped(status, sigval);
25311.1Skamil
25321.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
25331.1Skamil	    child, getpid());
25341.1Skamil	errno = 0;
25351.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
25361.1Skamil	ATF_REQUIRE_EQ(errno, 0);
25371.1Skamil
25381.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
25391.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
25401.1Skamil
25411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25421.1Skamil	    "without signal to be sent\n");
25431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25441.1Skamil
25451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25471.1Skamil
25481.1Skamil	validate_status_exited(status, exitval);
25491.1Skamil
25501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25521.1Skamil}
25531.1Skamil
25541.1SkamilATF_TC(read_d2);
25551.1SkamilATF_TC_HEAD(read_d2, tc)
25561.1Skamil{
25571.1Skamil	atf_tc_set_md_var(tc, "descr",
25581.1Skamil	    "Verify PT_READ_D called twice");
25591.1Skamil}
25601.1Skamil
25611.1SkamilATF_TC_BODY(read_d2, tc)
25621.1Skamil{
25631.1Skamil	const int exitval = 5;
25641.1Skamil	const int sigval = SIGSTOP;
25651.1Skamil	pid_t child, wpid;
25661.1Skamil	int lookup_me1 = 0;
25671.1Skamil	int lookup_me2 = 0;
25681.1Skamil	const int magic1 = (int)random();
25691.1Skamil	const int magic2 = (int)random();
25701.1Skamil#if defined(TWAIT_HAVE_STATUS)
25711.1Skamil	int status;
25721.1Skamil#endif
25731.1Skamil
25741.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25751.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25761.1Skamil	if (child == 0) {
25771.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25781.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25791.1Skamil
25801.1Skamil		lookup_me1 = magic1;
25811.1Skamil		lookup_me2 = magic2;
25821.1Skamil
25831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25851.1Skamil
25861.13Schristos		DPRINTF("Before exiting of the child process\n");
25871.1Skamil		_exit(exitval);
25881.1Skamil	}
25891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25901.1Skamil
25911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25931.1Skamil
25941.1Skamil	validate_status_stopped(status, sigval);
25951.1Skamil
25961.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
25971.1Skamil	    child, getpid());
25981.1Skamil	errno = 0;
25991.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26001.1Skamil	ATF_REQUIRE_EQ(errno, 0);
26011.1Skamil
26021.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26031.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26041.1Skamil
26051.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26061.1Skamil	    child, getpid());
26071.1Skamil	errno = 0;
26081.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26091.1Skamil	ATF_REQUIRE_EQ(errno, 0);
26101.1Skamil
26111.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26121.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26131.1Skamil
26141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26151.1Skamil	    "without signal to be sent\n");
26161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26171.1Skamil
26181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26201.1Skamil
26211.1Skamil	validate_status_exited(status, exitval);
26221.1Skamil
26231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26241.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26251.1Skamil}
26261.1Skamil
26271.1SkamilATF_TC(read_d3);
26281.1SkamilATF_TC_HEAD(read_d3, tc)
26291.1Skamil{
26301.1Skamil	atf_tc_set_md_var(tc, "descr",
26311.1Skamil	    "Verify PT_READ_D called three times");
26321.1Skamil}
26331.1Skamil
26341.1SkamilATF_TC_BODY(read_d3, tc)
26351.1Skamil{
26361.1Skamil	const int exitval = 5;
26371.1Skamil	const int sigval = SIGSTOP;
26381.1Skamil	pid_t child, wpid;
26391.1Skamil	int lookup_me1 = 0;
26401.1Skamil	int lookup_me2 = 0;
26411.1Skamil	int lookup_me3 = 0;
26421.1Skamil	const int magic1 = (int)random();
26431.1Skamil	const int magic2 = (int)random();
26441.1Skamil	const int magic3 = (int)random();
26451.1Skamil#if defined(TWAIT_HAVE_STATUS)
26461.1Skamil	int status;
26471.1Skamil#endif
26481.1Skamil
26491.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26501.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26511.1Skamil	if (child == 0) {
26521.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26531.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26541.1Skamil
26551.1Skamil		lookup_me1 = magic1;
26561.1Skamil		lookup_me2 = magic2;
26571.1Skamil		lookup_me3 = magic3;
26581.1Skamil
26591.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26601.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26611.1Skamil
26621.13Schristos		DPRINTF("Before exiting of the child process\n");
26631.1Skamil		_exit(exitval);
26641.1Skamil	}
26651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26661.1Skamil
26671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26691.1Skamil
26701.1Skamil	validate_status_stopped(status, sigval);
26711.1Skamil
26721.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
26731.1Skamil	    child, getpid());
26741.1Skamil	errno = 0;
26751.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
26761.1Skamil	ATF_REQUIRE_EQ(errno, 0);
26771.1Skamil
26781.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
26791.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
26801.1Skamil
26811.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
26821.1Skamil	    child, getpid());
26831.1Skamil	errno = 0;
26841.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
26851.1Skamil	ATF_REQUIRE_EQ(errno, 0);
26861.1Skamil
26871.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
26881.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
26891.1Skamil
26901.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
26911.1Skamil	    child, getpid());
26921.1Skamil	errno = 0;
26931.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
26941.1Skamil	ATF_REQUIRE_EQ(errno, 0);
26951.1Skamil
26961.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
26971.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
26981.1Skamil
26991.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27001.1Skamil	    "without signal to be sent\n");
27011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27021.1Skamil
27031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27051.1Skamil
27061.1Skamil	validate_status_exited(status, exitval);
27071.1Skamil
27081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27101.1Skamil}
27111.1Skamil
27121.1SkamilATF_TC(read_d4);
27131.1SkamilATF_TC_HEAD(read_d4, tc)
27141.1Skamil{
27151.1Skamil	atf_tc_set_md_var(tc, "descr",
27161.1Skamil	    "Verify PT_READ_D called four times");
27171.1Skamil}
27181.1Skamil
27191.1SkamilATF_TC_BODY(read_d4, tc)
27201.1Skamil{
27211.1Skamil	const int exitval = 5;
27221.1Skamil	const int sigval = SIGSTOP;
27231.1Skamil	pid_t child, wpid;
27241.1Skamil	int lookup_me1 = 0;
27251.1Skamil	int lookup_me2 = 0;
27261.1Skamil	int lookup_me3 = 0;
27271.1Skamil	int lookup_me4 = 0;
27281.1Skamil	const int magic1 = (int)random();
27291.1Skamil	const int magic2 = (int)random();
27301.1Skamil	const int magic3 = (int)random();
27311.1Skamil	const int magic4 = (int)random();
27321.1Skamil#if defined(TWAIT_HAVE_STATUS)
27331.1Skamil	int status;
27341.1Skamil#endif
27351.1Skamil
27361.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27371.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27381.1Skamil	if (child == 0) {
27391.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27401.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27411.1Skamil
27421.1Skamil		lookup_me1 = magic1;
27431.1Skamil		lookup_me2 = magic2;
27441.1Skamil		lookup_me3 = magic3;
27451.1Skamil		lookup_me4 = magic4;
27461.1Skamil
27471.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27481.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27491.1Skamil
27501.13Schristos		DPRINTF("Before exiting of the child process\n");
27511.1Skamil		_exit(exitval);
27521.1Skamil	}
27531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27541.1Skamil
27551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27571.1Skamil
27581.1Skamil	validate_status_stopped(status, sigval);
27591.1Skamil
27601.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
27611.1Skamil	    child, getpid());
27621.1Skamil	errno = 0;
27631.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
27641.1Skamil	ATF_REQUIRE_EQ(errno, 0);
27651.1Skamil
27661.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
27671.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
27681.1Skamil
27691.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
27701.1Skamil	    child, getpid());
27711.1Skamil	errno = 0;
27721.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
27731.1Skamil	ATF_REQUIRE_EQ(errno, 0);
27741.1Skamil
27751.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
27761.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
27771.1Skamil
27781.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
27791.1Skamil	    child, getpid());
27801.1Skamil	errno = 0;
27811.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
27821.1Skamil	ATF_REQUIRE_EQ(errno, 0);
27831.1Skamil
27841.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
27851.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
27861.1Skamil
27871.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
27881.1Skamil	    child, getpid());
27891.1Skamil	errno = 0;
27901.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
27911.1Skamil	ATF_REQUIRE_EQ(errno, 0);
27921.1Skamil
27931.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
27941.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
27951.1Skamil
27961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27971.1Skamil	    "without signal to be sent\n");
27981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27991.1Skamil
28001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28021.1Skamil
28031.1Skamil	validate_status_exited(status, exitval);
28041.1Skamil
28051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28071.1Skamil}
28081.1Skamil
28091.1SkamilATF_TC(write_d1);
28101.1SkamilATF_TC_HEAD(write_d1, tc)
28111.1Skamil{
28121.1Skamil	atf_tc_set_md_var(tc, "descr",
28131.1Skamil	    "Verify PT_WRITE_D called once");
28141.1Skamil}
28151.1Skamil
28161.1SkamilATF_TC_BODY(write_d1, tc)
28171.1Skamil{
28181.1Skamil	const int exitval = 5;
28191.1Skamil	const int sigval = SIGSTOP;
28201.1Skamil	pid_t child, wpid;
28211.1Skamil	int lookup_me = 0;
28221.1Skamil	const int magic = (int)random();
28231.1Skamil#if defined(TWAIT_HAVE_STATUS)
28241.1Skamil	int status;
28251.1Skamil#endif
28261.1Skamil
28271.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28281.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28291.1Skamil	if (child == 0) {
28301.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28311.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28321.1Skamil
28331.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28341.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28351.1Skamil
28361.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
28371.1Skamil
28381.13Schristos		DPRINTF("Before exiting of the child process\n");
28391.1Skamil		_exit(exitval);
28401.1Skamil	}
28411.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28421.1Skamil
28431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28451.1Skamil
28461.1Skamil	validate_status_stopped(status, sigval);
28471.1Skamil
28481.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
28491.1Skamil	    child, getpid());
28501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
28511.1Skamil
28521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28531.1Skamil	    "without signal to be sent\n");
28541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28551.1Skamil
28561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28581.1Skamil
28591.1Skamil	validate_status_exited(status, exitval);
28601.1Skamil
28611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28631.1Skamil}
28641.1Skamil
28651.1SkamilATF_TC(write_d2);
28661.1SkamilATF_TC_HEAD(write_d2, tc)
28671.1Skamil{
28681.1Skamil	atf_tc_set_md_var(tc, "descr",
28691.1Skamil	    "Verify PT_WRITE_D called twice");
28701.1Skamil}
28711.1Skamil
28721.1SkamilATF_TC_BODY(write_d2, tc)
28731.1Skamil{
28741.1Skamil	const int exitval = 5;
28751.1Skamil	const int sigval = SIGSTOP;
28761.1Skamil	pid_t child, wpid;
28771.1Skamil	int lookup_me1 = 0;
28781.1Skamil	int lookup_me2 = 0;
28791.1Skamil	const int magic1 = (int)random();
28801.1Skamil	const int magic2 = (int)random();
28811.1Skamil#if defined(TWAIT_HAVE_STATUS)
28821.1Skamil	int status;
28831.1Skamil#endif
28841.1Skamil
28851.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28861.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28871.1Skamil	if (child == 0) {
28881.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28891.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28901.1Skamil
28911.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28921.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28931.1Skamil
28941.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
28951.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
28961.1Skamil
28971.13Schristos		DPRINTF("Before exiting of the child process\n");
28981.1Skamil		_exit(exitval);
28991.1Skamil	}
29001.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29011.1Skamil
29021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29041.1Skamil
29051.1Skamil	validate_status_stopped(status, sigval);
29061.1Skamil
29071.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29081.1Skamil	    child, getpid());
29091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29101.1Skamil
29111.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29121.1Skamil	    child, getpid());
29131.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29141.1Skamil
29151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29161.1Skamil	    "without signal to be sent\n");
29171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29181.1Skamil
29191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29211.1Skamil
29221.1Skamil	validate_status_exited(status, exitval);
29231.1Skamil
29241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29251.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29261.1Skamil}
29271.1Skamil
29281.1SkamilATF_TC(write_d3);
29291.1SkamilATF_TC_HEAD(write_d3, tc)
29301.1Skamil{
29311.1Skamil	atf_tc_set_md_var(tc, "descr",
29321.1Skamil	    "Verify PT_WRITE_D called three times");
29331.1Skamil}
29341.1Skamil
29351.1SkamilATF_TC_BODY(write_d3, tc)
29361.1Skamil{
29371.1Skamil	const int exitval = 5;
29381.1Skamil	const int sigval = SIGSTOP;
29391.1Skamil	pid_t child, wpid;
29401.1Skamil	int lookup_me1 = 0;
29411.1Skamil	int lookup_me2 = 0;
29421.1Skamil	int lookup_me3 = 0;
29431.1Skamil	const int magic1 = (int)random();
29441.1Skamil	const int magic2 = (int)random();
29451.1Skamil	const int magic3 = (int)random();
29461.1Skamil#if defined(TWAIT_HAVE_STATUS)
29471.1Skamil	int status;
29481.1Skamil#endif
29491.1Skamil
29501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29521.1Skamil	if (child == 0) {
29531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29551.1Skamil
29561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29581.1Skamil
29591.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
29601.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
29611.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
29621.1Skamil
29631.13Schristos		DPRINTF("Before exiting of the child process\n");
29641.1Skamil		_exit(exitval);
29651.1Skamil	}
29661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29671.1Skamil
29681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29701.1Skamil
29711.1Skamil	validate_status_stopped(status, sigval);
29721.1Skamil
29731.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
29741.1Skamil	    child, getpid());
29751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
29761.1Skamil
29771.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
29781.1Skamil	    child, getpid());
29791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
29801.1Skamil
29811.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
29821.1Skamil	    child, getpid());
29831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
29841.1Skamil
29851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29861.1Skamil	    "without signal to be sent\n");
29871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29881.1Skamil
29891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29911.1Skamil
29921.1Skamil	validate_status_exited(status, exitval);
29931.1Skamil
29941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29961.1Skamil}
29971.1Skamil
29981.1SkamilATF_TC(write_d4);
29991.1SkamilATF_TC_HEAD(write_d4, tc)
30001.1Skamil{
30011.1Skamil	atf_tc_set_md_var(tc, "descr",
30021.1Skamil	    "Verify PT_WRITE_D called four times");
30031.1Skamil}
30041.1Skamil
30051.1SkamilATF_TC_BODY(write_d4, tc)
30061.1Skamil{
30071.1Skamil	const int exitval = 5;
30081.1Skamil	const int sigval = SIGSTOP;
30091.1Skamil	pid_t child, wpid;
30101.1Skamil	int lookup_me1 = 0;
30111.1Skamil	int lookup_me2 = 0;
30121.1Skamil	int lookup_me3 = 0;
30131.1Skamil	int lookup_me4 = 0;
30141.1Skamil	const int magic1 = (int)random();
30151.1Skamil	const int magic2 = (int)random();
30161.1Skamil	const int magic3 = (int)random();
30171.1Skamil	const int magic4 = (int)random();
30181.1Skamil#if defined(TWAIT_HAVE_STATUS)
30191.1Skamil	int status;
30201.1Skamil#endif
30211.1Skamil
30221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30241.1Skamil	if (child == 0) {
30251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30271.1Skamil
30281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30301.1Skamil
30311.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
30321.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
30331.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
30341.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
30351.1Skamil
30361.13Schristos		DPRINTF("Before exiting of the child process\n");
30371.1Skamil		_exit(exitval);
30381.1Skamil	}
30391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30401.1Skamil
30411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30431.1Skamil
30441.1Skamil	validate_status_stopped(status, sigval);
30451.1Skamil
30461.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
30471.1Skamil	    child, getpid());
30481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
30491.1Skamil
30501.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
30511.1Skamil	    child, getpid());
30521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
30531.1Skamil
30541.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
30551.1Skamil	    child, getpid());
30561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
30571.1Skamil
30581.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
30591.1Skamil	    child, getpid());
30601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
30611.1Skamil
30621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30631.1Skamil	    "without signal to be sent\n");
30641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30651.1Skamil
30661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30681.1Skamil
30691.1Skamil	validate_status_exited(status, exitval);
30701.1Skamil
30711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30721.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30731.1Skamil}
30741.1Skamil
30751.1SkamilATF_TC(io_read_d_write_d_handshake1);
30761.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
30771.1Skamil{
30781.1Skamil	atf_tc_set_md_var(tc, "descr",
30791.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
30801.1Skamil}
30811.1Skamil
30821.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
30831.1Skamil{
30841.1Skamil	const int exitval = 5;
30851.1Skamil	const int sigval = SIGSTOP;
30861.1Skamil	pid_t child, wpid;
30871.1Skamil	uint8_t lookup_me_fromtracee = 0;
30881.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
30891.1Skamil	uint8_t lookup_me_totracee = 0;
30901.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
30911.1Skamil	struct ptrace_io_desc io_fromtracee = {
30921.1Skamil		.piod_op = PIOD_READ_D,
30931.1Skamil		.piod_offs = &lookup_me_fromtracee,
30941.1Skamil		.piod_addr = &lookup_me_fromtracee,
30951.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
30961.1Skamil	};
30971.1Skamil	struct ptrace_io_desc io_totracee = {
30981.1Skamil		.piod_op = PIOD_WRITE_D,
30991.1Skamil		.piod_offs = &lookup_me_totracee,
31001.1Skamil		.piod_addr = &lookup_me_totracee,
31011.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31021.1Skamil	};
31031.1Skamil#if defined(TWAIT_HAVE_STATUS)
31041.1Skamil	int status;
31051.1Skamil#endif
31061.1Skamil
31071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31091.1Skamil	if (child == 0) {
31101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31121.1Skamil
31131.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31141.1Skamil
31151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31171.1Skamil
31181.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31191.1Skamil
31201.13Schristos		DPRINTF("Before exiting of the child process\n");
31211.1Skamil		_exit(exitval);
31221.1Skamil	}
31231.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31241.1Skamil
31251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31271.1Skamil
31281.1Skamil	validate_status_stopped(status, sigval);
31291.1Skamil
31301.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31311.1Skamil	    child, getpid());
31321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
31331.1Skamil
31341.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31351.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
31361.1Skamil	    magic_fromtracee);
31371.1Skamil
31381.1Skamil	lookup_me_totracee = magic_totracee;
31391.1Skamil
31401.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
31411.1Skamil	    child, getpid());
31421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
31431.1Skamil
31441.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
31451.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
31461.1Skamil	    magic_totracee);
31471.1Skamil
31481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31491.1Skamil	    "without signal to be sent\n");
31501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31511.1Skamil
31521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31541.1Skamil
31551.1Skamil	validate_status_exited(status, exitval);
31561.1Skamil
31571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31591.1Skamil}
31601.1Skamil
31611.1SkamilATF_TC(io_read_d_write_d_handshake2);
31621.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
31631.1Skamil{
31641.1Skamil	atf_tc_set_md_var(tc, "descr",
31651.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
31661.1Skamil}
31671.1Skamil
31681.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
31691.1Skamil{
31701.1Skamil	const int exitval = 5;
31711.1Skamil	const int sigval = SIGSTOP;
31721.1Skamil	pid_t child, wpid;
31731.1Skamil	uint8_t lookup_me_fromtracee = 0;
31741.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
31751.1Skamil	uint8_t lookup_me_totracee = 0;
31761.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
31771.1Skamil	struct ptrace_io_desc io_fromtracee = {
31781.1Skamil		.piod_op = PIOD_READ_D,
31791.1Skamil		.piod_offs = &lookup_me_fromtracee,
31801.1Skamil		.piod_addr = &lookup_me_fromtracee,
31811.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
31821.1Skamil	};
31831.1Skamil	struct ptrace_io_desc io_totracee = {
31841.1Skamil		.piod_op = PIOD_WRITE_D,
31851.1Skamil		.piod_offs = &lookup_me_totracee,
31861.1Skamil		.piod_addr = &lookup_me_totracee,
31871.1Skamil		.piod_len = sizeof(lookup_me_totracee)
31881.1Skamil	};
31891.1Skamil#if defined(TWAIT_HAVE_STATUS)
31901.1Skamil	int status;
31911.1Skamil#endif
31921.1Skamil
31931.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31941.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31951.1Skamil	if (child == 0) {
31961.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31971.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31981.1Skamil
31991.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32001.1Skamil
32011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32031.1Skamil
32041.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32051.1Skamil
32061.13Schristos		DPRINTF("Before exiting of the child process\n");
32071.1Skamil		_exit(exitval);
32081.1Skamil	}
32091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32101.1Skamil
32111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32131.1Skamil
32141.1Skamil	validate_status_stopped(status, sigval);
32151.1Skamil
32161.1Skamil	lookup_me_totracee = magic_totracee;
32171.1Skamil
32181.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
32191.1Skamil	    child, getpid());
32201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
32211.1Skamil
32221.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
32231.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
32241.1Skamil	    magic_totracee);
32251.1Skamil
32261.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32271.1Skamil	    child, getpid());
32281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
32291.1Skamil
32301.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32311.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
32321.1Skamil	    magic_fromtracee);
32331.1Skamil
32341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32351.1Skamil	    "without signal to be sent\n");
32361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32371.1Skamil
32381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32401.1Skamil
32411.1Skamil	validate_status_exited(status, exitval);
32421.1Skamil
32431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32441.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32451.1Skamil}
32461.1Skamil
32471.1SkamilATF_TC(read_d_write_d_handshake1);
32481.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
32491.1Skamil{
32501.1Skamil	atf_tc_set_md_var(tc, "descr",
32511.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
32521.1Skamil}
32531.1Skamil
32541.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
32551.1Skamil{
32561.1Skamil	const int exitval = 5;
32571.1Skamil	const int sigval = SIGSTOP;
32581.1Skamil	pid_t child, wpid;
32591.1Skamil	int lookup_me_fromtracee = 0;
32601.1Skamil	const int magic_fromtracee = (int)random();
32611.1Skamil	int lookup_me_totracee = 0;
32621.1Skamil	const int magic_totracee = (int)random();
32631.1Skamil#if defined(TWAIT_HAVE_STATUS)
32641.1Skamil	int status;
32651.1Skamil#endif
32661.1Skamil
32671.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32681.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32691.1Skamil	if (child == 0) {
32701.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32711.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32721.1Skamil
32731.1Skamil		lookup_me_fromtracee = magic_fromtracee;
32741.1Skamil
32751.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32761.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32771.1Skamil
32781.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
32791.1Skamil
32801.13Schristos		DPRINTF("Before exiting of the child process\n");
32811.1Skamil		_exit(exitval);
32821.1Skamil	}
32831.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32841.1Skamil
32851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32871.1Skamil
32881.1Skamil	validate_status_stopped(status, sigval);
32891.1Skamil
32901.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
32911.1Skamil	    child, getpid());
32921.1Skamil	errno = 0;
32931.1Skamil	lookup_me_fromtracee =
32941.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
32951.1Skamil	ATF_REQUIRE_EQ(errno, 0);
32961.1Skamil
32971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
32981.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
32991.1Skamil	    magic_fromtracee);
33001.1Skamil
33011.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33021.1Skamil	    child, getpid());
33031.1Skamil	ATF_REQUIRE
33041.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33051.1Skamil	    != -1);
33061.1Skamil
33071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33081.1Skamil	    "without signal to be sent\n");
33091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33101.1Skamil
33111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33131.1Skamil
33141.1Skamil	validate_status_exited(status, exitval);
33151.1Skamil
33161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33171.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33181.1Skamil}
33191.1Skamil
33201.1SkamilATF_TC(read_d_write_d_handshake2);
33211.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
33221.1Skamil{
33231.1Skamil	atf_tc_set_md_var(tc, "descr",
33241.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
33251.1Skamil}
33261.1Skamil
33271.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
33281.1Skamil{
33291.1Skamil	const int exitval = 5;
33301.1Skamil	const int sigval = SIGSTOP;
33311.1Skamil	pid_t child, wpid;
33321.1Skamil	int lookup_me_fromtracee = 0;
33331.1Skamil	const int magic_fromtracee = (int)random();
33341.1Skamil	int lookup_me_totracee = 0;
33351.1Skamil	const int magic_totracee = (int)random();
33361.1Skamil#if defined(TWAIT_HAVE_STATUS)
33371.1Skamil	int status;
33381.1Skamil#endif
33391.1Skamil
33401.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33411.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33421.1Skamil	if (child == 0) {
33431.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33441.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33451.1Skamil
33461.1Skamil		lookup_me_fromtracee = magic_fromtracee;
33471.1Skamil
33481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33501.1Skamil
33511.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
33521.1Skamil
33531.13Schristos		DPRINTF("Before exiting of the child process\n");
33541.1Skamil		_exit(exitval);
33551.1Skamil	}
33561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33571.1Skamil
33581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33601.1Skamil
33611.1Skamil	validate_status_stopped(status, sigval);
33621.1Skamil
33631.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
33641.1Skamil	    child, getpid());
33651.1Skamil	ATF_REQUIRE
33661.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
33671.1Skamil	    != -1);
33681.1Skamil
33691.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
33701.1Skamil	    child, getpid());
33711.1Skamil	errno = 0;
33721.1Skamil	lookup_me_fromtracee =
33731.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
33741.1Skamil	ATF_REQUIRE_EQ(errno, 0);
33751.1Skamil
33761.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
33771.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
33781.1Skamil	    magic_fromtracee);
33791.1Skamil
33801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33811.1Skamil	    "without signal to be sent\n");
33821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33831.1Skamil
33841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33861.1Skamil
33871.1Skamil	validate_status_exited(status, exitval);
33881.1Skamil
33891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33911.1Skamil}
33921.1Skamil
33931.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
33941.1Skamilstatic int __used
33951.1Skamildummy_fn1(int a, int b, int c, int d)
33961.1Skamil{
33971.1Skamil
33981.1Skamil	a *= 1;
33991.1Skamil	b += 2;
34001.1Skamil	c -= 3;
34011.1Skamil	d /= 4;
34021.1Skamil
34031.1Skamil	return a + b * c - d;
34041.1Skamil}
34051.1Skamil
34061.1Skamilstatic int __used
34071.1Skamildummy_fn2(int a, int b, int c, int d)
34081.1Skamil{
34091.1Skamil
34101.1Skamil	a *= 4;
34111.1Skamil	b += 3;
34121.1Skamil	c -= 2;
34131.1Skamil	d /= 1;
34141.1Skamil
34151.1Skamil	return a + b * c - d;
34161.1Skamil}
34171.1Skamil
34181.1Skamilstatic int __used
34191.1Skamildummy_fn3(int a, int b, int c, int d)
34201.1Skamil{
34211.1Skamil
34221.1Skamil	a *= 10;
34231.1Skamil	b += 20;
34241.1Skamil	c -= 30;
34251.1Skamil	d /= 40;
34261.1Skamil
34271.1Skamil	return a + b * c - d;
34281.1Skamil}
34291.1Skamil
34301.1Skamilstatic int __used
34311.1Skamildummy_fn4(int a, int b, int c, int d)
34321.1Skamil{
34331.1Skamil
34341.1Skamil	a *= 40;
34351.1Skamil	b += 30;
34361.1Skamil	c -= 20;
34371.1Skamil	d /= 10;
34381.1Skamil
34391.1Skamil	return a + b * c - d;
34401.1Skamil}
34411.1Skamil
34421.1SkamilATF_TC(io_read_i1);
34431.1SkamilATF_TC_HEAD(io_read_i1, tc)
34441.1Skamil{
34451.1Skamil	atf_tc_set_md_var(tc, "descr",
34461.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
34471.1Skamil}
34481.1Skamil
34491.1SkamilATF_TC_BODY(io_read_i1, tc)
34501.1Skamil{
34511.1Skamil	const int exitval = 5;
34521.1Skamil	const int sigval = SIGSTOP;
34531.1Skamil	pid_t child, wpid;
34541.1Skamil	uint8_t lookup_me = 0;
34551.1Skamil	uint8_t magic;
34561.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34571.1Skamil	struct ptrace_io_desc io = {
34581.1Skamil		.piod_op = PIOD_READ_I,
34591.1Skamil		.piod_offs = dummy_fn1,
34601.1Skamil		.piod_addr = &lookup_me,
34611.1Skamil		.piod_len = sizeof(lookup_me)
34621.1Skamil	};
34631.1Skamil#if defined(TWAIT_HAVE_STATUS)
34641.1Skamil	int status;
34651.1Skamil#endif
34661.1Skamil
34671.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34681.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34691.1Skamil	if (child == 0) {
34701.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34711.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34721.1Skamil
34731.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34741.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34751.1Skamil
34761.13Schristos		DPRINTF("Before exiting of the child process\n");
34771.1Skamil		_exit(exitval);
34781.1Skamil	}
34791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34801.1Skamil
34811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34831.1Skamil
34841.1Skamil	validate_status_stopped(status, sigval);
34851.1Skamil
34861.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34871.1Skamil	    child, getpid());
34881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34891.1Skamil
34901.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34911.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
34921.1Skamil
34931.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34941.1Skamil	    "without signal to be sent\n");
34951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34961.1Skamil
34971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34991.1Skamil
35001.1Skamil	validate_status_exited(status, exitval);
35011.1Skamil
35021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35031.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35041.1Skamil}
35051.1Skamil
35061.1SkamilATF_TC(io_read_i2);
35071.1SkamilATF_TC_HEAD(io_read_i2, tc)
35081.1Skamil{
35091.1Skamil	atf_tc_set_md_var(tc, "descr",
35101.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
35111.1Skamil}
35121.1Skamil
35131.1SkamilATF_TC_BODY(io_read_i2, tc)
35141.1Skamil{
35151.1Skamil	const int exitval = 5;
35161.1Skamil	const int sigval = SIGSTOP;
35171.1Skamil	pid_t child, wpid;
35181.1Skamil	uint16_t lookup_me = 0;
35191.1Skamil	uint16_t magic;
35201.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35211.1Skamil	struct ptrace_io_desc io = {
35221.1Skamil		.piod_op = PIOD_READ_I,
35231.1Skamil		.piod_offs = dummy_fn1,
35241.1Skamil		.piod_addr = &lookup_me,
35251.1Skamil		.piod_len = sizeof(lookup_me)
35261.1Skamil	};
35271.1Skamil#if defined(TWAIT_HAVE_STATUS)
35281.1Skamil	int status;
35291.1Skamil#endif
35301.1Skamil
35311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35331.1Skamil	if (child == 0) {
35341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35361.1Skamil
35371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35391.1Skamil
35401.13Schristos		DPRINTF("Before exiting of the child process\n");
35411.1Skamil		_exit(exitval);
35421.1Skamil	}
35431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35441.1Skamil
35451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35471.1Skamil
35481.1Skamil	validate_status_stopped(status, sigval);
35491.1Skamil
35501.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35511.1Skamil	    child, getpid());
35521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
35531.1Skamil
35541.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35551.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
35561.1Skamil
35571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35581.1Skamil	    "without signal to be sent\n");
35591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35601.1Skamil
35611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35631.1Skamil
35641.1Skamil	validate_status_exited(status, exitval);
35651.1Skamil
35661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35681.1Skamil}
35691.1Skamil
35701.1SkamilATF_TC(io_read_i3);
35711.1SkamilATF_TC_HEAD(io_read_i3, tc)
35721.1Skamil{
35731.1Skamil	atf_tc_set_md_var(tc, "descr",
35741.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
35751.1Skamil}
35761.1Skamil
35771.1SkamilATF_TC_BODY(io_read_i3, tc)
35781.1Skamil{
35791.1Skamil	const int exitval = 5;
35801.1Skamil	const int sigval = SIGSTOP;
35811.1Skamil	pid_t child, wpid;
35821.1Skamil	uint32_t lookup_me = 0;
35831.1Skamil	uint32_t magic;
35841.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35851.1Skamil	struct ptrace_io_desc io = {
35861.1Skamil		.piod_op = PIOD_READ_I,
35871.1Skamil		.piod_offs = dummy_fn1,
35881.1Skamil		.piod_addr = &lookup_me,
35891.1Skamil		.piod_len = sizeof(lookup_me)
35901.1Skamil	};
35911.1Skamil#if defined(TWAIT_HAVE_STATUS)
35921.1Skamil	int status;
35931.1Skamil#endif
35941.1Skamil
35951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35971.1Skamil	if (child == 0) {
35981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36001.1Skamil
36011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36031.1Skamil
36041.13Schristos		DPRINTF("Before exiting of the child process\n");
36051.1Skamil		_exit(exitval);
36061.1Skamil	}
36071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36081.1Skamil
36091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36111.1Skamil
36121.1Skamil	validate_status_stopped(status, sigval);
36131.1Skamil
36141.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36151.1Skamil	    child, getpid());
36161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36171.1Skamil
36181.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36191.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
36201.1Skamil
36211.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36221.1Skamil	    "without signal to be sent\n");
36231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36241.1Skamil
36251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36271.1Skamil
36281.1Skamil	validate_status_exited(status, exitval);
36291.1Skamil
36301.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36311.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36321.1Skamil}
36331.1Skamil
36341.1SkamilATF_TC(io_read_i4);
36351.1SkamilATF_TC_HEAD(io_read_i4, tc)
36361.1Skamil{
36371.1Skamil	atf_tc_set_md_var(tc, "descr",
36381.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
36391.1Skamil}
36401.1Skamil
36411.1SkamilATF_TC_BODY(io_read_i4, tc)
36421.1Skamil{
36431.1Skamil	const int exitval = 5;
36441.1Skamil	const int sigval = SIGSTOP;
36451.1Skamil	pid_t child, wpid;
36461.1Skamil	uint64_t lookup_me = 0;
36471.1Skamil	uint64_t magic;
36481.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
36491.1Skamil	struct ptrace_io_desc io = {
36501.1Skamil		.piod_op = PIOD_READ_I,
36511.1Skamil		.piod_offs = dummy_fn1,
36521.1Skamil		.piod_addr = &lookup_me,
36531.1Skamil		.piod_len = sizeof(lookup_me)
36541.1Skamil	};
36551.1Skamil#if defined(TWAIT_HAVE_STATUS)
36561.1Skamil	int status;
36571.1Skamil#endif
36581.1Skamil
36591.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36601.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36611.1Skamil	if (child == 0) {
36621.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36631.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36641.1Skamil
36651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36671.1Skamil
36681.13Schristos		DPRINTF("Before exiting of the child process\n");
36691.1Skamil		_exit(exitval);
36701.1Skamil	}
36711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36721.1Skamil
36731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36751.1Skamil
36761.1Skamil	validate_status_stopped(status, sigval);
36771.1Skamil
36781.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
36791.1Skamil	    child, getpid());
36801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
36811.1Skamil
36821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
36831.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
36841.1Skamil
36851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36861.1Skamil	    "without signal to be sent\n");
36871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36881.1Skamil
36891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36911.1Skamil
36921.1Skamil	validate_status_exited(status, exitval);
36931.1Skamil
36941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36961.1Skamil}
36971.1Skamil
36981.1SkamilATF_TC(read_i1);
36991.1SkamilATF_TC_HEAD(read_i1, tc)
37001.1Skamil{
37011.1Skamil	atf_tc_set_md_var(tc, "descr",
37021.1Skamil	    "Verify PT_READ_I called once");
37031.1Skamil}
37041.1Skamil
37051.1SkamilATF_TC_BODY(read_i1, tc)
37061.1Skamil{
37071.1Skamil	const int exitval = 5;
37081.1Skamil	const int sigval = SIGSTOP;
37091.1Skamil	pid_t child, wpid;
37101.1Skamil	int lookup_me = 0;
37111.1Skamil	int magic;
37121.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
37131.1Skamil#if defined(TWAIT_HAVE_STATUS)
37141.1Skamil	int status;
37151.1Skamil#endif
37161.1Skamil
37171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37191.1Skamil	if (child == 0) {
37201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37221.1Skamil
37231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37251.1Skamil
37261.13Schristos		DPRINTF("Before exiting of the child process\n");
37271.1Skamil		_exit(exitval);
37281.1Skamil	}
37291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37301.1Skamil
37311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37331.1Skamil
37341.1Skamil	validate_status_stopped(status, sigval);
37351.1Skamil
37361.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
37371.1Skamil	    child, getpid());
37381.1Skamil	errno = 0;
37391.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
37401.1Skamil	ATF_REQUIRE_EQ(errno, 0);
37411.1Skamil
37421.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
37431.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
37441.1Skamil
37451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37461.1Skamil	    "without signal to be sent\n");
37471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37481.1Skamil
37491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37511.1Skamil
37521.1Skamil	validate_status_exited(status, exitval);
37531.1Skamil
37541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37561.1Skamil}
37571.1Skamil
37581.1SkamilATF_TC(read_i2);
37591.1SkamilATF_TC_HEAD(read_i2, tc)
37601.1Skamil{
37611.1Skamil	atf_tc_set_md_var(tc, "descr",
37621.1Skamil	    "Verify PT_READ_I called twice");
37631.1Skamil}
37641.1Skamil
37651.1SkamilATF_TC_BODY(read_i2, tc)
37661.1Skamil{
37671.1Skamil	const int exitval = 5;
37681.1Skamil	const int sigval = SIGSTOP;
37691.1Skamil	pid_t child, wpid;
37701.1Skamil	int lookup_me1 = 0;
37711.1Skamil	int lookup_me2 = 0;
37721.1Skamil	int magic1;
37731.1Skamil	int magic2;
37741.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37751.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37761.1Skamil#if defined(TWAIT_HAVE_STATUS)
37771.1Skamil	int status;
37781.1Skamil#endif
37791.1Skamil
37801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37821.1Skamil	if (child == 0) {
37831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37851.1Skamil
37861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37881.1Skamil
37891.13Schristos		DPRINTF("Before exiting of the child process\n");
37901.1Skamil		_exit(exitval);
37911.1Skamil	}
37921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37931.1Skamil
37941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37961.1Skamil
37971.1Skamil	validate_status_stopped(status, sigval);
37981.1Skamil
37991.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38001.1Skamil	    child, getpid());
38011.1Skamil	errno = 0;
38021.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38031.1Skamil	ATF_REQUIRE_EQ(errno, 0);
38041.1Skamil
38051.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38061.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38071.1Skamil
38081.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38091.1Skamil	    child, getpid());
38101.1Skamil	errno = 0;
38111.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38121.1Skamil	ATF_REQUIRE_EQ(errno, 0);
38131.1Skamil
38141.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38151.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38161.1Skamil
38171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38181.1Skamil	    "without signal to be sent\n");
38191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38201.1Skamil
38211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38231.1Skamil
38241.1Skamil	validate_status_exited(status, exitval);
38251.1Skamil
38261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38281.1Skamil}
38291.1Skamil
38301.1SkamilATF_TC(read_i3);
38311.1SkamilATF_TC_HEAD(read_i3, tc)
38321.1Skamil{
38331.1Skamil	atf_tc_set_md_var(tc, "descr",
38341.1Skamil	    "Verify PT_READ_I called three times");
38351.1Skamil}
38361.1Skamil
38371.1SkamilATF_TC_BODY(read_i3, tc)
38381.1Skamil{
38391.1Skamil	const int exitval = 5;
38401.1Skamil	const int sigval = SIGSTOP;
38411.1Skamil	pid_t child, wpid;
38421.1Skamil	int lookup_me1 = 0;
38431.1Skamil	int lookup_me2 = 0;
38441.1Skamil	int lookup_me3 = 0;
38451.1Skamil	int magic1;
38461.1Skamil	int magic2;
38471.1Skamil	int magic3;
38481.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
38491.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
38501.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
38511.1Skamil#if defined(TWAIT_HAVE_STATUS)
38521.1Skamil	int status;
38531.1Skamil#endif
38541.1Skamil
38551.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38561.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38571.1Skamil	if (child == 0) {
38581.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38591.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38601.1Skamil
38611.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38621.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38631.1Skamil
38641.13Schristos		DPRINTF("Before exiting of the child process\n");
38651.1Skamil		_exit(exitval);
38661.1Skamil	}
38671.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38681.1Skamil
38691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38711.1Skamil
38721.1Skamil	validate_status_stopped(status, sigval);
38731.1Skamil
38741.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
38751.1Skamil	    child, getpid());
38761.1Skamil	errno = 0;
38771.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
38781.1Skamil	ATF_REQUIRE_EQ(errno, 0);
38791.1Skamil
38801.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
38811.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
38821.1Skamil
38831.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
38841.1Skamil	    child, getpid());
38851.1Skamil	errno = 0;
38861.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
38871.1Skamil	ATF_REQUIRE_EQ(errno, 0);
38881.1Skamil
38891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
38901.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
38911.1Skamil
38921.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
38931.1Skamil	    child, getpid());
38941.1Skamil	errno = 0;
38951.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
38961.1Skamil	ATF_REQUIRE_EQ(errno, 0);
38971.1Skamil
38981.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
38991.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39001.1Skamil
39011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39021.1Skamil	    "without signal to be sent\n");
39031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39041.1Skamil
39051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39071.1Skamil
39081.1Skamil	validate_status_exited(status, exitval);
39091.1Skamil
39101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39121.1Skamil}
39131.1Skamil
39141.1SkamilATF_TC(read_i4);
39151.1SkamilATF_TC_HEAD(read_i4, tc)
39161.1Skamil{
39171.1Skamil	atf_tc_set_md_var(tc, "descr",
39181.1Skamil	    "Verify PT_READ_I called four times");
39191.1Skamil}
39201.1Skamil
39211.1SkamilATF_TC_BODY(read_i4, tc)
39221.1Skamil{
39231.1Skamil	const int exitval = 5;
39241.1Skamil	const int sigval = SIGSTOP;
39251.1Skamil	pid_t child, wpid;
39261.1Skamil	int lookup_me1 = 0;
39271.1Skamil	int lookup_me2 = 0;
39281.1Skamil	int lookup_me3 = 0;
39291.1Skamil	int lookup_me4 = 0;
39301.1Skamil	int magic1;
39311.1Skamil	int magic2;
39321.1Skamil	int magic3;
39331.1Skamil	int magic4;
39341.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
39351.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
39361.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
39371.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
39381.1Skamil#if defined(TWAIT_HAVE_STATUS)
39391.1Skamil	int status;
39401.1Skamil#endif
39411.1Skamil
39421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39441.1Skamil	if (child == 0) {
39451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39471.1Skamil
39481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39501.1Skamil
39511.13Schristos		DPRINTF("Before exiting of the child process\n");
39521.1Skamil		_exit(exitval);
39531.1Skamil	}
39541.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39551.1Skamil
39561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39581.1Skamil
39591.1Skamil	validate_status_stopped(status, sigval);
39601.1Skamil
39611.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
39621.1Skamil	    child, getpid());
39631.1Skamil	errno = 0;
39641.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
39651.1Skamil	ATF_REQUIRE_EQ(errno, 0);
39661.1Skamil
39671.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
39681.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
39691.1Skamil
39701.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
39711.1Skamil	    child, getpid());
39721.1Skamil	errno = 0;
39731.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
39741.1Skamil	ATF_REQUIRE_EQ(errno, 0);
39751.1Skamil
39761.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
39771.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
39781.1Skamil
39791.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
39801.1Skamil	    child, getpid());
39811.1Skamil	errno = 0;
39821.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
39831.1Skamil	ATF_REQUIRE_EQ(errno, 0);
39841.1Skamil
39851.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
39861.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
39871.1Skamil
39881.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
39891.1Skamil	    child, getpid());
39901.1Skamil	errno = 0;
39911.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
39921.1Skamil	ATF_REQUIRE_EQ(errno, 0);
39931.1Skamil
39941.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
39951.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
39961.1Skamil
39971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39981.1Skamil	    "without signal to be sent\n");
39991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40001.1Skamil
40011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40031.1Skamil
40041.1Skamil	validate_status_exited(status, exitval);
40051.1Skamil
40061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40081.1Skamil}
40091.1Skamil
40101.1Skamil#if defined(HAVE_GPREGS)
40111.1SkamilATF_TC(regs1);
40121.1SkamilATF_TC_HEAD(regs1, tc)
40131.1Skamil{
40141.1Skamil	atf_tc_set_md_var(tc, "descr",
40151.1Skamil	    "Verify plain PT_GETREGS call without further steps");
40161.1Skamil}
40171.1Skamil
40181.1SkamilATF_TC_BODY(regs1, tc)
40191.1Skamil{
40201.1Skamil	const int exitval = 5;
40211.1Skamil	const int sigval = SIGSTOP;
40221.1Skamil	pid_t child, wpid;
40231.1Skamil#if defined(TWAIT_HAVE_STATUS)
40241.1Skamil	int status;
40251.1Skamil#endif
40261.1Skamil	struct reg r;
40271.1Skamil
40281.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40291.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40301.1Skamil	if (child == 0) {
40311.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40321.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40331.1Skamil
40341.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40351.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40361.1Skamil
40371.13Schristos		DPRINTF("Before exiting of the child process\n");
40381.1Skamil		_exit(exitval);
40391.1Skamil	}
40401.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40411.1Skamil
40421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40431.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40441.1Skamil
40451.1Skamil	validate_status_stopped(status, sigval);
40461.1Skamil
40471.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40491.1Skamil
40501.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40511.1Skamil	    "without signal to be sent\n");
40521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40531.1Skamil
40541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40561.1Skamil
40571.1Skamil	validate_status_exited(status, exitval);
40581.1Skamil
40591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40601.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40611.1Skamil}
40621.1Skamil#endif
40631.1Skamil
40641.1Skamil#if defined(HAVE_GPREGS)
40651.1SkamilATF_TC(regs2);
40661.1SkamilATF_TC_HEAD(regs2, tc)
40671.1Skamil{
40681.1Skamil	atf_tc_set_md_var(tc, "descr",
40691.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
40701.1Skamil}
40711.1Skamil
40721.1SkamilATF_TC_BODY(regs2, tc)
40731.1Skamil{
40741.1Skamil	const int exitval = 5;
40751.1Skamil	const int sigval = SIGSTOP;
40761.1Skamil	pid_t child, wpid;
40771.1Skamil#if defined(TWAIT_HAVE_STATUS)
40781.1Skamil	int status;
40791.1Skamil#endif
40801.1Skamil	struct reg r;
40811.1Skamil
40821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40841.1Skamil	if (child == 0) {
40851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40871.1Skamil
40881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40901.1Skamil
40911.13Schristos		DPRINTF("Before exiting of the child process\n");
40921.1Skamil		_exit(exitval);
40931.1Skamil	}
40941.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40951.1Skamil
40961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40981.1Skamil
40991.1Skamil	validate_status_stopped(status, sigval);
41001.1Skamil
41011.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41031.1Skamil
41041.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
41051.1Skamil
41061.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41071.1Skamil	    "without signal to be sent\n");
41081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41091.1Skamil
41101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41121.1Skamil
41131.1Skamil	validate_status_exited(status, exitval);
41141.1Skamil
41151.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41161.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41171.1Skamil}
41181.1Skamil#endif
41191.1Skamil
41201.1Skamil#if defined(HAVE_GPREGS)
41211.1SkamilATF_TC(regs3);
41221.1SkamilATF_TC_HEAD(regs3, tc)
41231.1Skamil{
41241.1Skamil	atf_tc_set_md_var(tc, "descr",
41251.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
41261.1Skamil}
41271.1Skamil
41281.1SkamilATF_TC_BODY(regs3, tc)
41291.1Skamil{
41301.1Skamil	const int exitval = 5;
41311.1Skamil	const int sigval = SIGSTOP;
41321.1Skamil	pid_t child, wpid;
41331.1Skamil#if defined(TWAIT_HAVE_STATUS)
41341.1Skamil	int status;
41351.1Skamil#endif
41361.1Skamil	struct reg r;
41371.1Skamil
41381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41401.1Skamil	if (child == 0) {
41411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41431.1Skamil
41441.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41451.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41461.1Skamil
41471.13Schristos		DPRINTF("Before exiting of the child process\n");
41481.1Skamil		_exit(exitval);
41491.1Skamil	}
41501.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41511.1Skamil
41521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41531.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41541.1Skamil
41551.1Skamil	validate_status_stopped(status, sigval);
41561.1Skamil
41571.13Schristos	DPRINTF("Call GETREGS for the child process\n");
41581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
41591.1Skamil
41601.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
41611.1Skamil
41621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41631.1Skamil	    "without signal to be sent\n");
41641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41651.1Skamil
41661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41681.1Skamil
41691.1Skamil	validate_status_exited(status, exitval);
41701.1Skamil
41711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41721.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41731.1Skamil}
41741.1Skamil#endif
41751.1Skamil
41761.1Skamil#if defined(HAVE_GPREGS)
41771.1SkamilATF_TC(regs4);
41781.1SkamilATF_TC_HEAD(regs4, tc)
41791.1Skamil{
41801.1Skamil	atf_tc_set_md_var(tc, "descr",
41811.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
41821.1Skamil}
41831.1Skamil
41841.1SkamilATF_TC_BODY(regs4, tc)
41851.1Skamil{
41861.1Skamil	const int exitval = 5;
41871.1Skamil	const int sigval = SIGSTOP;
41881.1Skamil	pid_t child, wpid;
41891.1Skamil#if defined(TWAIT_HAVE_STATUS)
41901.1Skamil	int status;
41911.1Skamil#endif
41921.1Skamil	struct reg r;
41931.1Skamil
41941.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41951.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41961.1Skamil	if (child == 0) {
41971.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41981.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41991.1Skamil
42001.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42011.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42021.1Skamil
42031.13Schristos		DPRINTF("Before exiting of the child process\n");
42041.1Skamil		_exit(exitval);
42051.1Skamil	}
42061.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42071.1Skamil
42081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42101.1Skamil
42111.1Skamil	validate_status_stopped(status, sigval);
42121.1Skamil
42131.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42151.1Skamil
42161.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
42171.1Skamil
42181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42191.1Skamil	    "without signal to be sent\n");
42201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42211.1Skamil
42221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42241.1Skamil
42251.1Skamil	validate_status_exited(status, exitval);
42261.1Skamil
42271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42281.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42291.1Skamil}
42301.1Skamil#endif
42311.1Skamil
42321.1Skamil#if defined(HAVE_GPREGS)
42331.1SkamilATF_TC(regs5);
42341.1SkamilATF_TC_HEAD(regs5, tc)
42351.1Skamil{
42361.1Skamil	atf_tc_set_md_var(tc, "descr",
42371.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
42381.1Skamil}
42391.1Skamil
42401.1SkamilATF_TC_BODY(regs5, tc)
42411.1Skamil{
42421.1Skamil	const int exitval = 5;
42431.1Skamil	const int sigval = SIGSTOP;
42441.1Skamil	pid_t child, wpid;
42451.1Skamil#if defined(TWAIT_HAVE_STATUS)
42461.1Skamil	int status;
42471.1Skamil#endif
42481.1Skamil	struct reg r;
42491.1Skamil
42501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42521.1Skamil	if (child == 0) {
42531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42551.1Skamil
42561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42581.1Skamil
42591.13Schristos		DPRINTF("Before exiting of the child process\n");
42601.1Skamil		_exit(exitval);
42611.1Skamil	}
42621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42631.1Skamil
42641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42661.1Skamil
42671.1Skamil	validate_status_stopped(status, sigval);
42681.1Skamil
42691.13Schristos	DPRINTF("Call GETREGS for the child process\n");
42701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42711.1Skamil
42721.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
42731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
42741.1Skamil
42751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42761.1Skamil	    "without signal to be sent\n");
42771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42781.1Skamil
42791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42811.1Skamil
42821.1Skamil	validate_status_exited(status, exitval);
42831.1Skamil
42841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42861.1Skamil}
42871.1Skamil#endif
42881.1Skamil
42891.1Skamil#if defined(HAVE_FPREGS)
42901.1SkamilATF_TC(fpregs1);
42911.1SkamilATF_TC_HEAD(fpregs1, tc)
42921.1Skamil{
42931.1Skamil	atf_tc_set_md_var(tc, "descr",
42941.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
42951.1Skamil}
42961.1Skamil
42971.1SkamilATF_TC_BODY(fpregs1, tc)
42981.1Skamil{
42991.1Skamil	const int exitval = 5;
43001.1Skamil	const int sigval = SIGSTOP;
43011.1Skamil	pid_t child, wpid;
43021.1Skamil#if defined(TWAIT_HAVE_STATUS)
43031.1Skamil	int status;
43041.1Skamil#endif
43051.1Skamil	struct fpreg r;
43061.1Skamil
43071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43091.1Skamil	if (child == 0) {
43101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43121.1Skamil
43131.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43141.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43151.1Skamil
43161.13Schristos		DPRINTF("Before exiting of the child process\n");
43171.1Skamil		_exit(exitval);
43181.1Skamil	}
43191.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43201.1Skamil
43211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43231.1Skamil
43241.1Skamil	validate_status_stopped(status, sigval);
43251.1Skamil
43261.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43281.1Skamil
43291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43301.1Skamil	    "without signal to be sent\n");
43311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43321.1Skamil
43331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43351.1Skamil
43361.1Skamil	validate_status_exited(status, exitval);
43371.1Skamil
43381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43401.1Skamil}
43411.1Skamil#endif
43421.1Skamil
43431.1Skamil#if defined(HAVE_FPREGS)
43441.1SkamilATF_TC(fpregs2);
43451.1SkamilATF_TC_HEAD(fpregs2, tc)
43461.1Skamil{
43471.1Skamil	atf_tc_set_md_var(tc, "descr",
43481.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
43491.1Skamil	    "regs");
43501.1Skamil}
43511.1Skamil
43521.1SkamilATF_TC_BODY(fpregs2, tc)
43531.1Skamil{
43541.1Skamil	const int exitval = 5;
43551.1Skamil	const int sigval = SIGSTOP;
43561.1Skamil	pid_t child, wpid;
43571.1Skamil#if defined(TWAIT_HAVE_STATUS)
43581.1Skamil	int status;
43591.1Skamil#endif
43601.1Skamil	struct fpreg r;
43611.1Skamil
43621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
43631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
43641.1Skamil	if (child == 0) {
43651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
43661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
43671.1Skamil
43681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
43691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
43701.1Skamil
43711.13Schristos		DPRINTF("Before exiting of the child process\n");
43721.1Skamil		_exit(exitval);
43731.1Skamil	}
43741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
43751.1Skamil
43761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43781.1Skamil
43791.1Skamil	validate_status_stopped(status, sigval);
43801.1Skamil
43811.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
43821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
43831.1Skamil
43841.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
43851.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
43861.1Skamil
43871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
43881.1Skamil	    "without signal to be sent\n");
43891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
43901.1Skamil
43911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
43931.1Skamil
43941.1Skamil	validate_status_exited(status, exitval);
43951.1Skamil
43961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
43971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
43981.1Skamil}
43991.1Skamil#endif
44001.1Skamil
44011.1Skamil#if defined(PT_STEP)
44021.1Skamilstatic void
44031.2Skamilptrace_step(int N, int setstep)
44041.1Skamil{
44051.1Skamil	const int exitval = 5;
44061.1Skamil	const int sigval = SIGSTOP;
44071.1Skamil	pid_t child, wpid;
44081.1Skamil#if defined(TWAIT_HAVE_STATUS)
44091.1Skamil	int status;
44101.1Skamil#endif
44111.1Skamil	int happy;
44121.1Skamil
44131.1Skamil#if defined(__arm__)
44141.1Skamil	/* PT_STEP not supported on arm 32-bit */
44151.1Skamil	atf_tc_expect_fail("PR kern/52119");
44161.1Skamil#endif
44171.1Skamil
44181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44201.1Skamil	if (child == 0) {
44211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44231.1Skamil
44241.1Skamil		happy = check_happy(999);
44251.1Skamil
44261.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44271.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44281.1Skamil
44291.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
44301.1Skamil
44311.13Schristos		DPRINTF("Before exiting of the child process\n");
44321.1Skamil		_exit(exitval);
44331.1Skamil	}
44341.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44351.1Skamil
44361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44381.1Skamil
44391.1Skamil	validate_status_stopped(status, sigval);
44401.1Skamil
44411.1Skamil	while (N --> 0) {
44421.2Skamil		if (setstep) {
44431.13Schristos			DPRINTF("Before resuming the child process where it "
44441.2Skamil			    "left off and without signal to be sent (use "
44451.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
44461.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
44471.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
44481.2Skamil			    != -1);
44491.2Skamil		} else {
44501.13Schristos			DPRINTF("Before resuming the child process where it "
44511.2Skamil			    "left off and without signal to be sent (use "
44521.2Skamil			    "PT_STEP)\n");
44531.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
44541.2Skamil			    != -1);
44551.2Skamil		}
44561.1Skamil
44571.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44581.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
44591.1Skamil		    child);
44601.1Skamil
44611.1Skamil		validate_status_stopped(status, SIGTRAP);
44621.2Skamil
44631.2Skamil		if (setstep) {
44641.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
44651.2Skamil		}
44661.1Skamil	}
44671.1Skamil
44681.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44691.1Skamil	    "without signal to be sent\n");
44701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
44711.1Skamil
44721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44741.1Skamil
44751.1Skamil	validate_status_exited(status, exitval);
44761.1Skamil
44771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44791.1Skamil}
44801.1Skamil#endif
44811.1Skamil
44821.1Skamil#if defined(PT_STEP)
44831.1SkamilATF_TC(step1);
44841.1SkamilATF_TC_HEAD(step1, tc)
44851.1Skamil{
44861.1Skamil	atf_tc_set_md_var(tc, "descr",
44871.1Skamil	    "Verify single PT_STEP call");
44881.1Skamil}
44891.1Skamil
44901.1SkamilATF_TC_BODY(step1, tc)
44911.1Skamil{
44921.2Skamil	ptrace_step(1, 0);
44931.1Skamil}
44941.1Skamil#endif
44951.1Skamil
44961.1Skamil#if defined(PT_STEP)
44971.1SkamilATF_TC(step2);
44981.1SkamilATF_TC_HEAD(step2, tc)
44991.1Skamil{
45001.1Skamil	atf_tc_set_md_var(tc, "descr",
45011.1Skamil	    "Verify PT_STEP called twice");
45021.1Skamil}
45031.1Skamil
45041.1SkamilATF_TC_BODY(step2, tc)
45051.1Skamil{
45061.2Skamil	ptrace_step(2, 0);
45071.1Skamil}
45081.1Skamil#endif
45091.1Skamil
45101.1Skamil#if defined(PT_STEP)
45111.1SkamilATF_TC(step3);
45121.1SkamilATF_TC_HEAD(step3, tc)
45131.1Skamil{
45141.1Skamil	atf_tc_set_md_var(tc, "descr",
45151.1Skamil	    "Verify PT_STEP called three times");
45161.1Skamil}
45171.1Skamil
45181.1SkamilATF_TC_BODY(step3, tc)
45191.1Skamil{
45201.2Skamil	ptrace_step(3, 0);
45211.1Skamil}
45221.1Skamil#endif
45231.1Skamil
45241.1Skamil#if defined(PT_STEP)
45251.1SkamilATF_TC(step4);
45261.1SkamilATF_TC_HEAD(step4, tc)
45271.1Skamil{
45281.1Skamil	atf_tc_set_md_var(tc, "descr",
45291.1Skamil	    "Verify PT_STEP called four times");
45301.1Skamil}
45311.1Skamil
45321.1SkamilATF_TC_BODY(step4, tc)
45331.1Skamil{
45341.2Skamil	ptrace_step(4, 0);
45351.2Skamil}
45361.2Skamil#endif
45371.2Skamil
45381.2Skamil#if defined(PT_STEP)
45391.2SkamilATF_TC(setstep1);
45401.2SkamilATF_TC_HEAD(setstep1, tc)
45411.2Skamil{
45421.2Skamil	atf_tc_set_md_var(tc, "descr",
45431.2Skamil	    "Verify single PT_SETSTEP call");
45441.2Skamil}
45451.2Skamil
45461.2SkamilATF_TC_BODY(setstep1, tc)
45471.2Skamil{
45481.2Skamil	ptrace_step(1, 1);
45491.2Skamil}
45501.2Skamil#endif
45511.2Skamil
45521.2Skamil#if defined(PT_STEP)
45531.2SkamilATF_TC(setstep2);
45541.2SkamilATF_TC_HEAD(setstep2, tc)
45551.2Skamil{
45561.2Skamil	atf_tc_set_md_var(tc, "descr",
45571.2Skamil	    "Verify PT_SETSTEP called twice");
45581.2Skamil}
45591.2Skamil
45601.2SkamilATF_TC_BODY(setstep2, tc)
45611.2Skamil{
45621.2Skamil	ptrace_step(2, 1);
45631.2Skamil}
45641.2Skamil#endif
45651.2Skamil
45661.2Skamil#if defined(PT_STEP)
45671.2SkamilATF_TC(setstep3);
45681.2SkamilATF_TC_HEAD(setstep3, tc)
45691.2Skamil{
45701.2Skamil	atf_tc_set_md_var(tc, "descr",
45711.2Skamil	    "Verify PT_SETSTEP called three times");
45721.2Skamil}
45731.2Skamil
45741.2SkamilATF_TC_BODY(setstep3, tc)
45751.2Skamil{
45761.2Skamil	ptrace_step(3, 1);
45771.2Skamil}
45781.2Skamil#endif
45791.2Skamil
45801.2Skamil#if defined(PT_STEP)
45811.2SkamilATF_TC(setstep4);
45821.2SkamilATF_TC_HEAD(setstep4, tc)
45831.2Skamil{
45841.2Skamil	atf_tc_set_md_var(tc, "descr",
45851.2Skamil	    "Verify PT_SETSTEP called four times");
45861.2Skamil}
45871.2Skamil
45881.2SkamilATF_TC_BODY(setstep4, tc)
45891.2Skamil{
45901.2Skamil	ptrace_step(4, 1);
45911.1Skamil}
45921.1Skamil#endif
45931.1Skamil
45941.1SkamilATF_TC(kill1);
45951.1SkamilATF_TC_HEAD(kill1, tc)
45961.1Skamil{
45971.1Skamil	atf_tc_set_md_var(tc, "descr",
45981.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
45991.1Skamil}
46001.1Skamil
46011.1SkamilATF_TC_BODY(kill1, tc)
46021.1Skamil{
46031.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
46041.1Skamil	pid_t child, wpid;
46051.1Skamil#if defined(TWAIT_HAVE_STATUS)
46061.1Skamil	int status;
46071.1Skamil#endif
46081.1Skamil
46091.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46101.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46111.1Skamil	if (child == 0) {
46121.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46131.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46141.1Skamil
46151.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46161.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46171.1Skamil
46181.1Skamil		/* NOTREACHED */
46191.1Skamil		FORKEE_ASSERTX(0 &&
46201.1Skamil		    "Child should be terminated by a signal from its parent");
46211.1Skamil	}
46221.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46231.1Skamil
46241.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46261.1Skamil
46271.1Skamil	validate_status_stopped(status, sigval);
46281.1Skamil
46291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46301.1Skamil	    "without signal to be sent\n");
46311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
46321.1Skamil
46331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46351.1Skamil
46361.1Skamil	validate_status_signaled(status, sigsent, 0);
46371.1Skamil
46381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46401.1Skamil}
46411.1Skamil
46421.1SkamilATF_TC(kill2);
46431.1SkamilATF_TC_HEAD(kill2, tc)
46441.1Skamil{
46451.1Skamil	atf_tc_set_md_var(tc, "descr",
46461.1Skamil	    "Verify that PT_KILL terminates child");
46471.1Skamil}
46481.1Skamil
46491.1SkamilATF_TC_BODY(kill2, tc)
46501.1Skamil{
46511.1Skamil	const int sigval = SIGSTOP;
46521.1Skamil	pid_t child, wpid;
46531.1Skamil#if defined(TWAIT_HAVE_STATUS)
46541.1Skamil	int status;
46551.1Skamil#endif
46561.1Skamil
46571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46591.1Skamil	if (child == 0) {
46601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46621.1Skamil
46631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46651.1Skamil
46661.1Skamil		/* NOTREACHED */
46671.1Skamil		FORKEE_ASSERTX(0 &&
46681.1Skamil		    "Child should be terminated by a signal from its parent");
46691.1Skamil	}
46701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
46711.1Skamil
46721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46741.1Skamil
46751.1Skamil	validate_status_stopped(status, sigval);
46761.1Skamil
46771.13Schristos	DPRINTF("Before resuming the child process where it left off and "
46781.1Skamil	    "without signal to be sent\n");
46791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
46801.1Skamil
46811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
46831.1Skamil
46841.1Skamil	validate_status_signaled(status, SIGKILL, 0);
46851.1Skamil
46861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
46871.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
46881.1Skamil}
46891.1Skamil
46901.1SkamilATF_TC(lwpinfo1);
46911.1SkamilATF_TC_HEAD(lwpinfo1, tc)
46921.1Skamil{
46931.1Skamil	atf_tc_set_md_var(tc, "descr",
46941.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
46951.1Skamil}
46961.1Skamil
46971.1SkamilATF_TC_BODY(lwpinfo1, tc)
46981.1Skamil{
46991.1Skamil	const int exitval = 5;
47001.1Skamil	const int sigval = SIGSTOP;
47011.1Skamil	pid_t child, wpid;
47021.1Skamil#if defined(TWAIT_HAVE_STATUS)
47031.1Skamil	int status;
47041.1Skamil#endif
47051.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47061.1Skamil
47071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47091.1Skamil	if (child == 0) {
47101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47121.1Skamil
47131.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47141.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47151.1Skamil
47161.13Schristos		DPRINTF("Before exiting of the child process\n");
47171.1Skamil		_exit(exitval);
47181.1Skamil	}
47191.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47201.1Skamil
47211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47231.1Skamil
47241.1Skamil	validate_status_stopped(status, sigval);
47251.1Skamil
47261.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47281.1Skamil
47291.13Schristos	DPRINTF("Assert that there exists a thread\n");
47301.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
47311.1Skamil
47321.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
47331.1Skamil	    info.pl_lwpid);
47341.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
47351.1Skamil	    "Received event %d != expected event %d",
47361.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
47371.1Skamil
47381.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
47391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
47401.1Skamil
47411.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
47421.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
47431.1Skamil
47441.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47451.1Skamil	    "without signal to be sent\n");
47461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
47471.1Skamil
47481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47491.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47501.1Skamil
47511.1Skamil	validate_status_exited(status, exitval);
47521.1Skamil
47531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47541.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47551.1Skamil}
47561.1Skamil
47571.1Skamil#if defined(TWAIT_HAVE_PID)
47581.1SkamilATF_TC(lwpinfo2);
47591.1SkamilATF_TC_HEAD(lwpinfo2, tc)
47601.1Skamil{
47611.1Skamil	atf_tc_set_md_var(tc, "descr",
47621.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
47631.1Skamil	    "tracer)");
47641.1Skamil}
47651.1Skamil
47661.1SkamilATF_TC_BODY(lwpinfo2, tc)
47671.1Skamil{
47681.1Skamil	struct msg_fds parent_tracee, parent_tracer;
47691.1Skamil	const int exitval_tracee = 5;
47701.1Skamil	const int exitval_tracer = 10;
47711.1Skamil	pid_t tracee, tracer, wpid;
47721.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
47731.1Skamil#if defined(TWAIT_HAVE_STATUS)
47741.1Skamil	int status;
47751.1Skamil#endif
47761.1Skamil	struct ptrace_lwpinfo info = {0, 0};
47771.1Skamil
47781.13Schristos	DPRINTF("Spawn tracee\n");
47791.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
47801.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
47811.1Skamil	tracee = atf_utils_fork();
47821.1Skamil	if (tracee == 0) {
47831.1Skamil
47841.1Skamil		/* Wait for message from the parent */
47851.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
47861.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
47871.1Skamil
47881.1Skamil		_exit(exitval_tracee);
47891.1Skamil	}
47901.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
47911.1Skamil
47921.13Schristos	DPRINTF("Spawn debugger\n");
47931.1Skamil	tracer = atf_utils_fork();
47941.1Skamil	if (tracer == 0) {
47951.1Skamil		/* No IPC to communicate with the child */
47961.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
47971.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
47981.1Skamil
47991.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
48001.1Skamil		FORKEE_REQUIRE_SUCCESS(
48011.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48021.1Skamil
48031.1Skamil		forkee_status_stopped(status, SIGSTOP);
48041.1Skamil
48051.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48061.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48071.1Skamil		    != -1);
48081.1Skamil
48091.13Schristos		DPRINTF("Assert that there exists a thread\n");
48101.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
48111.1Skamil
48121.13Schristos		DPRINTF("Assert that lwp thread %d received event "
48131.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
48141.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
48151.1Skamil
48161.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
48171.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
48181.1Skamil		    != -1);
48191.1Skamil
48201.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
48211.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
48221.1Skamil
48231.1Skamil		/* Resume tracee with PT_CONTINUE */
48241.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
48251.1Skamil
48261.1Skamil		/* Inform parent that tracer has attached to tracee */
48271.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
48281.1Skamil		/* Wait for parent */
48291.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
48301.1Skamil
48311.1Skamil		/* Wait for tracee and assert that it exited */
48321.1Skamil		FORKEE_REQUIRE_SUCCESS(
48331.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
48341.1Skamil
48351.1Skamil		forkee_status_exited(status, exitval_tracee);
48361.1Skamil
48371.13Schristos		DPRINTF("Before exiting of the tracer process\n");
48381.1Skamil		_exit(exitval_tracer);
48391.1Skamil	}
48401.1Skamil
48411.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
48421.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
48431.1Skamil
48441.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
48451.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
48461.1Skamil
48471.13Schristos	DPRINTF("Detect that tracee is zombie\n");
48481.1Skamil	await_zombie(tracee);
48491.1Skamil
48501.13Schristos	DPRINTF("Assert that there is no status about tracee - "
48511.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
48521.1Skamil	TWAIT_REQUIRE_SUCCESS(
48531.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
48541.1Skamil
48551.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
48561.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
48571.1Skamil
48581.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
48591.1Skamil	    TWAIT_FNAME);
48601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
48611.1Skamil	    tracer);
48621.1Skamil
48631.1Skamil	validate_status_exited(status, exitval_tracer);
48641.1Skamil
48651.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
48661.1Skamil	    TWAIT_FNAME);
48671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
48681.1Skamil	    tracee);
48691.1Skamil
48701.1Skamil	validate_status_exited(status, exitval_tracee);
48711.1Skamil
48721.1Skamil	msg_close(&parent_tracer);
48731.1Skamil	msg_close(&parent_tracee);
48741.1Skamil}
48751.1Skamil#endif
48761.1Skamil
48771.1SkamilATF_TC(siginfo1);
48781.1SkamilATF_TC_HEAD(siginfo1, tc)
48791.1Skamil{
48801.1Skamil	atf_tc_set_md_var(tc, "descr",
48811.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
48821.1Skamil}
48831.1Skamil
48841.1SkamilATF_TC_BODY(siginfo1, tc)
48851.1Skamil{
48861.1Skamil	const int exitval = 5;
48871.1Skamil	const int sigval = SIGTRAP;
48881.1Skamil	pid_t child, wpid;
48891.1Skamil#if defined(TWAIT_HAVE_STATUS)
48901.1Skamil	int status;
48911.1Skamil#endif
48921.1Skamil	struct ptrace_siginfo info;
48931.1Skamil	memset(&info, 0, sizeof(info));
48941.1Skamil
48951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48971.1Skamil	if (child == 0) {
48981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49001.1Skamil
49011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49031.1Skamil
49041.13Schristos		DPRINTF("Before exiting of the child process\n");
49051.1Skamil		_exit(exitval);
49061.1Skamil	}
49071.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49081.1Skamil
49091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49111.1Skamil
49121.1Skamil	validate_status_stopped(status, sigval);
49131.1Skamil
49141.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49161.1Skamil
49171.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49181.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49191.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49201.1Skamil	    info.psi_siginfo.si_errno);
49211.1Skamil
49221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49231.1Skamil	    "without signal to be sent\n");
49241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49251.1Skamil
49261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49281.1Skamil
49291.1Skamil	validate_status_exited(status, exitval);
49301.1Skamil
49311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49331.1Skamil}
49341.1Skamil
49351.1SkamilATF_TC(siginfo2);
49361.1SkamilATF_TC_HEAD(siginfo2, tc)
49371.1Skamil{
49381.1Skamil	atf_tc_set_md_var(tc, "descr",
49391.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
49401.1Skamil	    "modification of SIGINT from tracee");
49411.1Skamil}
49421.1Skamil
49431.1Skamilstatic int siginfo2_caught = 0;
49441.1Skamil
49451.1Skamilstatic void
49461.1Skamilsiginfo2_sighandler(int sig)
49471.1Skamil{
49481.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
49491.1Skamil
49501.1Skamil	++siginfo2_caught;
49511.1Skamil}
49521.1Skamil
49531.1SkamilATF_TC_BODY(siginfo2, tc)
49541.1Skamil{
49551.1Skamil	const int exitval = 5;
49561.1Skamil	const int sigval = SIGINT;
49571.1Skamil	pid_t child, wpid;
49581.1Skamil	struct sigaction sa;
49591.1Skamil#if defined(TWAIT_HAVE_STATUS)
49601.1Skamil	int status;
49611.1Skamil#endif
49621.1Skamil	struct ptrace_siginfo info;
49631.1Skamil	memset(&info, 0, sizeof(info));
49641.1Skamil
49651.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49661.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49671.1Skamil	if (child == 0) {
49681.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49691.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49701.1Skamil
49711.1Skamil		sa.sa_handler = siginfo2_sighandler;
49721.1Skamil		sa.sa_flags = SA_SIGINFO;
49731.1Skamil		sigemptyset(&sa.sa_mask);
49741.1Skamil
49751.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
49761.1Skamil
49771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
49781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
49791.1Skamil
49801.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
49811.1Skamil
49821.13Schristos		DPRINTF("Before exiting of the child process\n");
49831.1Skamil		_exit(exitval);
49841.1Skamil	}
49851.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49861.1Skamil
49871.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49881.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49891.1Skamil
49901.1Skamil	validate_status_stopped(status, sigval);
49911.1Skamil
49921.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49941.1Skamil
49951.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49961.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49971.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49981.1Skamil	    info.psi_siginfo.si_errno);
49991.1Skamil
50001.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50021.1Skamil
50031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50041.1Skamil	    "without signal to be sent\n");
50051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
50061.1Skamil
50071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50091.1Skamil
50101.1Skamil	validate_status_exited(status, exitval);
50111.1Skamil
50121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
50141.1Skamil}
50151.1Skamil
50161.1SkamilATF_TC(siginfo3);
50171.1SkamilATF_TC_HEAD(siginfo3, tc)
50181.1Skamil{
50191.1Skamil	atf_tc_set_md_var(tc, "descr",
50201.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
50211.1Skamil	    "setting signal to new value");
50221.1Skamil}
50231.1Skamil
50241.1Skamilstatic int siginfo3_caught = 0;
50251.1Skamil
50261.1Skamilstatic void
50271.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
50281.1Skamil{
50291.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
50301.1Skamil
50311.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
50321.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
50331.1Skamil
50341.1Skamil	++siginfo3_caught;
50351.1Skamil}
50361.1Skamil
50371.1SkamilATF_TC_BODY(siginfo3, tc)
50381.1Skamil{
50391.1Skamil	const int exitval = 5;
50401.1Skamil	const int sigval = SIGINT;
50411.1Skamil	const int sigfaked = SIGTRAP;
50421.1Skamil	const int sicodefaked = TRAP_BRKPT;
50431.1Skamil	pid_t child, wpid;
50441.1Skamil	struct sigaction sa;
50451.1Skamil#if defined(TWAIT_HAVE_STATUS)
50461.1Skamil	int status;
50471.1Skamil#endif
50481.1Skamil	struct ptrace_siginfo info;
50491.1Skamil	memset(&info, 0, sizeof(info));
50501.1Skamil
50511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
50521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
50531.1Skamil	if (child == 0) {
50541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
50551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
50561.1Skamil
50571.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
50581.1Skamil		sa.sa_flags = SA_SIGINFO;
50591.1Skamil		sigemptyset(&sa.sa_mask);
50601.1Skamil
50611.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
50621.1Skamil
50631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50651.1Skamil
50661.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
50671.1Skamil
50681.13Schristos		DPRINTF("Before exiting of the child process\n");
50691.1Skamil		_exit(exitval);
50701.1Skamil	}
50711.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50721.1Skamil
50731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50751.1Skamil
50761.1Skamil	validate_status_stopped(status, sigval);
50771.1Skamil
50781.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50801.1Skamil
50811.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
50821.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
50831.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
50841.1Skamil	    info.psi_siginfo.si_errno);
50851.1Skamil
50861.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
50871.1Skamil	    sigfaked, sicodefaked);
50881.1Skamil	info.psi_siginfo.si_signo = sigfaked;
50891.1Skamil	info.psi_siginfo.si_code = sicodefaked;
50901.1Skamil
50911.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
50921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
50931.1Skamil
50941.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50961.1Skamil
50971.13Schristos	DPRINTF("Before checking siginfo_t\n");
50981.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
50991.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
51001.1Skamil
51011.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51021.1Skamil	    "without signal to be sent\n");
51031.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
51041.1Skamil
51051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51071.1Skamil
51081.1Skamil	validate_status_exited(status, exitval);
51091.1Skamil
51101.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51111.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51121.1Skamil}
51131.1Skamil
51141.1SkamilATF_TC(siginfo4);
51151.1SkamilATF_TC_HEAD(siginfo4, tc)
51161.1Skamil{
51171.1Skamil	atf_tc_set_md_var(tc, "descr",
51181.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
51191.1Skamil}
51201.1Skamil
51211.1SkamilATF_TC_BODY(siginfo4, tc)
51221.1Skamil{
51231.1Skamil	const int sigval = SIGTRAP;
51241.1Skamil	pid_t child, wpid;
51251.1Skamil#if defined(TWAIT_HAVE_STATUS)
51261.1Skamil	int status;
51271.1Skamil#endif
51281.1Skamil
51291.1Skamil	struct ptrace_siginfo info;
51301.1Skamil	memset(&info, 0, sizeof(info));
51311.1Skamil
51321.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51331.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51341.1Skamil	if (child == 0) {
51351.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51361.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51371.1Skamil
51381.13Schristos		DPRINTF("Before calling execve(2) from child\n");
51391.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
51401.1Skamil
51411.1Skamil		FORKEE_ASSERT(0 && "Not reached");
51421.1Skamil	}
51431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51441.1Skamil
51451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51471.1Skamil
51481.1Skamil	validate_status_stopped(status, sigval);
51491.1Skamil
51501.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51521.1Skamil
51531.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
51541.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
51551.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
51561.1Skamil	    info.psi_siginfo.si_errno);
51571.1Skamil
51581.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51591.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
51601.1Skamil
51611.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51621.1Skamil	    "without signal to be sent\n");
51631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51641.1Skamil
51651.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51671.1Skamil
51681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51701.1Skamil}
51711.1Skamil
51721.1Skamil#if defined(TWAIT_HAVE_PID)
51731.1SkamilATF_TC(siginfo5);
51741.1SkamilATF_TC_HEAD(siginfo5, tc)
51751.1Skamil{
51761.1Skamil	atf_tc_set_md_var(tc, "descr",
51771.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
51781.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
51791.1Skamil}
51801.1Skamil
51811.1SkamilATF_TC_BODY(siginfo5, tc)
51821.1Skamil{
51831.1Skamil	const int exitval = 5;
51841.1Skamil	const int exitval2 = 15;
51851.1Skamil	const int sigval = SIGSTOP;
51861.1Skamil	pid_t child, child2, wpid;
51871.1Skamil#if defined(TWAIT_HAVE_STATUS)
51881.1Skamil	int status;
51891.1Skamil#endif
51901.1Skamil	ptrace_state_t state;
51911.1Skamil	const int slen = sizeof(state);
51921.1Skamil	ptrace_event_t event;
51931.1Skamil	const int elen = sizeof(event);
51941.1Skamil	struct ptrace_siginfo info;
51951.1Skamil
51961.1Skamil	memset(&info, 0, sizeof(info));
51971.1Skamil
51981.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51991.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52001.1Skamil	if (child == 0) {
52011.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52021.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52031.1Skamil
52041.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52051.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52061.1Skamil
52071.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
52081.1Skamil
52091.1Skamil		if (child2 == 0)
52101.1Skamil			_exit(exitval2);
52111.1Skamil
52121.1Skamil		FORKEE_REQUIRE_SUCCESS
52131.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
52141.1Skamil
52151.1Skamil		forkee_status_exited(status, exitval2);
52161.1Skamil
52171.13Schristos		DPRINTF("Before exiting of the child process\n");
52181.1Skamil		_exit(exitval);
52191.1Skamil	}
52201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52211.1Skamil
52221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52241.1Skamil
52251.1Skamil	validate_status_stopped(status, sigval);
52261.1Skamil
52271.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52291.1Skamil
52301.13Schristos	DPRINTF("Before checking siginfo_t\n");
52311.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
52321.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
52331.1Skamil
52341.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
52351.1Skamil	event.pe_set_event = PTRACE_FORK;
52361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52371.1Skamil
52381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52391.1Skamil	    "without signal to be sent\n");
52401.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
52411.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
52421.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
52431.1Skamil                "state.pe_other_pid=child)\n", child);
52441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52451.1Skamil
52461.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
52471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52481.1Skamil
52491.1Skamil	validate_status_stopped(status, SIGTRAP);
52501.1Skamil
52511.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52521.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52531.1Skamil
52541.13Schristos	DPRINTF("Before checking siginfo_t\n");
52551.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52561.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52571.1Skamil
52581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52591.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52601.1Skamil
52611.1Skamil	child2 = state.pe_other_pid;
52621.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
52631.1Skamil
52641.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
52651.1Skamil	    TWAIT_FNAME, child2, child);
52661.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52671.1Skamil	    child2);
52681.1Skamil
52691.1Skamil	validate_status_stopped(status, SIGTRAP);
52701.1Skamil
52711.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
52721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
52731.1Skamil
52741.13Schristos	DPRINTF("Before checking siginfo_t\n");
52751.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
52761.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
52771.1Skamil
52781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
52791.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
52801.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
52811.1Skamil
52821.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
52831.1Skamil	    "without signal to be sent\n");
52841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
52851.1Skamil
52861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52871.1Skamil	    "without signal to be sent\n");
52881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52891.1Skamil
52901.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
52911.1Skamil	    TWAIT_FNAME);
52921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
52931.1Skamil	    child2);
52941.1Skamil
52951.1Skamil	validate_status_exited(status, exitval2);
52961.1Skamil
52971.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
52981.1Skamil	    TWAIT_FNAME);
52991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
53001.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
53011.1Skamil
53021.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53031.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
53041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53051.1Skamil
53061.1Skamil	validate_status_stopped(status, SIGCHLD);
53071.1Skamil
53081.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53101.1Skamil
53111.13Schristos	DPRINTF("Before checking siginfo_t\n");
53121.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
53131.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
53141.1Skamil
53151.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53161.1Skamil	    "without signal to be sent\n");
53171.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53181.1Skamil
53191.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53201.1Skamil	    TWAIT_FNAME);
53211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53221.1Skamil
53231.1Skamil	validate_status_exited(status, exitval);
53241.1Skamil
53251.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53261.1Skamil	    TWAIT_FNAME);
53271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53281.1Skamil}
53291.1Skamil#endif
53301.1Skamil
53311.1Skamil#if defined(PT_STEP)
53321.1SkamilATF_TC(siginfo6);
53331.1SkamilATF_TC_HEAD(siginfo6, tc)
53341.1Skamil{
53351.1Skamil	atf_tc_set_md_var(tc, "descr",
53361.1Skamil	    "Verify single PT_STEP call with signal information check");
53371.1Skamil}
53381.1Skamil
53391.1SkamilATF_TC_BODY(siginfo6, tc)
53401.1Skamil{
53411.1Skamil	const int exitval = 5;
53421.1Skamil	const int sigval = SIGSTOP;
53431.1Skamil	pid_t child, wpid;
53441.1Skamil#if defined(TWAIT_HAVE_STATUS)
53451.1Skamil	int status;
53461.1Skamil#endif
53471.1Skamil	int happy;
53481.1Skamil	struct ptrace_siginfo info;
53491.1Skamil
53501.1Skamil#if defined(__arm__)
53511.1Skamil	/* PT_STEP not supported on arm 32-bit */
53521.1Skamil	atf_tc_expect_fail("PR kern/52119");
53531.1Skamil#endif
53541.1Skamil
53551.1Skamil	memset(&info, 0, sizeof(info));
53561.1Skamil
53571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53591.1Skamil	if (child == 0) {
53601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53621.1Skamil
53631.1Skamil		happy = check_happy(100);
53641.1Skamil
53651.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53661.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53671.1Skamil
53681.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
53691.1Skamil
53701.13Schristos		DPRINTF("Before exiting of the child process\n");
53711.1Skamil		_exit(exitval);
53721.1Skamil	}
53731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53741.1Skamil
53751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53771.1Skamil
53781.1Skamil	validate_status_stopped(status, sigval);
53791.1Skamil
53801.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53821.1Skamil
53831.13Schristos	DPRINTF("Before checking siginfo_t\n");
53841.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
53851.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
53861.1Skamil
53871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53881.1Skamil	    "without signal to be sent (use PT_STEP)\n");
53891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
53901.1Skamil
53911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53931.1Skamil
53941.1Skamil	validate_status_stopped(status, SIGTRAP);
53951.1Skamil
53961.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
53971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
53981.1Skamil
53991.13Schristos	DPRINTF("Before checking siginfo_t\n");
54001.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
54011.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
54021.1Skamil
54031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54041.1Skamil	    "without signal to be sent\n");
54051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54061.1Skamil
54071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54091.1Skamil
54101.1Skamil	validate_status_exited(status, exitval);
54111.1Skamil
54121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54131.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54141.1Skamil}
54151.1Skamil#endif
54161.1Skamil
54171.1Skamilvolatile lwpid_t the_lwp_id = 0;
54181.1Skamil
54191.1Skamilstatic void
54201.1Skamillwp_main_func(void *arg)
54211.1Skamil{
54221.1Skamil	the_lwp_id = _lwp_self();
54231.1Skamil	_lwp_exit();
54241.1Skamil}
54251.1Skamil
54261.1SkamilATF_TC(lwp_create1);
54271.1SkamilATF_TC_HEAD(lwp_create1, tc)
54281.1Skamil{
54291.1Skamil	atf_tc_set_md_var(tc, "descr",
54301.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
54311.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
54321.1Skamil}
54331.1Skamil
54341.1SkamilATF_TC_BODY(lwp_create1, tc)
54351.1Skamil{
54361.1Skamil	const int exitval = 5;
54371.1Skamil	const int sigval = SIGSTOP;
54381.1Skamil	pid_t child, wpid;
54391.1Skamil#if defined(TWAIT_HAVE_STATUS)
54401.1Skamil	int status;
54411.1Skamil#endif
54421.1Skamil	ptrace_state_t state;
54431.1Skamil	const int slen = sizeof(state);
54441.1Skamil	ptrace_event_t event;
54451.1Skamil	const int elen = sizeof(event);
54461.1Skamil	ucontext_t uc;
54471.1Skamil	lwpid_t lid;
54481.1Skamil	static const size_t ssize = 16*1024;
54491.1Skamil	void *stack;
54501.1Skamil
54511.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54521.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54531.1Skamil	if (child == 0) {
54541.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54551.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54561.1Skamil
54571.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54581.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54591.1Skamil
54601.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
54611.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
54621.1Skamil
54631.13Schristos		DPRINTF("Before making context for new lwp in child\n");
54641.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
54651.1Skamil
54661.13Schristos		DPRINTF("Before creating new in child\n");
54671.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
54681.1Skamil
54691.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
54701.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
54711.1Skamil
54721.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
54731.1Skamil		    "are the same\n", lid, the_lwp_id);
54741.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
54751.1Skamil
54761.13Schristos		DPRINTF("Before exiting of the child process\n");
54771.1Skamil		_exit(exitval);
54781.1Skamil	}
54791.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54801.1Skamil
54811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54821.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54831.1Skamil
54841.1Skamil	validate_status_stopped(status, sigval);
54851.1Skamil
54861.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
54871.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
54881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
54891.1Skamil
54901.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54911.1Skamil	    "without signal to be sent\n");
54921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54931.1Skamil
54941.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
54951.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
54961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54971.1Skamil
54981.1Skamil	validate_status_stopped(status, SIGTRAP);
54991.1Skamil
55001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55011.1Skamil
55021.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
55031.1Skamil
55041.1Skamil	lid = state.pe_lwp;
55051.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
55061.1Skamil
55071.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55081.1Skamil	    "without signal to be sent\n");
55091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55101.1Skamil
55111.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
55121.1Skamil	    TWAIT_FNAME);
55131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55141.1Skamil
55151.1Skamil	validate_status_exited(status, exitval);
55161.1Skamil
55171.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
55181.1Skamil	    TWAIT_FNAME);
55191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55201.1Skamil}
55211.1Skamil
55221.1SkamilATF_TC(lwp_exit1);
55231.1SkamilATF_TC_HEAD(lwp_exit1, tc)
55241.1Skamil{
55251.1Skamil	atf_tc_set_md_var(tc, "descr",
55261.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
55271.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
55281.1Skamil}
55291.1Skamil
55301.1SkamilATF_TC_BODY(lwp_exit1, tc)
55311.1Skamil{
55321.1Skamil	const int exitval = 5;
55331.1Skamil	const int sigval = SIGSTOP;
55341.1Skamil	pid_t child, wpid;
55351.1Skamil#if defined(TWAIT_HAVE_STATUS)
55361.1Skamil	int status;
55371.1Skamil#endif
55381.1Skamil	ptrace_state_t state;
55391.1Skamil	const int slen = sizeof(state);
55401.1Skamil	ptrace_event_t event;
55411.1Skamil	const int elen = sizeof(event);
55421.1Skamil	ucontext_t uc;
55431.1Skamil	lwpid_t lid;
55441.1Skamil	static const size_t ssize = 16*1024;
55451.1Skamil	void *stack;
55461.1Skamil
55471.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55481.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55491.1Skamil	if (child == 0) {
55501.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55511.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55521.1Skamil
55531.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55541.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55551.1Skamil
55561.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
55571.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
55581.1Skamil
55591.13Schristos		DPRINTF("Before making context for new lwp in child\n");
55601.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
55611.1Skamil
55621.13Schristos		DPRINTF("Before creating new in child\n");
55631.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
55641.1Skamil
55651.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
55661.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
55671.1Skamil
55681.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
55691.1Skamil		    "are the same\n", lid, the_lwp_id);
55701.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
55711.1Skamil
55721.13Schristos		DPRINTF("Before exiting of the child process\n");
55731.1Skamil		_exit(exitval);
55741.1Skamil	}
55751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55761.1Skamil
55771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55791.1Skamil
55801.1Skamil	validate_status_stopped(status, sigval);
55811.1Skamil
55821.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
55831.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
55841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
55851.1Skamil
55861.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55871.1Skamil	    "without signal to be sent\n");
55881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55891.1Skamil
55901.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
55911.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
55921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55931.1Skamil
55941.1Skamil	validate_status_stopped(status, SIGTRAP);
55951.1Skamil
55961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
55971.1Skamil
55981.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
55991.1Skamil
56001.1Skamil	lid = state.pe_lwp;
56011.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
56021.1Skamil
56031.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56041.1Skamil	    "without signal to be sent\n");
56051.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56061.1Skamil
56071.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
56081.1Skamil	    TWAIT_FNAME);
56091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56101.1Skamil
56111.1Skamil	validate_status_exited(status, exitval);
56121.1Skamil
56131.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
56141.1Skamil	    TWAIT_FNAME);
56151.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56161.1Skamil}
56171.1Skamil
56181.1SkamilATF_TC(signal1);
56191.1SkamilATF_TC_HEAD(signal1, tc)
56201.1Skamil{
56211.1Skamil	atf_tc_set_md_var(tc, "descr",
56221.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
56231.1Skamil	    "from catching other signals");
56241.1Skamil}
56251.1Skamil
56261.1SkamilATF_TC_BODY(signal1, tc)
56271.1Skamil{
56281.1Skamil	const int exitval = 5;
56291.1Skamil	const int sigval = SIGSTOP;
56301.1Skamil	const int sigmasked = SIGTRAP;
56311.1Skamil	const int signotmasked = SIGINT;
56321.1Skamil	pid_t child, wpid;
56331.1Skamil#if defined(TWAIT_HAVE_STATUS)
56341.1Skamil	int status;
56351.1Skamil#endif
56361.1Skamil	sigset_t intmask;
56371.1Skamil
56381.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56391.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56401.1Skamil	if (child == 0) {
56411.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56421.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56431.1Skamil
56441.1Skamil		sigemptyset(&intmask);
56451.1Skamil		sigaddset(&intmask, sigmasked);
56461.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56471.1Skamil
56481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56501.1Skamil
56511.13Schristos		DPRINTF("Before raising %s from child\n",
56521.1Skamil		    strsignal(signotmasked));
56531.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
56541.1Skamil
56551.13Schristos		DPRINTF("Before exiting of the child process\n");
56561.1Skamil		_exit(exitval);
56571.1Skamil	}
56581.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56591.1Skamil
56601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56621.1Skamil
56631.1Skamil	validate_status_stopped(status, sigval);
56641.1Skamil
56651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56661.1Skamil	    "without signal to be sent\n");
56671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56681.1Skamil
56691.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56701.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56711.1Skamil
56721.1Skamil	validate_status_stopped(status, signotmasked);
56731.1Skamil
56741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56751.1Skamil	    "without signal to be sent\n");
56761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56771.1Skamil
56781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56791.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56801.1Skamil
56811.1Skamil	validate_status_exited(status, exitval);
56821.1Skamil
56831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56841.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56851.1Skamil}
56861.1Skamil
56871.1SkamilATF_TC(signal2);
56881.1SkamilATF_TC_HEAD(signal2, tc)
56891.1Skamil{
56901.1Skamil	atf_tc_set_md_var(tc, "descr",
56911.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
56921.1Skamil	    "catching this raised signal");
56931.1Skamil}
56941.1Skamil
56951.1SkamilATF_TC_BODY(signal2, tc)
56961.1Skamil{
56971.1Skamil	const int exitval = 5;
56981.1Skamil	const int sigval = SIGSTOP;
56991.1Skamil	const int sigmasked = SIGTRAP;
57001.1Skamil	pid_t child, wpid;
57011.1Skamil#if defined(TWAIT_HAVE_STATUS)
57021.1Skamil	int status;
57031.1Skamil#endif
57041.1Skamil	sigset_t intmask;
57051.1Skamil
57061.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57071.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57081.1Skamil	if (child == 0) {
57091.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57101.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57111.1Skamil
57121.1Skamil		sigemptyset(&intmask);
57131.1Skamil		sigaddset(&intmask, sigmasked);
57141.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57151.1Skamil
57161.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57171.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57181.1Skamil
57191.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
57201.1Skamil		    strsignal(sigmasked));
57211.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
57221.1Skamil
57231.13Schristos		DPRINTF("Before exiting of the child process\n");
57241.1Skamil		_exit(exitval);
57251.1Skamil	}
57261.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57271.1Skamil
57281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57301.1Skamil
57311.1Skamil	validate_status_stopped(status, sigval);
57321.1Skamil
57331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57341.1Skamil	    "without signal to be sent\n");
57351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57361.1Skamil
57371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57391.1Skamil
57401.1Skamil	validate_status_exited(status, exitval);
57411.1Skamil
57421.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57441.1Skamil}
57451.1Skamil
57461.1SkamilATF_TC(signal3);
57471.1SkamilATF_TC_HEAD(signal3, tc)
57481.1Skamil{
57491.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57501.1Skamil	atf_tc_set_md_var(tc, "descr",
57511.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57521.1Skamil	    "catching software breakpoints");
57531.1Skamil}
57541.1Skamil
57551.1SkamilATF_TC_BODY(signal3, tc)
57561.1Skamil{
57571.1Skamil	const int exitval = 5;
57581.1Skamil	const int sigval = SIGSTOP;
57591.1Skamil	const int sigmasked = SIGTRAP;
57601.1Skamil	pid_t child, wpid;
57611.1Skamil#if defined(TWAIT_HAVE_STATUS)
57621.1Skamil	int status;
57631.1Skamil#endif
57641.1Skamil	sigset_t intmask;
57651.1Skamil
57661.10Smartin#if defined(__sparc__)
57671.7Skamil	atf_tc_expect_timeout("PR kern/52167");
57681.7Skamil
57691.7Skamil	// timeout wins, failure still valid
57701.7Skamil	// atf_tc_expect_fail("PR kern/51918");
57711.7Skamil#endif
57721.1Skamil
57731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57751.1Skamil	if (child == 0) {
57761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57781.1Skamil
57791.1Skamil		sigemptyset(&intmask);
57801.1Skamil		sigaddset(&intmask, sigmasked);
57811.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57821.1Skamil
57831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57851.1Skamil
57861.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
57871.4Skamil
57881.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
57891.4Skamil		PTRACE_BREAKPOINT_ASM;
57901.1Skamil#else
57911.4Skamil		/* port me */
57921.1Skamil#endif
57931.1Skamil
57941.13Schristos		DPRINTF("Before exiting of the child process\n");
57951.1Skamil		_exit(exitval);
57961.1Skamil	}
57971.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57981.1Skamil
57991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58011.1Skamil
58021.1Skamil	validate_status_stopped(status, sigval);
58031.1Skamil
58041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58051.1Skamil	    "without signal to be sent\n");
58061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58071.1Skamil
58081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58101.1Skamil
58111.1Skamil	validate_status_stopped(status, sigmasked);
58121.1Skamil
58131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58141.1Skamil	    "without signal to be sent\n");
58151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58161.1Skamil
58171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58191.1Skamil
58201.1Skamil	validate_status_exited(status, exitval);
58211.1Skamil
58221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58231.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58241.1Skamil}
58251.1Skamil
58261.1Skamil#if defined(PT_STEP)
58271.1SkamilATF_TC(signal4);
58281.1SkamilATF_TC_HEAD(signal4, tc)
58291.1Skamil{
58301.1Skamil	atf_tc_set_md_var(tc, "descr",
58311.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
58321.1Skamil	    "catching single step trap");
58331.1Skamil}
58341.1Skamil
58351.1SkamilATF_TC_BODY(signal4, tc)
58361.1Skamil{
58371.1Skamil	const int exitval = 5;
58381.1Skamil	const int sigval = SIGSTOP;
58391.1Skamil	const int sigmasked = SIGTRAP;
58401.1Skamil	pid_t child, wpid;
58411.1Skamil#if defined(TWAIT_HAVE_STATUS)
58421.1Skamil	int status;
58431.1Skamil#endif
58441.1Skamil	sigset_t intmask;
58451.1Skamil	int happy;
58461.1Skamil
58471.1Skamil#if defined(__arm__)
58481.5Skamil	/* PT_STEP not supported on arm 32-bit */
58491.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
58501.1Skamil#endif
58511.1Skamil
58521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58541.1Skamil	if (child == 0) {
58551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58571.1Skamil
58581.1Skamil		happy = check_happy(100);
58591.1Skamil
58601.1Skamil		sigemptyset(&intmask);
58611.1Skamil		sigaddset(&intmask, sigmasked);
58621.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58631.1Skamil
58641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58661.1Skamil
58671.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
58681.1Skamil
58691.13Schristos		DPRINTF("Before exiting of the child process\n");
58701.1Skamil		_exit(exitval);
58711.1Skamil	}
58721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58731.1Skamil
58741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58761.1Skamil
58771.1Skamil	validate_status_stopped(status, sigval);
58781.1Skamil
58791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58801.1Skamil	    "without signal to be sent\n");
58811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
58821.1Skamil
58831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58851.1Skamil
58861.1Skamil	validate_status_stopped(status, sigmasked);
58871.1Skamil
58881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58891.1Skamil	    "without signal to be sent\n");
58901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58911.1Skamil
58921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58941.1Skamil
58951.1Skamil	validate_status_exited(status, exitval);
58961.1Skamil
58971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
58991.1Skamil}
59001.1Skamil#endif
59011.1Skamil
59021.1SkamilATF_TC(signal5);
59031.1SkamilATF_TC_HEAD(signal5, tc)
59041.1Skamil{
59051.1Skamil	atf_tc_set_md_var(tc, "descr",
59061.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59071.1Skamil	    "catching exec() breakpoint");
59081.1Skamil}
59091.1Skamil
59101.1SkamilATF_TC_BODY(signal5, tc)
59111.1Skamil{
59121.1Skamil	const int exitval = 5;
59131.1Skamil	const int sigval = SIGSTOP;
59141.1Skamil	const int sigmasked = SIGTRAP;
59151.1Skamil	pid_t child, wpid;
59161.1Skamil#if defined(TWAIT_HAVE_STATUS)
59171.1Skamil	int status;
59181.1Skamil#endif
59191.1Skamil	sigset_t intmask;
59201.1Skamil
59211.14Schristos	atf_tc_expect_fail("wrong signal");
59221.14Schristos
59231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59251.1Skamil	if (child == 0) {
59261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59281.1Skamil
59291.1Skamil		sigemptyset(&intmask);
59301.1Skamil		sigaddset(&intmask, sigmasked);
59311.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59321.1Skamil
59331.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59341.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59351.1Skamil
59361.13Schristos		DPRINTF("Before calling execve(2) from child\n");
59371.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
59381.1Skamil
59391.13Schristos		DPRINTF("Before exiting of the child process\n");
59401.1Skamil		_exit(exitval);
59411.1Skamil	}
59421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59431.1Skamil
59441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59461.1Skamil
59471.1Skamil	validate_status_stopped(status, sigval);
59481.1Skamil
59491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59501.1Skamil	    "without signal to be sent\n");
59511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59521.1Skamil
59531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59551.1Skamil
59561.1Skamil	validate_status_stopped(status, sigmasked);
59571.1Skamil
59581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59591.1Skamil	    "without signal to be sent\n");
59601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59611.1Skamil
59621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59641.1Skamil
59651.1Skamil	validate_status_exited(status, exitval);
59661.1Skamil
59671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59691.1Skamil}
59701.1Skamil
59711.1Skamil#if defined(TWAIT_HAVE_PID)
59721.1SkamilATF_TC(signal6);
59731.1SkamilATF_TC_HEAD(signal6, tc)
59741.1Skamil{
59751.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
59761.1Skamil	atf_tc_set_md_var(tc, "descr",
59771.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59781.1Skamil	    "catching PTRACE_FORK breakpoint");
59791.1Skamil}
59801.1Skamil
59811.1SkamilATF_TC_BODY(signal6, tc)
59821.1Skamil{
59831.1Skamil	const int exitval = 5;
59841.1Skamil	const int exitval2 = 15;
59851.1Skamil	const int sigval = SIGSTOP;
59861.1Skamil	const int sigmasked = SIGTRAP;
59871.1Skamil	pid_t child, child2, wpid;
59881.1Skamil#if defined(TWAIT_HAVE_STATUS)
59891.1Skamil	int status;
59901.1Skamil#endif
59911.1Skamil	sigset_t intmask;
59921.1Skamil	ptrace_state_t state;
59931.1Skamil	const int slen = sizeof(state);
59941.1Skamil	ptrace_event_t event;
59951.1Skamil	const int elen = sizeof(event);
59961.1Skamil
59971.14Schristos	atf_tc_expect_timeout("PR kern/51918");
59981.14Schristos
59991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60011.1Skamil	if (child == 0) {
60021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60041.1Skamil
60051.1Skamil		sigemptyset(&intmask);
60061.1Skamil		sigaddset(&intmask, sigmasked);
60071.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60081.1Skamil
60091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60111.1Skamil
60121.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
60131.1Skamil
60141.1Skamil		if (child2 == 0)
60151.1Skamil			_exit(exitval2);
60161.1Skamil
60171.1Skamil		FORKEE_REQUIRE_SUCCESS
60181.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60191.1Skamil
60201.1Skamil		forkee_status_exited(status, exitval2);
60211.1Skamil
60221.13Schristos		DPRINTF("Before exiting of the child process\n");
60231.1Skamil		_exit(exitval);
60241.1Skamil	}
60251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60261.1Skamil
60271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60291.1Skamil
60301.1Skamil	validate_status_stopped(status, sigval);
60311.1Skamil
60321.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
60331.1Skamil	event.pe_set_event = PTRACE_FORK;
60341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60351.1Skamil
60361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60371.1Skamil	    "without signal to be sent\n");
60381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60391.1Skamil
60401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60421.1Skamil
60431.1Skamil	validate_status_stopped(status, sigmasked);
60441.1Skamil
60451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
60461.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60471.1Skamil
60481.1Skamil	child2 = state.pe_other_pid;
60491.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
60501.1Skamil
60511.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
60521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60531.1Skamil	    child2);
60541.1Skamil
60551.1Skamil	validate_status_stopped(status, SIGTRAP);
60561.1Skamil
60571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
60581.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
60591.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
60601.1Skamil
60611.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
60621.1Skamil	    "without signal to be sent\n");
60631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
60641.1Skamil
60651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60661.1Skamil	    "without signal to be sent\n");
60671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60681.1Skamil
60691.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60701.1Skamil	    TWAIT_FNAME);
60711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60721.1Skamil	    child2);
60731.1Skamil
60741.1Skamil	validate_status_exited(status, exitval2);
60751.1Skamil
60761.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
60771.1Skamil	    TWAIT_FNAME);
60781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
60791.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
60801.1Skamil
60811.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60821.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
60831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60841.1Skamil
60851.1Skamil	validate_status_stopped(status, SIGCHLD);
60861.1Skamil
60871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60881.1Skamil	    "without signal to be sent\n");
60891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60901.1Skamil
60911.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60921.1Skamil	    TWAIT_FNAME);
60931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60941.1Skamil
60951.1Skamil	validate_status_exited(status, exitval);
60961.1Skamil
60971.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60981.1Skamil	    TWAIT_FNAME);
60991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61001.1Skamil}
61011.1Skamil#endif
61021.1Skamil
61031.1Skamil#if defined(TWAIT_HAVE_PID)
61041.1SkamilATF_TC(signal7);
61051.1SkamilATF_TC_HEAD(signal7, tc)
61061.1Skamil{
61071.1Skamil	atf_tc_set_md_var(tc, "descr",
61081.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61091.1Skamil	    "catching PTRACE_VFORK breakpoint");
61101.1Skamil}
61111.1Skamil
61121.1SkamilATF_TC_BODY(signal7, tc)
61131.1Skamil{
61141.1Skamil	const int exitval = 5;
61151.1Skamil	const int exitval2 = 15;
61161.1Skamil	const int sigval = SIGSTOP;
61171.1Skamil	const int sigmasked = SIGTRAP;
61181.1Skamil	pid_t child, child2, wpid;
61191.1Skamil#if defined(TWAIT_HAVE_STATUS)
61201.1Skamil	int status;
61211.1Skamil#endif
61221.1Skamil	sigset_t intmask;
61231.1Skamil	ptrace_state_t state;
61241.1Skamil	const int slen = sizeof(state);
61251.1Skamil	ptrace_event_t event;
61261.1Skamil	const int elen = sizeof(event);
61271.1Skamil
61281.14Schristos	atf_tc_expect_fail("PR kern/51918 PR kern/51630");
61291.14Schristos
61301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61321.1Skamil	if (child == 0) {
61331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61351.1Skamil
61361.1Skamil		sigemptyset(&intmask);
61371.1Skamil		sigaddset(&intmask, sigmasked);
61381.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61391.1Skamil
61401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61421.1Skamil
61431.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
61441.1Skamil
61451.1Skamil		if (child2 == 0)
61461.1Skamil			_exit(exitval2);
61471.1Skamil
61481.1Skamil		FORKEE_REQUIRE_SUCCESS
61491.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
61501.1Skamil
61511.1Skamil		forkee_status_exited(status, exitval2);
61521.1Skamil
61531.13Schristos		DPRINTF("Before exiting of the child process\n");
61541.1Skamil		_exit(exitval);
61551.1Skamil	}
61561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
61571.1Skamil
61581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61601.1Skamil
61611.1Skamil	validate_status_stopped(status, sigval);
61621.1Skamil
61631.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
61641.1Skamil	event.pe_set_event = PTRACE_VFORK;
61651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
61661.1Skamil
61671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61681.1Skamil	    "without signal to be sent\n");
61691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61701.1Skamil
61711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61731.1Skamil
61741.1Skamil	validate_status_stopped(status, sigmasked);
61751.1Skamil
61761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61771.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61781.1Skamil
61791.1Skamil	child2 = state.pe_other_pid;
61801.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
61811.1Skamil
61821.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
61831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
61841.1Skamil	    child2);
61851.1Skamil
61861.1Skamil	validate_status_stopped(status, SIGTRAP);
61871.1Skamil
61881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
61891.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
61901.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
61911.1Skamil
61921.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
61931.1Skamil	    "without signal to be sent\n");
61941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
61951.1Skamil
61961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61971.1Skamil	    "without signal to be sent\n");
61981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61991.1Skamil
62001.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
62011.1Skamil	    TWAIT_FNAME);
62021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
62031.1Skamil	    child2);
62041.1Skamil
62051.1Skamil	validate_status_exited(status, exitval2);
62061.1Skamil
62071.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
62081.1Skamil	    TWAIT_FNAME);
62091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
62101.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
62111.1Skamil
62121.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62131.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
62141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62151.1Skamil
62161.1Skamil	validate_status_stopped(status, SIGCHLD);
62171.1Skamil
62181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62191.1Skamil	    "without signal to be sent\n");
62201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62211.1Skamil
62221.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62231.1Skamil	    TWAIT_FNAME);
62241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62251.1Skamil
62261.1Skamil	validate_status_exited(status, exitval);
62271.1Skamil
62281.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62291.1Skamil	    TWAIT_FNAME);
62301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62311.1Skamil}
62321.1Skamil#endif
62331.1Skamil
62341.1SkamilATF_TC(signal8);
62351.1SkamilATF_TC_HEAD(signal8, tc)
62361.1Skamil{
62371.1Skamil	atf_tc_set_md_var(tc, "descr",
62381.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62391.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
62401.1Skamil}
62411.1Skamil
62421.1SkamilATF_TC_BODY(signal8, tc)
62431.1Skamil{
62441.1Skamil	const int exitval = 5;
62451.1Skamil	const int exitval2 = 15;
62461.1Skamil	const int sigval = SIGSTOP;
62471.1Skamil	const int sigmasked = SIGTRAP;
62481.1Skamil	pid_t child, child2, wpid;
62491.1Skamil#if defined(TWAIT_HAVE_STATUS)
62501.1Skamil	int status;
62511.1Skamil#endif
62521.1Skamil	sigset_t intmask;
62531.1Skamil	ptrace_state_t state;
62541.1Skamil	const int slen = sizeof(state);
62551.1Skamil	ptrace_event_t event;
62561.1Skamil	const int elen = sizeof(event);
62571.1Skamil
62581.14Schristos	atf_tc_expect_fail("PR kern/51918");
62591.14Schristos
62601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62621.1Skamil	if (child == 0) {
62631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62651.1Skamil
62661.1Skamil		sigemptyset(&intmask);
62671.1Skamil		sigaddset(&intmask, sigmasked);
62681.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62691.1Skamil
62701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62721.1Skamil
62731.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
62741.1Skamil
62751.1Skamil		if (child2 == 0)
62761.1Skamil			_exit(exitval2);
62771.1Skamil
62781.1Skamil		FORKEE_REQUIRE_SUCCESS
62791.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
62801.1Skamil
62811.1Skamil		forkee_status_exited(status, exitval2);
62821.1Skamil
62831.13Schristos		DPRINTF("Before exiting of the child process\n");
62841.1Skamil		_exit(exitval);
62851.1Skamil	}
62861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62871.1Skamil
62881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62901.1Skamil
62911.1Skamil	validate_status_stopped(status, sigval);
62921.1Skamil
62931.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
62941.1Skamil	    child);
62951.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
62961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
62971.1Skamil
62981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62991.1Skamil	    "without signal to be sent\n");
63001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63011.1Skamil
63021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63041.1Skamil
63051.1Skamil	validate_status_stopped(status, sigmasked);
63061.1Skamil
63071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63081.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
63091.1Skamil
63101.1Skamil	child2 = state.pe_other_pid;
63111.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
63121.1Skamil
63131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63141.1Skamil	    "without signal to be sent\n");
63151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63161.1Skamil
63171.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63181.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
63191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63201.1Skamil
63211.1Skamil	validate_status_stopped(status, SIGCHLD);
63221.1Skamil
63231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63241.1Skamil	    "without signal to be sent\n");
63251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63261.1Skamil
63271.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63281.1Skamil	    TWAIT_FNAME);
63291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63301.1Skamil
63311.1Skamil	validate_status_exited(status, exitval);
63321.1Skamil
63331.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63341.1Skamil	    TWAIT_FNAME);
63351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63361.1Skamil}
63371.1Skamil
63381.1SkamilATF_TC(signal9);
63391.1SkamilATF_TC_HEAD(signal9, tc)
63401.1Skamil{
63411.1Skamil	atf_tc_set_md_var(tc, "descr",
63421.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
63431.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
63441.1Skamil}
63451.1Skamil
63461.1SkamilATF_TC_BODY(signal9, tc)
63471.1Skamil{
63481.1Skamil	const int exitval = 5;
63491.1Skamil	const int sigval = SIGSTOP;
63501.1Skamil	const int sigmasked = SIGTRAP;
63511.1Skamil	pid_t child, wpid;
63521.1Skamil#if defined(TWAIT_HAVE_STATUS)
63531.1Skamil	int status;
63541.1Skamil#endif
63551.1Skamil	sigset_t intmask;
63561.1Skamil	ptrace_state_t state;
63571.1Skamil	const int slen = sizeof(state);
63581.1Skamil	ptrace_event_t event;
63591.1Skamil	const int elen = sizeof(event);
63601.1Skamil	ucontext_t uc;
63611.1Skamil	lwpid_t lid;
63621.1Skamil	static const size_t ssize = 16*1024;
63631.1Skamil	void *stack;
63641.1Skamil
63651.14Schristos	atf_tc_expect_fail("PR kern/51918");
63661.14Schristos
63671.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63681.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63691.1Skamil	if (child == 0) {
63701.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63711.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63721.1Skamil
63731.1Skamil		sigemptyset(&intmask);
63741.1Skamil		sigaddset(&intmask, sigmasked);
63751.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
63761.1Skamil
63771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63791.1Skamil
63801.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63811.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
63821.1Skamil
63831.13Schristos		DPRINTF("Before making context for new lwp in child\n");
63841.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
63851.1Skamil
63861.13Schristos		DPRINTF("Before creating new in child\n");
63871.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
63881.1Skamil
63891.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
63901.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
63911.1Skamil
63921.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
63931.1Skamil		    "are the same\n", lid, the_lwp_id);
63941.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
63951.1Skamil
63961.13Schristos		DPRINTF("Before exiting of the child process\n");
63971.1Skamil		_exit(exitval);
63981.1Skamil	}
63991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64001.1Skamil
64011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64031.1Skamil
64041.1Skamil	validate_status_stopped(status, sigval);
64051.1Skamil
64061.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
64071.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
64081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
64091.1Skamil
64101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64111.1Skamil	    "without signal to be sent\n");
64121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64131.1Skamil
64141.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64151.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64171.1Skamil
64181.1Skamil	validate_status_stopped(status, sigmasked);
64191.1Skamil
64201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
64211.1Skamil
64221.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
64231.1Skamil
64241.1Skamil	lid = state.pe_lwp;
64251.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
64261.1Skamil
64271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64281.1Skamil	    "without signal to be sent\n");
64291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64301.1Skamil
64311.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64321.1Skamil	    TWAIT_FNAME);
64331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64341.1Skamil
64351.1Skamil	validate_status_exited(status, exitval);
64361.1Skamil
64371.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64381.1Skamil	    TWAIT_FNAME);
64391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64401.1Skamil}
64411.1Skamil
64421.1SkamilATF_TC(signal10);
64431.1SkamilATF_TC_HEAD(signal10, tc)
64441.1Skamil{
64451.1Skamil	atf_tc_set_md_var(tc, "descr",
64461.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
64471.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
64481.1Skamil}
64491.1Skamil
64501.1SkamilATF_TC_BODY(signal10, tc)
64511.1Skamil{
64521.1Skamil	const int exitval = 5;
64531.1Skamil	const int sigval = SIGSTOP;
64541.1Skamil	const int sigmasked = SIGTRAP;
64551.1Skamil	pid_t child, wpid;
64561.1Skamil#if defined(TWAIT_HAVE_STATUS)
64571.1Skamil	int status;
64581.1Skamil#endif
64591.1Skamil	sigset_t intmask;
64601.1Skamil	ptrace_state_t state;
64611.1Skamil	const int slen = sizeof(state);
64621.1Skamil	ptrace_event_t event;
64631.1Skamil	const int elen = sizeof(event);
64641.1Skamil	ucontext_t uc;
64651.1Skamil	lwpid_t lid;
64661.1Skamil	static const size_t ssize = 16*1024;
64671.1Skamil	void *stack;
64681.1Skamil
64691.14Schristos	atf_tc_expect_fail("PR kern/51918");
64701.14Schristos
64711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
64721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
64731.1Skamil	if (child == 0) {
64741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
64751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
64761.1Skamil
64771.1Skamil		sigemptyset(&intmask);
64781.1Skamil		sigaddset(&intmask, sigmasked);
64791.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
64801.1Skamil
64811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
64821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
64831.1Skamil
64841.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
64851.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
64861.1Skamil
64871.13Schristos		DPRINTF("Before making context for new lwp in child\n");
64881.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
64891.1Skamil
64901.13Schristos		DPRINTF("Before creating new in child\n");
64911.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64921.1Skamil
64931.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64941.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64951.1Skamil
64961.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64971.1Skamil		    "are the same\n", lid, the_lwp_id);
64981.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64991.1Skamil
65001.13Schristos		DPRINTF("Before exiting of the child process\n");
65011.1Skamil		_exit(exitval);
65021.1Skamil	}
65031.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65041.1Skamil
65051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65071.1Skamil
65081.1Skamil	validate_status_stopped(status, sigval);
65091.1Skamil
65101.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
65111.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
65121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
65131.1Skamil
65141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65151.1Skamil	    "without signal to be sent\n");
65161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65171.1Skamil
65181.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
65191.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
65201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65211.1Skamil
65221.1Skamil	validate_status_stopped(status, sigmasked);
65231.1Skamil
65241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
65251.1Skamil
65261.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
65271.1Skamil
65281.1Skamil	lid = state.pe_lwp;
65291.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
65301.1Skamil
65311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65321.1Skamil	    "without signal to be sent\n");
65331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65341.1Skamil
65351.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65361.1Skamil	    TWAIT_FNAME);
65371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65381.1Skamil
65391.1Skamil	validate_status_exited(status, exitval);
65401.1Skamil
65411.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65421.1Skamil	    TWAIT_FNAME);
65431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65441.1Skamil}
65451.1Skamil
65461.1SkamilATF_TC(getsigmask1);
65471.1SkamilATF_TC_HEAD(getsigmask1, tc)
65481.1Skamil{
65491.1Skamil	atf_tc_set_md_var(tc, "descr",
65501.1Skamil	    "Verify that plain PT_SET_SIGMASK can be called");
65511.1Skamil}
65521.1Skamil
65531.1SkamilATF_TC_BODY(getsigmask1, tc)
65541.1Skamil{
65551.1Skamil	const int exitval = 5;
65561.1Skamil	const int sigval = SIGSTOP;
65571.1Skamil	pid_t child, wpid;
65581.1Skamil#if defined(TWAIT_HAVE_STATUS)
65591.1Skamil	int status;
65601.1Skamil#endif
65611.1Skamil	sigset_t mask;
65621.1Skamil
65631.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65641.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65651.1Skamil	if (child == 0) {
65661.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65671.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65681.1Skamil
65691.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65701.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65711.1Skamil
65721.13Schristos		DPRINTF("Before exiting of the child process\n");
65731.1Skamil		_exit(exitval);
65741.1Skamil	}
65751.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65761.1Skamil
65771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65791.1Skamil
65801.1Skamil	validate_status_stopped(status, sigval);
65811.1Skamil
65821.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK\n");
65831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &mask, 0) != -1);
65841.1Skamil
65851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65861.1Skamil	    "without signal to be sent\n");
65871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65881.1Skamil
65891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65911.1Skamil
65921.1Skamil	validate_status_exited(status, exitval);
65931.1Skamil
65941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65951.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65961.1Skamil}
65971.1Skamil
65981.1SkamilATF_TC(getsigmask2);
65991.1SkamilATF_TC_HEAD(getsigmask2, tc)
66001.1Skamil{
66011.1Skamil	atf_tc_set_md_var(tc, "descr",
66021.1Skamil	    "Verify that PT_SET_SIGMASK reports correct mask from tracee");
66031.1Skamil}
66041.1Skamil
66051.1SkamilATF_TC_BODY(getsigmask2, tc)
66061.1Skamil{
66071.1Skamil	const int exitval = 5;
66081.1Skamil	const int sigval = SIGSTOP;
66091.1Skamil	const int sigmasked = SIGTRAP;
66101.1Skamil	pid_t child, wpid;
66111.1Skamil#if defined(TWAIT_HAVE_STATUS)
66121.1Skamil	int status;
66131.1Skamil#endif
66141.1Skamil	sigset_t mask;
66151.1Skamil	sigset_t expected_mask;
66161.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
66171.1Skamil	ATF_REQUIRE(sigemptyset(&expected_mask) == 0);
66181.1Skamil	ATF_REQUIRE(sigaddset(&expected_mask, sigmasked) == 0);
66191.1Skamil
66201.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66211.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66221.1Skamil	if (child == 0) {
66231.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66241.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66251.1Skamil
66261.1Skamil		sigaddset(&mask, sigmasked);
66271.1Skamil		sigprocmask(SIG_BLOCK, &mask, NULL);
66281.1Skamil
66291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66311.1Skamil
66321.13Schristos		DPRINTF("Before exiting of the child process\n");
66331.1Skamil		_exit(exitval);
66341.1Skamil	}
66351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66361.1Skamil
66371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66391.1Skamil
66401.1Skamil	validate_status_stopped(status, sigval);
66411.1Skamil
66421.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK\n");
66431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &mask, 0) != -1);
66441.1Skamil
66451.1Skamil	ATF_REQUIRE(memcmp(&mask, &expected_mask, sizeof(sigset_t)) == 0);
66461.1Skamil
66471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66481.1Skamil	    "without signal to be sent\n");
66491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66501.1Skamil
66511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66531.1Skamil
66541.1Skamil	validate_status_exited(status, exitval);
66551.1Skamil
66561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66581.1Skamil}
66591.1Skamil
66601.1SkamilATF_TC(setsigmask1);
66611.1SkamilATF_TC_HEAD(setsigmask1, tc)
66621.1Skamil{
66631.1Skamil	atf_tc_set_md_var(tc, "descr",
66641.1Skamil	    "Verify that plain PT_SET_SIGMASK can be called with empty mask");
66651.1Skamil}
66661.1Skamil
66671.1SkamilATF_TC_BODY(setsigmask1, tc)
66681.1Skamil{
66691.1Skamil	const int exitval = 5;
66701.1Skamil	const int sigval = SIGSTOP;
66711.1Skamil	pid_t child, wpid;
66721.1Skamil#if defined(TWAIT_HAVE_STATUS)
66731.1Skamil	int status;
66741.1Skamil#endif
66751.1Skamil	sigset_t mask;
66761.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
66771.1Skamil
66781.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
66791.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
66801.1Skamil	if (child == 0) {
66811.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
66821.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66831.1Skamil
66841.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66851.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66861.1Skamil
66871.13Schristos		DPRINTF("Before exiting of the child process\n");
66881.1Skamil		_exit(exitval);
66891.1Skamil	}
66901.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66911.1Skamil
66921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66941.1Skamil
66951.1Skamil	validate_status_stopped(status, sigval);
66961.1Skamil
66971.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for empty mask\n");
66981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
66991.1Skamil
67001.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67011.1Skamil	    "without signal to be sent\n");
67021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67031.1Skamil
67041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67061.1Skamil
67071.1Skamil	validate_status_exited(status, exitval);
67081.1Skamil
67091.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67111.1Skamil}
67121.1Skamil
67131.1SkamilATF_TC(setsigmask2);
67141.1SkamilATF_TC_HEAD(setsigmask2, tc)
67151.1Skamil{
67161.1Skamil	atf_tc_set_md_var(tc, "descr",
67171.1Skamil	    "Verify that sigmask is preserved between PT_GET_SIGMASK and "
67181.1Skamil	    "PT_SET_SIGMASK");
67191.1Skamil}
67201.1Skamil
67211.1SkamilATF_TC_BODY(setsigmask2, tc)
67221.1Skamil{
67231.1Skamil	const int exitval = 5;
67241.1Skamil	const int sigval = SIGSTOP;
67251.1Skamil	pid_t child, wpid;
67261.1Skamil#if defined(TWAIT_HAVE_STATUS)
67271.1Skamil	int status;
67281.1Skamil#endif
67291.1Skamil	sigset_t new_mask;
67301.1Skamil	sigset_t mask;
67311.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
67321.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
67331.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGINT) == 0);
67341.1Skamil
67351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67371.1Skamil	if (child == 0) {
67381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67401.1Skamil
67411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67431.1Skamil
67441.13Schristos		DPRINTF("Before exiting of the child process\n");
67451.1Skamil		_exit(exitval);
67461.1Skamil	}
67471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67481.1Skamil
67491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67511.1Skamil
67521.1Skamil	validate_status_stopped(status, sigval);
67531.1Skamil
67541.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
67551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
67561.1Skamil
67571.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
67581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
67591.1Skamil
67601.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) == 0);
67611.1Skamil
67621.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67631.1Skamil	    "without signal to be sent\n");
67641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67651.1Skamil
67661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67671.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67681.1Skamil
67691.1Skamil	validate_status_exited(status, exitval);
67701.1Skamil
67711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67721.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67731.1Skamil}
67741.1Skamil
67751.1SkamilATF_TC(setsigmask3);
67761.1SkamilATF_TC_HEAD(setsigmask3, tc)
67771.1Skamil{
67781.1Skamil	atf_tc_set_md_var(tc, "descr",
67791.1Skamil	    "Verify that sigmask is preserved between PT_GET_SIGMASK, process "
67801.1Skamil	    "resumed and PT_SET_SIGMASK");
67811.1Skamil}
67821.1Skamil
67831.1SkamilATF_TC_BODY(setsigmask3, tc)
67841.1Skamil{
67851.1Skamil	const int exitval = 5;
67861.1Skamil	const int sigval = SIGSTOP;
67871.1Skamil	pid_t child, wpid;
67881.1Skamil#if defined(TWAIT_HAVE_STATUS)
67891.1Skamil	int status;
67901.1Skamil#endif
67911.1Skamil	sigset_t new_mask;
67921.1Skamil	sigset_t mask;
67931.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
67941.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
67951.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGINT) == 0);
67961.1Skamil
67971.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67981.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67991.1Skamil	if (child == 0) {
68001.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68011.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68021.1Skamil
68031.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68041.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68051.1Skamil
68061.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68071.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68081.1Skamil
68091.13Schristos		DPRINTF("Before exiting of the child process\n");
68101.1Skamil		_exit(exitval);
68111.1Skamil	}
68121.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68131.1Skamil
68141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68161.1Skamil
68171.1Skamil	validate_status_stopped(status, sigval);
68181.1Skamil
68191.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
68201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
68211.1Skamil
68221.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68231.1Skamil	    "without signal to be sent\n");
68241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68251.1Skamil
68261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68281.1Skamil
68291.1Skamil	validate_status_stopped(status, sigval);
68301.1Skamil
68311.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
68321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
68331.1Skamil
68341.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) == 0);
68351.1Skamil
68361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68371.1Skamil	    "without signal to be sent\n");
68381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68391.1Skamil
68401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68421.1Skamil
68431.1Skamil	validate_status_exited(status, exitval);
68441.1Skamil
68451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
68471.1Skamil}
68481.1Skamil
68491.1SkamilATF_TC(setsigmask4);
68501.1SkamilATF_TC_HEAD(setsigmask4, tc)
68511.1Skamil{
68521.1Skamil	atf_tc_set_md_var(tc, "descr",
68531.1Skamil	    "Verify that new sigmask is visible in tracee");
68541.1Skamil}
68551.1Skamil
68561.1SkamilATF_TC_BODY(setsigmask4, tc)
68571.1Skamil{
68581.1Skamil	const int exitval = 5;
68591.1Skamil	const int sigval = SIGSTOP;
68601.1Skamil	pid_t child, wpid;
68611.1Skamil#if defined(TWAIT_HAVE_STATUS)
68621.1Skamil	int status;
68631.1Skamil#endif
68641.1Skamil	sigset_t mask;
68651.1Skamil	sigset_t expected_mask;
68661.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
68671.1Skamil	ATF_REQUIRE(sigemptyset(&expected_mask) == 0);
68681.1Skamil	ATF_REQUIRE(sigaddset(&expected_mask, SIGINT) == 0);
68691.1Skamil
68701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
68711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
68721.1Skamil	if (child == 0) {
68731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68751.1Skamil
68761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68781.1Skamil
68791.1Skamil		sigprocmask(0, NULL, &mask);
68801.1Skamil
68811.1Skamil		FORKEE_ASSERT
68821.1Skamil		    (memcmp(&mask, &expected_mask, sizeof(sigset_t)) == 0);
68831.1Skamil
68841.13Schristos		DPRINTF("Before exiting of the child process\n");
68851.1Skamil		_exit(exitval);
68861.1Skamil	}
68871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68881.1Skamil
68891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68911.1Skamil
68921.1Skamil	validate_status_stopped(status, sigval);
68931.1Skamil
68941.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
68951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &expected_mask, 0) != -1);
68961.1Skamil
68971.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68981.1Skamil	    "without signal to be sent\n");
68991.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69001.1Skamil
69011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69031.1Skamil
69041.1Skamil	validate_status_exited(status, exitval);
69051.1Skamil
69061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69071.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69081.1Skamil}
69091.1Skamil
69101.1SkamilATF_TC(setsigmask5);
69111.1SkamilATF_TC_HEAD(setsigmask5, tc)
69121.1Skamil{
69131.1Skamil	atf_tc_set_md_var(tc, "descr",
69141.1Skamil	    "Verify that sigmask cannot be set to SIGKILL");
69151.1Skamil}
69161.1Skamil
69171.1SkamilATF_TC_BODY(setsigmask5, tc)
69181.1Skamil{
69191.1Skamil	const int exitval = 5;
69201.1Skamil	const int sigval = SIGSTOP;
69211.1Skamil	pid_t child, wpid;
69221.1Skamil#if defined(TWAIT_HAVE_STATUS)
69231.1Skamil	int status;
69241.1Skamil#endif
69251.1Skamil	sigset_t new_mask;
69261.1Skamil	sigset_t mask;
69271.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
69281.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
69291.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGKILL) == 0);
69301.1Skamil
69311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69331.1Skamil	if (child == 0) {
69341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69361.1Skamil
69371.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69381.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
69391.1Skamil
69401.13Schristos		DPRINTF("Before exiting of the child process\n");
69411.1Skamil		_exit(exitval);
69421.1Skamil	}
69431.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
69441.1Skamil
69451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69471.1Skamil
69481.1Skamil	validate_status_stopped(status, sigval);
69491.1Skamil
69501.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
69511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
69521.1Skamil
69531.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
69541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
69551.1Skamil
69561.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) != 0);
69571.1Skamil
69581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
69591.1Skamil	    "without signal to be sent\n");
69601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
69611.1Skamil
69621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
69641.1Skamil
69651.1Skamil	validate_status_exited(status, exitval);
69661.1Skamil
69671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
69681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
69691.1Skamil}
69701.1Skamil
69711.1SkamilATF_TC(setsigmask6);
69721.1SkamilATF_TC_HEAD(setsigmask6, tc)
69731.1Skamil{
69741.1Skamil	atf_tc_set_md_var(tc, "descr",
69751.1Skamil	    "Verify that sigmask cannot be set to SIGSTOP");
69761.1Skamil}
69771.1Skamil
69781.1SkamilATF_TC_BODY(setsigmask6, tc)
69791.1Skamil{
69801.1Skamil	const int exitval = 5;
69811.1Skamil	const int sigval = SIGSTOP;
69821.1Skamil	pid_t child, wpid;
69831.1Skamil#if defined(TWAIT_HAVE_STATUS)
69841.1Skamil	int status;
69851.1Skamil#endif
69861.1Skamil	sigset_t new_mask;
69871.1Skamil	sigset_t mask;
69881.1Skamil	ATF_REQUIRE(sigemptyset(&new_mask) == 0);
69891.1Skamil	ATF_REQUIRE(sigemptyset(&mask) == 0);
69901.1Skamil	ATF_REQUIRE(sigaddset(&mask, SIGSTOP) == 0);
69911.1Skamil
69921.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
69931.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
69941.1Skamil	if (child == 0) {
69951.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
69961.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
69971.1Skamil
69981.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
69991.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70001.1Skamil
70011.13Schristos		DPRINTF("Before exiting of the child process\n");
70021.1Skamil		_exit(exitval);
70031.1Skamil	}
70041.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
70051.1Skamil
70061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70081.1Skamil
70091.1Skamil	validate_status_stopped(status, sigval);
70101.1Skamil
70111.13Schristos	DPRINTF("Before calling PT_SET_SIGMASK for new mask with SIGINT\n");
70121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGMASK, child, &mask, 0) != -1);
70131.1Skamil
70141.13Schristos	DPRINTF("Before calling PT_GET_SIGMASK to store it in new_mask\n");
70151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGMASK, child, &new_mask, 0) != -1);
70161.1Skamil
70171.1Skamil	ATF_REQUIRE(memcmp(&mask, &new_mask, sizeof(sigset_t)) != 0);
70181.1Skamil
70191.13Schristos	DPRINTF("Before resuming the child process where it left off and "
70201.1Skamil	    "without signal to be sent\n");
70211.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
70221.1Skamil
70231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
70251.1Skamil
70261.1Skamil	validate_status_exited(status, exitval);
70271.1Skamil
70281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
70291.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
70301.1Skamil}
70311.1Skamil
70321.1Skamilstatic void
70331.1Skamillwp_main_stop(void *arg)
70341.1Skamil{
70351.1Skamil	the_lwp_id = _lwp_self();
70361.1Skamil
70371.1Skamil	raise(SIGTRAP);
70381.1Skamil
70391.1Skamil	_lwp_exit();
70401.1Skamil}
70411.1Skamil
70421.1SkamilATF_TC(suspend1);
70431.1SkamilATF_TC_HEAD(suspend1, tc)
70441.1Skamil{
70451.1Skamil	atf_tc_set_md_var(tc, "descr",
70461.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
70471.1Skamil	    "resumed by a tracee");
70481.1Skamil}
70491.1Skamil
70501.1SkamilATF_TC_BODY(suspend1, tc)
70511.1Skamil{
70521.1Skamil	const int exitval = 5;
70531.1Skamil	const int sigval = SIGSTOP;
70541.1Skamil	pid_t child, wpid;
70551.1Skamil#if defined(TWAIT_HAVE_STATUS)
70561.1Skamil	int status;
70571.1Skamil#endif
70581.1Skamil	ucontext_t uc;
70591.1Skamil	lwpid_t lid;
70601.1Skamil	static const size_t ssize = 16*1024;
70611.1Skamil	void *stack;
70621.1Skamil	struct ptrace_lwpinfo pl;
70631.1Skamil	struct ptrace_siginfo psi;
70641.1Skamil	volatile int go = 0;
70651.1Skamil
70661.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
70671.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
70681.1Skamil	if (child == 0) {
70691.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
70701.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
70711.1Skamil
70721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
70731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
70741.1Skamil
70751.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
70761.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
70771.1Skamil
70781.13Schristos		DPRINTF("Before making context for new lwp in child\n");
70791.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
70801.1Skamil
70811.13Schristos		DPRINTF("Before creating new in child\n");
70821.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
70831.1Skamil
70841.1Skamil		while (go == 0)
70851.1Skamil			continue;
70861.1Skamil
70871.1Skamil		raise(SIGINT);
70881.1Skamil
70891.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
70901.1Skamil
70911.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
70921.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
70931.1Skamil
70941.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
70951.1Skamil		    "are the same\n", lid, the_lwp_id);
70961.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
70971.1Skamil
70981.13Schristos		DPRINTF("Before exiting of the child process\n");
70991.1Skamil		_exit(exitval);
71001.1Skamil	}
71011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
71021.1Skamil
71031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
71041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71051.1Skamil
71061.1Skamil	validate_status_stopped(status, sigval);
71071.1Skamil
71081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
71091.1Skamil	    "without signal to be sent\n");
71101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
71111.1Skamil
71121.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
71131.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
71141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71151.1Skamil
71161.1Skamil	validate_status_stopped(status, SIGTRAP);
71171.1Skamil
71181.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
71191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
71201.1Skamil
71211.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
71221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
71231.1Skamil
71241.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
71251.1Skamil	    child, getpid());
71261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
71271.1Skamil
71281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
71291.1Skamil	    "without signal to be sent\n");
71301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
71311.1Skamil
71321.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
71331.1Skamil	    "SIGINT\n", TWAIT_FNAME);
71341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71351.1Skamil
71361.1Skamil	validate_status_stopped(status, SIGINT);
71371.1Skamil
71381.1Skamil	pl.pl_lwpid = 0;
71391.1Skamil
71401.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
71411.1Skamil	while (pl.pl_lwpid != 0) {
71421.1Skamil
71431.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
71441.1Skamil		switch (pl.pl_lwpid) {
71451.1Skamil		case 1:
71461.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
71471.1Skamil			break;
71481.1Skamil		case 2:
71491.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
71501.1Skamil			break;
71511.1Skamil		}
71521.1Skamil	}
71531.1Skamil
71541.13Schristos	DPRINTF("Before resuming the child process where it left off and "
71551.1Skamil	    "without signal to be sent\n");
71561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
71571.1Skamil
71581.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
71591.1Skamil	    TWAIT_FNAME);
71601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
71611.1Skamil
71621.1Skamil	validate_status_exited(status, exitval);
71631.1Skamil
71641.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
71651.1Skamil	    TWAIT_FNAME);
71661.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
71671.1Skamil}
71681.1Skamil
71691.1SkamilATF_TC(suspend2);
71701.1SkamilATF_TC_HEAD(suspend2, tc)
71711.1Skamil{
71721.1Skamil	atf_tc_set_md_var(tc, "descr",
71731.1Skamil	    "Verify that the while the only thread within a process is "
71741.1Skamil	    "suspended, the whole process cannot be unstopped");
71751.1Skamil}
71761.1Skamil
71771.1SkamilATF_TC_BODY(suspend2, tc)
71781.1Skamil{
71791.1Skamil	const int exitval = 5;
71801.1Skamil	const int sigval = SIGSTOP;
71811.1Skamil	pid_t child, wpid;
71821.1Skamil#if defined(TWAIT_HAVE_STATUS)
71831.1Skamil	int status;
71841.1Skamil#endif
71851.1Skamil	struct ptrace_siginfo psi;
71861.1Skamil
71871.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
71881.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
71891.1Skamil	if (child == 0) {
71901.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
71911.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
71921.1Skamil
71931.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
71941.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
71951.1Skamil
71961.13Schristos		DPRINTF("Before exiting of the child process\n");
71971.1Skamil		_exit(exitval);
71981.1Skamil	}
71991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
72001.1Skamil
72011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
72021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
72031.1Skamil
72041.1Skamil	validate_status_stopped(status, sigval);
72051.1Skamil
72061.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
72071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
72081.1Skamil
72091.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
72101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
72111.1Skamil
72121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
72131.1Skamil	    "without signal to be sent\n");
72141.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
72151.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
72161.1Skamil
72171.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
72181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
72191.1Skamil
72201.13Schristos	DPRINTF("Before resuming the child process where it left off and "
72211.1Skamil	    "without signal to be sent\n");
72221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
72231.1Skamil
72241.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
72251.1Skamil	    TWAIT_FNAME);
72261.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
72271.1Skamil
72281.1Skamil	validate_status_exited(status, exitval);
72291.1Skamil
72301.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
72311.1Skamil	    TWAIT_FNAME);
72321.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
72331.1Skamil}
72341.1Skamil
72351.1SkamilATF_TC(resume1);
72361.1SkamilATF_TC_HEAD(resume1, tc)
72371.1Skamil{
72381.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
72391.1Skamil	atf_tc_set_md_var(tc, "descr",
72401.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
72411.1Skamil	    "resumed by the debugger");
72421.1Skamil}
72431.1Skamil
72441.1SkamilATF_TC_BODY(resume1, tc)
72451.1Skamil{
72461.1Skamil	struct msg_fds fds;
72471.1Skamil	const int exitval = 5;
72481.1Skamil	const int sigval = SIGSTOP;
72491.1Skamil	pid_t child, wpid;
72501.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
72511.1Skamil#if defined(TWAIT_HAVE_STATUS)
72521.1Skamil	int status;
72531.1Skamil#endif
72541.1Skamil	ucontext_t uc;
72551.1Skamil	lwpid_t lid;
72561.1Skamil	static const size_t ssize = 16*1024;
72571.1Skamil	void *stack;
72581.1Skamil	struct ptrace_lwpinfo pl;
72591.1Skamil	struct ptrace_siginfo psi;
72601.1Skamil
72611.13Schristos	// Times out
72621.1Skamil	atf_tc_expect_timeout("PR kern/51995");
72631.1Skamil
72641.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
72651.1Skamil
72661.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
72671.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
72681.1Skamil	if (child == 0) {
72691.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
72701.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
72711.1Skamil
72721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
72731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
72741.1Skamil
72751.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
72761.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
72771.1Skamil
72781.13Schristos		DPRINTF("Before making context for new lwp in child\n");
72791.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
72801.1Skamil
72811.13Schristos		DPRINTF("Before creating new in child\n");
72821.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
72831.1Skamil
72841.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
72851.1Skamil
72861.1Skamil		raise(SIGINT);
72871.1Skamil
72881.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
72891.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
72901.1Skamil
72911.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
72921.1Skamil		    "are the same\n", lid, the_lwp_id);
72931.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
72941.1Skamil
72951.13Schristos		DPRINTF("Before exiting of the child process\n");
72961.1Skamil		_exit(exitval);
72971.1Skamil	}
72981.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
72991.1Skamil
73001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
73011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73021.1Skamil
73031.1Skamil	validate_status_stopped(status, sigval);
73041.1Skamil
73051.13Schristos	DPRINTF("Before resuming the child process where it left off and "
73061.1Skamil	    "without signal to be sent\n");
73071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
73081.1Skamil
73091.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
73101.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
73111.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73121.1Skamil
73131.1Skamil	validate_status_stopped(status, SIGTRAP);
73141.1Skamil
73151.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
73161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
73171.1Skamil
73181.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
73191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
73201.1Skamil
73211.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
73221.1Skamil
73231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
73241.1Skamil	    "without signal to be sent\n");
73251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
73261.1Skamil
73271.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
73281.1Skamil	    "SIGINT\n", TWAIT_FNAME);
73291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73301.1Skamil
73311.1Skamil	validate_status_stopped(status, SIGINT);
73321.1Skamil
73331.1Skamil	pl.pl_lwpid = 0;
73341.1Skamil
73351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
73361.1Skamil	while (pl.pl_lwpid != 0) {
73371.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
73381.1Skamil		switch (pl.pl_lwpid) {
73391.1Skamil		case 1:
73401.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
73411.1Skamil			break;
73421.1Skamil		case 2:
73431.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
73441.1Skamil			break;
73451.1Skamil		}
73461.1Skamil	}
73471.1Skamil
73481.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
73491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
73501.1Skamil
73511.13Schristos	DPRINTF("Before resuming the child process where it left off and "
73521.1Skamil	    "without signal to be sent\n");
73531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
73541.1Skamil
73551.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
73561.1Skamil	    TWAIT_FNAME);
73571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
73581.1Skamil
73591.1Skamil	validate_status_exited(status, exitval);
73601.1Skamil
73611.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
73621.1Skamil	    TWAIT_FNAME);
73631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
73641.1Skamil
73651.1Skamil	msg_close(&fds);
73661.1Skamil
73671.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
73681.1Skamil	sleep(10);
73691.1Skamil}
73701.1Skamil
73711.1SkamilATF_TC(syscall1);
73721.1SkamilATF_TC_HEAD(syscall1, tc)
73731.1Skamil{
73741.1Skamil	atf_tc_set_md_var(tc, "descr",
73751.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
73761.1Skamil}
73771.1Skamil
73781.1SkamilATF_TC_BODY(syscall1, tc)
73791.1Skamil{
73801.1Skamil	const int exitval = 5;
73811.1Skamil	const int sigval = SIGSTOP;
73821.1Skamil	pid_t child, wpid;
73831.1Skamil#if defined(TWAIT_HAVE_STATUS)
73841.1Skamil	int status;
73851.1Skamil#endif
73861.1Skamil	struct ptrace_siginfo info;
73871.1Skamil	memset(&info, 0, sizeof(info));
73881.1Skamil
73891.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
73901.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
73911.1Skamil	if (child == 0) {
73921.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
73931.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
73941.1Skamil
73951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
73961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
73971.1Skamil
73981.1Skamil		syscall(SYS_getpid);
73991.1Skamil
74001.13Schristos		DPRINTF("Before exiting of the child process\n");
74011.1Skamil		_exit(exitval);
74021.1Skamil	}
74031.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
74041.1Skamil
74051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74071.1Skamil
74081.1Skamil	validate_status_stopped(status, sigval);
74091.1Skamil
74101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
74111.1Skamil	    "without signal to be sent\n");
74121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
74131.1Skamil
74141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74161.1Skamil
74171.1Skamil	validate_status_stopped(status, SIGTRAP);
74181.1Skamil
74191.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
74201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
74211.1Skamil
74221.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
74231.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
74241.1Skamil
74251.13Schristos	DPRINTF("Before resuming the child process where it left off and "
74261.1Skamil	    "without signal to be sent\n");
74271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
74281.1Skamil
74291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74311.1Skamil
74321.1Skamil	validate_status_stopped(status, SIGTRAP);
74331.1Skamil
74341.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
74351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
74361.1Skamil
74371.13Schristos	DPRINTF("Before checking siginfo_t\n");
74381.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
74391.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
74401.1Skamil
74411.13Schristos	DPRINTF("Before resuming the child process where it left off and "
74421.1Skamil	    "without signal to be sent\n");
74431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
74441.1Skamil
74451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74461.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74471.1Skamil
74481.1Skamil	validate_status_exited(status, exitval);
74491.1Skamil
74501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74511.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
74521.1Skamil}
74531.1Skamil
74541.1SkamilATF_TC(syscallemu1);
74551.1SkamilATF_TC_HEAD(syscallemu1, tc)
74561.1Skamil{
74571.1Skamil	atf_tc_set_md_var(tc, "descr",
74581.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
74591.1Skamil}
74601.1Skamil
74611.1SkamilATF_TC_BODY(syscallemu1, tc)
74621.1Skamil{
74631.1Skamil	const int exitval = 5;
74641.1Skamil	const int sigval = SIGSTOP;
74651.1Skamil	pid_t child, wpid;
74661.1Skamil#if defined(TWAIT_HAVE_STATUS)
74671.1Skamil	int status;
74681.1Skamil#endif
74691.1Skamil
74701.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
74711.6Skamil	/* syscallemu does not work on sparc (32-bit) */
74721.6Skamil	atf_tc_expect_fail("PR kern/52166");
74731.6Skamil#endif
74741.6Skamil
74751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
74761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
74771.1Skamil	if (child == 0) {
74781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
74791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
74801.1Skamil
74811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
74821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
74831.1Skamil
74841.1Skamil		syscall(SYS_exit, 100);
74851.1Skamil
74861.13Schristos		DPRINTF("Before exiting of the child process\n");
74871.1Skamil		_exit(exitval);
74881.1Skamil	}
74891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
74901.1Skamil
74911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
74921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
74931.1Skamil
74941.1Skamil	validate_status_stopped(status, sigval);
74951.1Skamil
74961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
74971.1Skamil	    "without signal to be sent\n");
74981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
74991.1Skamil
75001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
75021.1Skamil
75031.1Skamil	validate_status_stopped(status, SIGTRAP);
75041.1Skamil
75051.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
75061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
75071.1Skamil
75081.13Schristos	DPRINTF("Before resuming the child process where it left off and "
75091.1Skamil	    "without signal to be sent\n");
75101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
75111.1Skamil
75121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
75141.1Skamil
75151.1Skamil	validate_status_stopped(status, SIGTRAP);
75161.1Skamil
75171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
75181.1Skamil	    "without signal to be sent\n");
75191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
75201.1Skamil
75211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
75231.1Skamil
75241.1Skamil	validate_status_exited(status, exitval);
75251.1Skamil
75261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
75271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
75281.1Skamil}
75291.1Skamil
75301.1Skamil#include "t_ptrace_amd64_wait.h"
75311.1Skamil#include "t_ptrace_i386_wait.h"
75321.1Skamil#include "t_ptrace_x86_wait.h"
75331.1Skamil
75341.1SkamilATF_TP_ADD_TCS(tp)
75351.1Skamil{
75361.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
75371.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
75381.1Skamil	ATF_TP_ADD_TC(tp, traceme1);
75391.1Skamil	ATF_TP_ADD_TC(tp, traceme2);
75401.1Skamil	ATF_TP_ADD_TC(tp, traceme3);
75411.1Skamil	ATF_TP_ADD_TC(tp, traceme4);
75421.1Skamil
75431.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
75441.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
75451.1Skamil	ATF_TP_ADD_TC(tp, attach3);
75461.1Skamil	ATF_TP_ADD_TC(tp, attach4);
75471.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
75481.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
75491.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
75501.1Skamil
75511.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
75521.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
75531.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
75541.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
75551.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
75561.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
75571.1Skamil
75581.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork1);
75591.1Skamil	ATF_TP_ADD_TC(tp, fork2);
75601.1Skamil
75611.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork1);
75621.1Skamil	ATF_TP_ADD_TC(tp, vfork2);
75631.1Skamil
75641.1Skamil	ATF_TP_ADD_TC(tp, vforkdone1);
75651.1Skamil	ATF_TP_ADD_TC(tp, vforkdone2);
75661.1Skamil
75671.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
75681.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
75691.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
75701.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
75711.1Skamil
75721.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
75731.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
75741.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
75751.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
75761.1Skamil
75771.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
75781.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
75791.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
75801.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
75811.1Skamil
75821.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
75831.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
75841.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
75851.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
75861.1Skamil
75871.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
75881.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
75891.1Skamil
75901.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
75911.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
75921.1Skamil
75931.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
75941.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
75951.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
75961.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
75971.1Skamil
75981.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
75991.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
76001.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
76011.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
76021.1Skamil
76031.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
76041.1Skamil
76051.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
76061.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
76071.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
76081.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
76091.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
76101.1Skamil
76111.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
76121.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
76131.1Skamil
76141.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
76151.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
76161.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
76171.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
76181.1Skamil
76191.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
76201.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
76211.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
76221.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
76231.2Skamil
76241.1Skamil	ATF_TP_ADD_TC(tp, kill1);
76251.1Skamil	ATF_TP_ADD_TC(tp, kill2);
76261.1Skamil
76271.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
76281.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
76291.1Skamil
76301.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
76311.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
76321.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
76331.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
76341.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
76351.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
76361.1Skamil
76371.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
76381.1Skamil
76391.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
76401.1Skamil
76411.1Skamil	ATF_TP_ADD_TC(tp, signal1);
76421.1Skamil	ATF_TP_ADD_TC(tp, signal2);
76431.1Skamil	ATF_TP_ADD_TC(tp, signal3);
76441.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
76451.1Skamil	ATF_TP_ADD_TC(tp, signal5);
76461.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
76471.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
76481.1Skamil	ATF_TP_ADD_TC(tp, signal8);
76491.1Skamil	ATF_TP_ADD_TC(tp, signal9);
76501.1Skamil	ATF_TP_ADD_TC(tp, signal10);
76511.1Skamil
76521.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
76531.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
76541.1Skamil
76551.1Skamil	ATF_TP_ADD_TC(tp, resume1);
76561.1Skamil
76571.1Skamil	ATF_TP_ADD_TC(tp, getsigmask1);
76581.1Skamil	ATF_TP_ADD_TC(tp, getsigmask2);
76591.1Skamil
76601.1Skamil	ATF_TP_ADD_TC(tp, setsigmask1);
76611.1Skamil	ATF_TP_ADD_TC(tp, setsigmask2);
76621.1Skamil	ATF_TP_ADD_TC(tp, setsigmask3);
76631.1Skamil	ATF_TP_ADD_TC(tp, setsigmask4);
76641.1Skamil	ATF_TP_ADD_TC(tp, setsigmask5);
76651.1Skamil	ATF_TP_ADD_TC(tp, setsigmask6);
76661.1Skamil
76671.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
76681.1Skamil
76691.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
76701.1Skamil
76711.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
76721.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
76731.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
76741.1Skamil
76751.1Skamil	return atf_no_error();
76761.1Skamil}
7677