t_ptrace_wait.c revision 1.40
11.40Skamil/*	$NetBSD: t_ptrace_wait.c,v 1.40 2018/05/16 00:42:15 kamil Exp $	*/
21.1Skamil
31.1Skamil/*-
41.1Skamil * Copyright (c) 2016 The NetBSD Foundation, Inc.
51.1Skamil * All rights reserved.
61.1Skamil *
71.1Skamil * Redistribution and use in source and binary forms, with or without
81.1Skamil * modification, are permitted provided that the following conditions
91.1Skamil * are met:
101.1Skamil * 1. Redistributions of source code must retain the above copyright
111.1Skamil *    notice, this list of conditions and the following disclaimer.
121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright
131.1Skamil *    notice, this list of conditions and the following disclaimer in the
141.1Skamil *    documentation and/or other materials provided with the distribution.
151.1Skamil *
161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Skamil * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Skamil * POSSIBILITY OF SUCH DAMAGE.
271.1Skamil */
281.1Skamil
291.1Skamil#include <sys/cdefs.h>
301.40Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.40 2018/05/16 00:42:15 kamil Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/types.h>
341.39Skamil#include <sys/mman.h>
351.1Skamil#include <sys/ptrace.h>
361.1Skamil#include <sys/resource.h>
371.1Skamil#include <sys/stat.h>
381.1Skamil#include <sys/syscall.h>
391.1Skamil#include <sys/sysctl.h>
401.1Skamil#include <sys/wait.h>
411.1Skamil#include <machine/reg.h>
421.1Skamil#include <elf.h>
431.1Skamil#include <err.h>
441.1Skamil#include <errno.h>
451.1Skamil#include <lwp.h>
461.1Skamil#include <sched.h>
471.1Skamil#include <signal.h>
481.1Skamil#include <stdint.h>
491.1Skamil#include <stdio.h>
501.1Skamil#include <stdlib.h>
511.1Skamil#include <strings.h>
521.26Skamil#include <time.h>
531.1Skamil#include <unistd.h>
541.1Skamil
551.1Skamil#include <atf-c.h>
561.1Skamil
571.1Skamil#include "h_macros.h"
581.1Skamil
591.1Skamil#include "t_ptrace_wait.h"
601.1Skamil#include "msg.h"
611.1Skamil
621.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \
631.13Schristos    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
641.1Skamil
651.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \
661.1Skamil    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
671.1Skamil
681.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \
691.1Skamil    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
701.1Skamil
711.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \
721.13Schristos    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
731.13Schristos
741.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
751.13Schristos    strerror(errno))
761.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
771.18Schristos    "%d(%s) != %d", res, strerror(res), exp)
781.13Schristos
791.13Schristosstatic int debug = 0;
801.13Schristos
811.13Schristos#define DPRINTF(a, ...)	do  \
821.13Schristos	if (debug) printf(a,  ##__VA_ARGS__); \
831.13Schristos    while (/*CONSTCOND*/0)
841.1Skamil
851.34Skamil/// ----------------------------------------------------------------------------
861.34Skamil
871.33Skamilstatic void
881.33Skamiltraceme_raise(int sigval)
891.1Skamil{
901.1Skamil	const int exitval = 5;
911.1Skamil	pid_t child, wpid;
921.1Skamil#if defined(TWAIT_HAVE_STATUS)
931.1Skamil	int status;
941.1Skamil#endif
951.1Skamil
961.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
971.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
981.1Skamil	if (child == 0) {
991.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1001.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1011.1Skamil
1021.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1031.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1041.1Skamil
1051.36Skamil		switch (sigval) {
1061.36Skamil		case SIGKILL:
1071.36Skamil			/* NOTREACHED */
1081.36Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
1091.36Skamil		default:
1101.36Skamil			DPRINTF("Before exiting of the child process\n");
1111.36Skamil			_exit(exitval);
1121.36Skamil		}
1131.1Skamil	}
1141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1151.1Skamil
1161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1181.1Skamil
1191.36Skamil	switch (sigval) {
1201.36Skamil	case SIGKILL:
1211.36Skamil		validate_status_signaled(status, sigval, 0);
1221.36Skamil		break;
1231.36Skamil	default:
1241.36Skamil		validate_status_stopped(status, sigval);
1251.1Skamil
1261.36Skamil		DPRINTF("Before resuming the child process where it left off "
1271.36Skamil		    "and without signal to be sent\n");
1281.36Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1291.1Skamil
1301.36Skamil		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1311.36Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1321.36Skamil		                      child);
1331.36Skamil		break;
1341.36Skamil	}
1351.1Skamil
1361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1371.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1381.1Skamil}
1391.1Skamil
1401.33Skamil#define TRACEME_RAISE(test, sig)						\
1411.33SkamilATF_TC(test);									\
1421.33SkamilATF_TC_HEAD(test, tc)								\
1431.33Skamil{										\
1441.33Skamil	atf_tc_set_md_var(tc, "descr",						\
1451.33Skamil	    "Verify " #sig " followed by _exit(2) in a child");			\
1461.33Skamil}										\
1471.33Skamil										\
1481.33SkamilATF_TC_BODY(test, tc)								\
1491.33Skamil{										\
1501.33Skamil										\
1511.33Skamil	traceme_raise(sig);							\
1521.33Skamil}
1531.33Skamil
1541.36SkamilTRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
1551.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
1561.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
1571.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
1581.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
1591.33Skamil
1601.34Skamil/// ----------------------------------------------------------------------------
1611.1Skamil
1621.1Skamilstatic void
1631.34Skamiltraceme_sighandler_catch(int sigsent, void (*sah)(int arg), int *traceme_caught)
1641.1Skamil{
1651.1Skamil	const int exitval = 5;
1661.34Skamil	const int sigval = SIGSTOP;
1671.1Skamil	pid_t child, wpid;
1681.1Skamil	struct sigaction sa;
1691.1Skamil#if defined(TWAIT_HAVE_STATUS)
1701.1Skamil	int status;
1711.1Skamil#endif
1721.1Skamil
1731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
1741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
1751.1Skamil	if (child == 0) {
1761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1781.1Skamil
1791.34Skamil		sa.sa_handler = sah;
1801.1Skamil		sa.sa_flags = SA_SIGINFO;
1811.1Skamil		sigemptyset(&sa.sa_mask);
1821.1Skamil
1831.1Skamil		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1841.1Skamil
1851.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1861.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
1871.1Skamil
1881.34Skamil		FORKEE_ASSERT_EQ(*traceme_caught, 1);
1891.1Skamil
1901.13Schristos		DPRINTF("Before exiting of the child process\n");
1911.1Skamil		_exit(exitval);
1921.1Skamil	}
1931.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1941.1Skamil
1951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1971.1Skamil
1981.1Skamil	validate_status_stopped(status, sigval);
1991.1Skamil
2001.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2011.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2021.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2031.1Skamil
2041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2061.1Skamil
2071.1Skamil	validate_status_exited(status, exitval);
2081.1Skamil
2091.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2111.1Skamil}
2121.1Skamil
2131.34Skamil#define TRACEME_SIGHANDLER_CATCH(test, sig)					\
2141.34SkamilATF_TC(test);									\
2151.34SkamilATF_TC_HEAD(test, tc)								\
2161.34Skamil{										\
2171.34Skamil	atf_tc_set_md_var(tc, "descr",						\
2181.34Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
2191.34Skamil	    "handled correctly and caught by a signal handler");		\
2201.34Skamil}										\
2211.34Skamil										\
2221.34Skamilstatic int test##_caught = 0;							\
2231.34Skamil										\
2241.34Skamilstatic void									\
2251.34Skamiltest##_sighandler(int arg)							\
2261.34Skamil{										\
2271.34Skamil	FORKEE_ASSERT_EQ(arg, sig);						\
2281.34Skamil										\
2291.34Skamil	++ test##_caught;							\
2301.34Skamil}										\
2311.34Skamil										\
2321.34SkamilATF_TC_BODY(test, tc)								\
2331.34Skamil{										\
2341.34Skamil										\
2351.34Skamil	traceme_sighandler_catch(sig, test##_sighandler, & test##_caught);	\
2361.34Skamil}
2371.34Skamil
2381.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered.
2391.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch1, SIGABRT) /* abort trap */
2401.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch2, SIGHUP)  /* hangup */
2411.34SkamilTRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch3, SIGCONT) /* continued? */
2421.34Skamil
2431.34Skamil/// ----------------------------------------------------------------------------
2441.34Skamil
2451.35Skamilstatic void
2461.35Skamiltraceme_signal_nohandler(int sigsent)
2471.1Skamil{
2481.35Skamil	const int sigval = SIGSTOP;
2491.35Skamil	int exitval = 0;
2501.1Skamil	pid_t child, wpid;
2511.1Skamil#if defined(TWAIT_HAVE_STATUS)
2521.1Skamil	int status;
2531.35Skamil	int expect_core = (sigsent == SIGABRT) ? 1 : 0;
2541.1Skamil#endif
2551.1Skamil
2561.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
2571.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
2581.1Skamil	if (child == 0) {
2591.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2601.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2611.1Skamil
2621.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2631.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
2641.1Skamil
2651.35Skamil		switch (sigsent) {
2661.35Skamil		case SIGCONT:
2671.35Skamil			_exit(exitval);
2681.35Skamil		default:
2691.35Skamil			/* NOTREACHED */
2701.35Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
2711.35Skamil		}
2721.1Skamil	}
2731.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2741.1Skamil
2751.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2761.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2771.1Skamil
2781.1Skamil	validate_status_stopped(status, sigval);
2791.1Skamil
2801.13Schristos	DPRINTF("Before resuming the child process where it left off and with "
2811.1Skamil	    "signal %s to be sent\n", strsignal(sigsent));
2821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
2831.1Skamil
2841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2861.1Skamil
2871.35Skamil	switch (sigsent) {
2881.35Skamil	case SIGCONT:
2891.35Skamil		validate_status_exited(status, exitval);
2901.35Skamil		break;
2911.35Skamil	default:
2921.35Skamil		validate_status_signaled(status, sigsent, expect_core);
2931.35Skamil		break;
2941.35Skamil	}
2951.1Skamil
2961.13Schristos	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2971.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2981.1Skamil}
2991.1Skamil
3001.35Skamil#define TRACEME_SIGNAL_NOHANDLER(test, sig)					\
3011.35SkamilATF_TC(test);									\
3021.35SkamilATF_TC_HEAD(test, tc)								\
3031.35Skamil{										\
3041.35Skamil	atf_tc_set_md_var(tc, "descr",						\
3051.35Skamil	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
3061.35Skamil	    "handled correctly in a child without a signal handler");		\
3071.35Skamil}										\
3081.35Skamil										\
3091.35SkamilATF_TC_BODY(test, tc)								\
3101.35Skamil{										\
3111.35Skamil										\
3121.35Skamil	traceme_signal_nohandler(sig);						\
3131.35Skamil}
3141.35Skamil
3151.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */
3161.35Skamil//TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */
3171.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */
3181.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP)  /* hangup */
3191.35SkamilTRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */
3201.35Skamil
3211.35Skamil/// ----------------------------------------------------------------------------
3221.35Skamil
3231.37SkamilATF_TC(traceme_pid1_parent);
3241.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc)
3251.37Skamil{
3261.37Skamil	atf_tc_set_md_var(tc, "descr",
3271.37Skamil	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
3281.37Skamil}
3291.37Skamil
3301.37SkamilATF_TC_BODY(traceme_pid1_parent, tc)
3311.37Skamil{
3321.37Skamil	struct msg_fds parent_child;
3331.37Skamil	int exitval_child1 = 1, exitval_child2 = 2;
3341.37Skamil	pid_t child1, child2, wpid;
3351.37Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3361.37Skamil#if defined(TWAIT_HAVE_STATUS)
3371.37Skamil	int status;
3381.37Skamil#endif
3391.37Skamil
3401.37Skamil	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
3411.37Skamil
3421.37Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
3431.37Skamil	SYSCALL_REQUIRE((child1 = fork()) != -1);
3441.37Skamil	if (child1 == 0) {
3451.37Skamil		DPRINTF("Before forking process PID=%d\n", getpid());
3461.37Skamil		SYSCALL_REQUIRE((child2 = fork()) != -1);
3471.37Skamil		if (child2 != 0) {
3481.37Skamil			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
3491.37Skamil			        getpid(), child2);
3501.37Skamil			_exit(exitval_child1);
3511.37Skamil		}
3521.37Skamil		CHILD_FROM_PARENT("exit child1", parent_child, msg);
3531.37Skamil
3541.37Skamil		DPRINTF("Assert that our parent is PID1 (initproc)\n");
3551.37Skamil		FORKEE_ASSERT_EQ(getppid(), 1);
3561.37Skamil
3571.37Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3581.37Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
3591.37Skamil		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
3601.37Skamil
3611.37Skamil		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
3621.37Skamil
3631.37Skamil		_exit(exitval_child2);
3641.37Skamil	}
3651.37Skamil	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
3661.37Skamil
3671.37Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3681.37Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child1, &status, WEXITED),
3691.37Skamil	                      child1);
3701.37Skamil
3711.37Skamil	validate_status_exited(status, exitval_child1);
3721.37Skamil
3731.37Skamil	DPRINTF("Notify that child1 is dead\n");
3741.37Skamil	PARENT_TO_CHILD("exit child1", parent_child, msg);
3751.37Skamil
3761.37Skamil	DPRINTF("Wait for exiting of child2\n");
3771.37Skamil	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
3781.37Skamil}
3791.37Skamil
3801.37Skamil/// ----------------------------------------------------------------------------
3811.37Skamil
3821.40Skamilstatic void
3831.40Skamiltraceme_vfork_raise(int sigval)
3841.40Skamil{
3851.40Skamil	const int exitval = 5;
3861.40Skamil	pid_t child, wpid;
3871.40Skamil#if defined(TWAIT_HAVE_STATUS)
3881.40Skamil	int status;
3891.40Skamil	int expect_core = (sigval == SIGABRT) ? 1 : 0;
3901.40Skamil#endif
3911.40Skamil
3921.40Skamil	DPRINTF("Before forking process PID=%d\n", getpid());
3931.40Skamil	SYSCALL_REQUIRE((child = vfork()) != -1);
3941.40Skamil	if (child == 0) {
3951.40Skamil		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3961.40Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3971.40Skamil
3981.40Skamil		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3991.40Skamil		FORKEE_ASSERT(raise(sigval) == 0);
4001.40Skamil
4011.40Skamil		switch (sigval) {
4021.40Skamil		case SIGKILL:
4031.40Skamil		case SIGABRT:
4041.40Skamil		case SIGHUP:
4051.40Skamil			/* NOTREACHED */
4061.40Skamil			FORKEE_ASSERTX(0 && "This shall not be reached");
4071.40Skamil		default:
4081.40Skamil			DPRINTF("Before exiting of the child process\n");
4091.40Skamil			_exit(exitval);
4101.40Skamil		}
4111.40Skamil	}
4121.40Skamil	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4131.40Skamil
4141.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4151.40Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4161.40Skamil
4171.40Skamil	switch (sigval) {
4181.40Skamil	case SIGKILL:
4191.40Skamil	case SIGABRT:
4201.40Skamil	case SIGHUP:
4211.40Skamil		validate_status_signaled(status, sigval, expect_core);
4221.40Skamil		break;
4231.40Skamil	case SIGSTOP:
4241.40Skamil	case SIGCONT:
4251.40Skamil		validate_status_exited(status, exitval);
4261.40Skamil		break;
4271.40Skamil	default:
4281.40Skamil		/* NOTREACHED */
4291.40Skamil		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
4301.40Skamil		break;
4311.40Skamil	}
4321.40Skamil
4331.40Skamil	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4341.40Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4351.40Skamil}
4361.40Skamil
4371.40Skamil#define TRACEME_VFORK_RAISE(test, sig)						\
4381.40SkamilATF_TC(test);									\
4391.40SkamilATF_TC_HEAD(test, tc)								\
4401.40Skamil{										\
4411.40Skamil	atf_tc_set_md_var(tc, "descr",						\
4421.40Skamil	    "Verify " #sig " followed by _exit(2) in a vfork(2)ed child");	\
4431.40Skamil}										\
4441.40Skamil										\
4451.40SkamilATF_TC_BODY(test, tc)								\
4461.40Skamil{										\
4471.40Skamil										\
4481.40Skamil	traceme_vfork_raise(sig);						\
4491.40Skamil}
4501.40Skamil
4511.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
4521.40Skamil// TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ // TODO
4531.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGABRT) /* regular abort trap */
4541.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGHUP)  /* hangup */
4551.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGCONT) /* continued? */
4561.40Skamil
4571.40Skamil/// ----------------------------------------------------------------------------
4581.40Skamil
4591.1Skamil#if defined(TWAIT_HAVE_PID)
4601.1SkamilATF_TC(attach1);
4611.1SkamilATF_TC_HEAD(attach1, tc)
4621.1Skamil{
4631.1Skamil	atf_tc_set_md_var(tc, "descr",
4641.1Skamil	    "Assert that tracer sees process termination before the parent");
4651.1Skamil}
4661.1Skamil
4671.26Skamilstatic void
4681.26Skamilattach1_raw(bool raw)
4691.1Skamil{
4701.1Skamil	struct msg_fds parent_tracee, parent_tracer;
4711.1Skamil	const int exitval_tracee = 5;
4721.1Skamil	const int exitval_tracer = 10;
4731.1Skamil	pid_t tracee, tracer, wpid;
4741.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4751.1Skamil#if defined(TWAIT_HAVE_STATUS)
4761.1Skamil	int status;
4771.1Skamil#endif
4781.1Skamil
4791.13Schristos	DPRINTF("Spawn tracee\n");
4801.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4811.1Skamil	tracee = atf_utils_fork();
4821.1Skamil	if (tracee == 0) {
4831.1Skamil		// Wait for parent to let us exit
4841.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
4851.1Skamil		_exit(exitval_tracee);
4861.1Skamil	}
4871.1Skamil
4881.13Schristos	DPRINTF("Spawn debugger\n");
4891.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4901.1Skamil	tracer = atf_utils_fork();
4911.1Skamil	if (tracer == 0) {
4921.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4931.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4941.1Skamil
4951.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4961.1Skamil		FORKEE_REQUIRE_SUCCESS(
4971.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4981.1Skamil
4991.1Skamil		forkee_status_stopped(status, SIGSTOP);
5001.1Skamil
5011.1Skamil		/* Resume tracee with PT_CONTINUE */
5021.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5031.1Skamil
5041.1Skamil		/* Inform parent that tracer has attached to tracee */
5051.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
5061.1Skamil
5071.1Skamil		/* Wait for parent to tell use that tracee should have exited */
5081.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
5091.1Skamil
5101.1Skamil		/* Wait for tracee and assert that it exited */
5111.1Skamil		FORKEE_REQUIRE_SUCCESS(
5121.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5131.1Skamil
5141.1Skamil		forkee_status_exited(status, exitval_tracee);
5151.13Schristos		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
5161.1Skamil
5171.13Schristos		DPRINTF("Before exiting of the tracer process\n");
5181.1Skamil		_exit(exitval_tracer);
5191.1Skamil	}
5201.1Skamil
5211.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
5221.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
5231.1Skamil
5241.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
5251.1Skamil	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
5261.1Skamil
5271.13Schristos	DPRINTF("Detect that tracee is zombie\n");
5281.26Skamil	if (raw)
5291.26Skamil		await_zombie_raw(tracee, 0);
5301.26Skamil	else
5311.26Skamil		await_zombie(tracee);
5321.1Skamil
5331.13Schristos	DPRINTF("Assert that there is no status about tracee %d - "
5341.1Skamil	    "Tracer must detect zombie first - calling %s()\n", tracee,
5351.1Skamil	    TWAIT_FNAME);
5361.1Skamil	TWAIT_REQUIRE_SUCCESS(
5371.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
5381.1Skamil
5391.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
5401.1Skamil	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
5411.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
5421.1Skamil	    TWAIT_FNAME);
5431.1Skamil
5441.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
5451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
5461.1Skamil	    tracer);
5471.1Skamil
5481.1Skamil	validate_status_exited(status, exitval_tracer);
5491.1Skamil
5501.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5511.1Skamil	    TWAIT_FNAME);
5521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
5531.1Skamil	    tracee);
5541.1Skamil
5551.1Skamil	validate_status_exited(status, exitval_tracee);
5561.1Skamil
5571.1Skamil	msg_close(&parent_tracer);
5581.1Skamil	msg_close(&parent_tracee);
5591.1Skamil}
5601.26Skamil
5611.26SkamilATF_TC_BODY(attach1, tc)
5621.26Skamil{
5631.26Skamil
5641.26Skamil	/* Reuse this test with race1 */
5651.26Skamil	attach1_raw(false);
5661.26Skamil}
5671.26Skamil
5681.1Skamil#endif
5691.1Skamil
5701.1Skamil#if defined(TWAIT_HAVE_PID)
5711.1SkamilATF_TC(attach2);
5721.1SkamilATF_TC_HEAD(attach2, tc)
5731.1Skamil{
5741.1Skamil	atf_tc_set_md_var(tc, "descr",
5751.1Skamil	    "Assert that any tracer sees process termination before its "
5761.1Skamil	    "parent");
5771.1Skamil}
5781.1Skamil
5791.1SkamilATF_TC_BODY(attach2, tc)
5801.1Skamil{
5811.1Skamil	struct msg_fds parent_tracer, parent_tracee;
5821.1Skamil	const int exitval_tracee = 5;
5831.1Skamil	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
5841.1Skamil	pid_t tracee, tracer, wpid;
5851.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5861.1Skamil#if defined(TWAIT_HAVE_STATUS)
5871.1Skamil	int status;
5881.1Skamil#endif
5891.1Skamil
5901.13Schristos	DPRINTF("Spawn tracee\n");
5911.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5921.1Skamil	tracee = atf_utils_fork();
5931.1Skamil	if (tracee == 0) {
5941.1Skamil		/* Wait for message from the parent */
5951.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
5961.1Skamil		_exit(exitval_tracee);
5971.1Skamil	}
5981.1Skamil
5991.13Schristos	DPRINTF("Spawn debugger\n");
6001.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
6011.1Skamil	tracer = atf_utils_fork();
6021.1Skamil	if (tracer == 0) {
6031.1Skamil		/* Fork again and drop parent to reattach to PID 1 */
6041.1Skamil		tracer = atf_utils_fork();
6051.1Skamil		if (tracer != 0)
6061.1Skamil			_exit(exitval_tracer1);
6071.1Skamil
6081.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
6091.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
6101.1Skamil
6111.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
6121.1Skamil		FORKEE_REQUIRE_SUCCESS(
6131.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6141.1Skamil
6151.1Skamil		forkee_status_stopped(status, SIGSTOP);
6161.1Skamil
6171.1Skamil		/* Resume tracee with PT_CONTINUE */
6181.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
6191.1Skamil
6201.1Skamil		/* Inform parent that tracer has attached to tracee */
6211.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
6221.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
6231.1Skamil
6241.1Skamil		/* Wait for tracee and assert that it exited */
6251.1Skamil		FORKEE_REQUIRE_SUCCESS(
6261.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
6271.1Skamil
6281.1Skamil		forkee_status_exited(status, exitval_tracee);
6291.1Skamil
6301.13Schristos		DPRINTF("Before exiting of the tracer process\n");
6311.1Skamil		_exit(exitval_tracer2);
6321.1Skamil	}
6331.13Schristos	DPRINTF("Wait for the tracer process (direct child) to exit calling "
6341.1Skamil	    "%s()\n", TWAIT_FNAME);
6351.1Skamil	TWAIT_REQUIRE_SUCCESS(
6361.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
6371.1Skamil
6381.1Skamil	validate_status_exited(status, exitval_tracer1);
6391.1Skamil
6401.13Schristos	DPRINTF("Wait for the non-exited tracee process with %s()\n",
6411.1Skamil	    TWAIT_FNAME);
6421.1Skamil	TWAIT_REQUIRE_SUCCESS(
6431.1Skamil	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
6441.1Skamil
6451.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
6461.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
6471.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
6481.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
6491.1Skamil
6501.13Schristos	DPRINTF("Detect that tracee is zombie\n");
6511.1Skamil	await_zombie(tracee);
6521.1Skamil
6531.13Schristos	DPRINTF("Assert that there is no status about tracee - "
6541.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
6551.1Skamil	TWAIT_REQUIRE_SUCCESS(
6561.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
6571.1Skamil
6581.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
6591.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
6601.1Skamil
6611.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
6621.1Skamil	    TWAIT_FNAME);
6631.24Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
6641.1Skamil	    tracee);
6651.1Skamil
6661.1Skamil	validate_status_exited(status, exitval_tracee);
6671.1Skamil
6681.1Skamil	msg_close(&parent_tracer);
6691.1Skamil	msg_close(&parent_tracee);
6701.1Skamil}
6711.1Skamil#endif
6721.1Skamil
6731.1SkamilATF_TC(attach3);
6741.1SkamilATF_TC_HEAD(attach3, tc)
6751.1Skamil{
6761.1Skamil	atf_tc_set_md_var(tc, "descr",
6771.1Skamil	    "Assert that tracer parent can PT_ATTACH to its child");
6781.1Skamil}
6791.1Skamil
6801.1SkamilATF_TC_BODY(attach3, tc)
6811.1Skamil{
6821.1Skamil	struct msg_fds parent_tracee;
6831.1Skamil	const int exitval_tracee = 5;
6841.1Skamil	pid_t tracee, wpid;
6851.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6861.1Skamil#if defined(TWAIT_HAVE_STATUS)
6871.1Skamil	int status;
6881.1Skamil#endif
6891.1Skamil
6901.13Schristos	DPRINTF("Spawn tracee\n");
6911.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
6921.1Skamil	tracee = atf_utils_fork();
6931.1Skamil	if (tracee == 0) {
6941.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
6951.13Schristos		DPRINTF("Parent should now attach to tracee\n");
6961.1Skamil
6971.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
6981.1Skamil		/* Wait for message from the parent */
6991.1Skamil		_exit(exitval_tracee);
7001.1Skamil	}
7011.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
7021.1Skamil
7031.13Schristos	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
7041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
7051.1Skamil
7061.13Schristos	DPRINTF("Wait for the stopped tracee process with %s()\n",
7071.1Skamil	    TWAIT_FNAME);
7081.1Skamil	TWAIT_REQUIRE_SUCCESS(
7091.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7101.1Skamil
7111.1Skamil	validate_status_stopped(status, SIGSTOP);
7121.1Skamil
7131.13Schristos	DPRINTF("Resume tracee with PT_CONTINUE\n");
7141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
7151.1Skamil
7161.13Schristos	DPRINTF("Let the tracee exit now\n");
7171.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
7181.1Skamil
7191.13Schristos	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
7201.1Skamil	TWAIT_REQUIRE_SUCCESS(
7211.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
7221.1Skamil
7231.1Skamil	validate_status_exited(status, exitval_tracee);
7241.1Skamil
7251.13Schristos	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
7261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
7271.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, 0));
7281.1Skamil
7291.1Skamil	msg_close(&parent_tracee);
7301.1Skamil}
7311.1Skamil
7321.1SkamilATF_TC(attach4);
7331.1SkamilATF_TC_HEAD(attach4, tc)
7341.1Skamil{
7351.1Skamil	atf_tc_set_md_var(tc, "descr",
7361.1Skamil	    "Assert that tracer child can PT_ATTACH to its parent");
7371.1Skamil}
7381.1Skamil
7391.1SkamilATF_TC_BODY(attach4, tc)
7401.1Skamil{
7411.1Skamil	struct msg_fds parent_tracee;
7421.1Skamil	const int exitval_tracer = 5;
7431.1Skamil	pid_t tracer, wpid;
7441.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
7451.1Skamil#if defined(TWAIT_HAVE_STATUS)
7461.1Skamil	int status;
7471.1Skamil#endif
7481.1Skamil
7491.13Schristos	DPRINTF("Spawn tracer\n");
7501.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
7511.1Skamil	tracer = atf_utils_fork();
7521.1Skamil	if (tracer == 0) {
7531.1Skamil
7541.1Skamil		/* Wait for message from the parent */
7551.1Skamil		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
7561.1Skamil
7571.13Schristos		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
7581.1Skamil		    getppid());
7591.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
7601.1Skamil
7611.13Schristos		DPRINTF("Wait for the stopped parent process with %s()\n",
7621.1Skamil		    TWAIT_FNAME);
7631.1Skamil		FORKEE_REQUIRE_SUCCESS(
7641.1Skamil		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
7651.1Skamil
7661.1Skamil		forkee_status_stopped(status, SIGSTOP);
7671.1Skamil
7681.13Schristos		DPRINTF("Resume parent with PT_DETACH\n");
7691.1Skamil		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
7701.1Skamil		    != -1);
7711.1Skamil
7721.1Skamil		/* Tell parent we are ready */
7731.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
7741.1Skamil
7751.1Skamil		_exit(exitval_tracer);
7761.1Skamil	}
7771.1Skamil
7781.13Schristos	DPRINTF("Wait for the tracer to become ready\n");
7791.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
7801.13Schristos	DPRINTF("Allow the tracer to exit now\n");
7811.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
7821.1Skamil
7831.13Schristos	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
7841.1Skamil	TWAIT_REQUIRE_SUCCESS(
7851.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
7861.1Skamil
7871.1Skamil	validate_status_exited(status, exitval_tracer);
7881.1Skamil
7891.13Schristos	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
7901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
7911.1Skamil	    wpid = TWAIT_GENERIC(tracer, &status, 0));
7921.1Skamil
7931.1Skamil	msg_close(&parent_tracee);
7941.1Skamil}
7951.1Skamil
7961.1Skamil#if defined(TWAIT_HAVE_PID)
7971.1SkamilATF_TC(attach5);
7981.1SkamilATF_TC_HEAD(attach5, tc)
7991.1Skamil{
8001.1Skamil	atf_tc_set_md_var(tc, "descr",
8011.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
8021.1Skamil	    "(check getppid(2))");
8031.1Skamil}
8041.1Skamil
8051.1SkamilATF_TC_BODY(attach5, tc)
8061.1Skamil{
8071.1Skamil	struct msg_fds parent_tracer, parent_tracee;
8081.1Skamil	const int exitval_tracee = 5;
8091.1Skamil	const int exitval_tracer = 10;
8101.1Skamil	pid_t parent, tracee, tracer, wpid;
8111.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
8121.1Skamil#if defined(TWAIT_HAVE_STATUS)
8131.1Skamil	int status;
8141.1Skamil#endif
8151.1Skamil
8161.13Schristos	DPRINTF("Spawn tracee\n");
8171.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
8181.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
8191.1Skamil	tracee = atf_utils_fork();
8201.1Skamil	if (tracee == 0) {
8211.1Skamil		parent = getppid();
8221.1Skamil
8231.1Skamil		/* Emit message to the parent */
8241.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
8251.1Skamil		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
8261.1Skamil
8271.1Skamil		FORKEE_ASSERT_EQ(parent, getppid());
8281.1Skamil
8291.1Skamil		_exit(exitval_tracee);
8301.1Skamil	}
8311.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
8321.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
8331.1Skamil
8341.13Schristos	DPRINTF("Spawn debugger\n");
8351.1Skamil	tracer = atf_utils_fork();
8361.1Skamil	if (tracer == 0) {
8371.1Skamil		/* No IPC to communicate with the child */
8381.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
8391.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
8401.1Skamil
8411.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
8421.1Skamil		FORKEE_REQUIRE_SUCCESS(
8431.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8441.1Skamil
8451.1Skamil		forkee_status_stopped(status, SIGSTOP);
8461.1Skamil
8471.1Skamil		/* Resume tracee with PT_CONTINUE */
8481.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
8491.1Skamil
8501.1Skamil		/* Inform parent that tracer has attached to tracee */
8511.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
8521.1Skamil
8531.1Skamil		/* Wait for parent to tell use that tracee should have exited */
8541.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
8551.1Skamil
8561.1Skamil		/* Wait for tracee and assert that it exited */
8571.1Skamil		FORKEE_REQUIRE_SUCCESS(
8581.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
8591.1Skamil
8601.1Skamil		forkee_status_exited(status, exitval_tracee);
8611.1Skamil
8621.13Schristos		DPRINTF("Before exiting of the tracer process\n");
8631.1Skamil		_exit(exitval_tracer);
8641.1Skamil	}
8651.1Skamil
8661.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
8671.1Skamil	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
8681.1Skamil
8691.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
8701.1Skamil	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
8711.1Skamil
8721.13Schristos	DPRINTF("Detect that tracee is zombie\n");
8731.1Skamil	await_zombie(tracee);
8741.1Skamil
8751.13Schristos	DPRINTF("Assert that there is no status about tracee - "
8761.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
8771.1Skamil	TWAIT_REQUIRE_SUCCESS(
8781.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
8791.1Skamil
8801.13Schristos	DPRINTF("Tell the tracer child should have exited\n");
8811.1Skamil	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
8821.1Skamil
8831.13Schristos	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
8841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
8851.1Skamil	    tracer);
8861.1Skamil
8871.1Skamil	validate_status_exited(status, exitval_tracer);
8881.1Skamil
8891.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
8901.1Skamil	    TWAIT_FNAME);
8911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
8921.1Skamil	    tracee);
8931.1Skamil
8941.1Skamil	validate_status_exited(status, exitval_tracee);
8951.1Skamil
8961.1Skamil	msg_close(&parent_tracer);
8971.1Skamil	msg_close(&parent_tracee);
8981.1Skamil}
8991.1Skamil#endif
9001.1Skamil
9011.1Skamil#if defined(TWAIT_HAVE_PID)
9021.1SkamilATF_TC(attach6);
9031.1SkamilATF_TC_HEAD(attach6, tc)
9041.1Skamil{
9051.1Skamil	atf_tc_set_md_var(tc, "descr",
9061.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
9071.1Skamil	    "(check sysctl(7) and struct kinfo_proc2)");
9081.1Skamil}
9091.1Skamil
9101.1SkamilATF_TC_BODY(attach6, tc)
9111.1Skamil{
9121.1Skamil	struct msg_fds parent_tracee, parent_tracer;
9131.1Skamil	const int exitval_tracee = 5;
9141.1Skamil	const int exitval_tracer = 10;
9151.1Skamil	pid_t parent, tracee, tracer, wpid;
9161.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
9171.1Skamil#if defined(TWAIT_HAVE_STATUS)
9181.1Skamil	int status;
9191.1Skamil#endif
9201.1Skamil	int name[CTL_MAXNAME];
9211.1Skamil	struct kinfo_proc2 kp;
9221.1Skamil	size_t len = sizeof(kp);
9231.1Skamil	unsigned int namelen;
9241.1Skamil
9251.13Schristos	DPRINTF("Spawn tracee\n");
9261.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
9271.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
9281.1Skamil	tracee = atf_utils_fork();
9291.1Skamil	if (tracee == 0) {
9301.1Skamil		parent = getppid();
9311.1Skamil
9321.1Skamil		/* Emit message to the parent */
9331.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
9341.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
9351.1Skamil
9361.1Skamil		namelen = 0;
9371.1Skamil		name[namelen++] = CTL_KERN;
9381.1Skamil		name[namelen++] = KERN_PROC2;
9391.1Skamil		name[namelen++] = KERN_PROC_PID;
9401.1Skamil		name[namelen++] = getpid();
9411.1Skamil		name[namelen++] = len;
9421.1Skamil		name[namelen++] = 1;
9431.1Skamil
9441.1Skamil		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
9451.1Skamil		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
9461.1Skamil
9471.1Skamil		_exit(exitval_tracee);
9481.1Skamil	}
9491.1Skamil
9501.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
9511.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
9521.1Skamil
9531.13Schristos	DPRINTF("Spawn debugger\n");
9541.1Skamil	tracer = atf_utils_fork();
9551.1Skamil	if (tracer == 0) {
9561.1Skamil		/* No IPC to communicate with the child */
9571.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
9581.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
9591.1Skamil
9601.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
9611.1Skamil		FORKEE_REQUIRE_SUCCESS(
9621.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9631.1Skamil
9641.1Skamil		forkee_status_stopped(status, SIGSTOP);
9651.1Skamil
9661.1Skamil		/* Resume tracee with PT_CONTINUE */
9671.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
9681.1Skamil
9691.1Skamil		/* Inform parent that tracer has attached to tracee */
9701.1Skamil		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
9711.1Skamil
9721.1Skamil		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
9731.1Skamil
9741.1Skamil		/* Wait for tracee and assert that it exited */
9751.1Skamil		FORKEE_REQUIRE_SUCCESS(
9761.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
9771.1Skamil
9781.1Skamil		forkee_status_exited(status, exitval_tracee);
9791.1Skamil
9801.13Schristos		DPRINTF("Before exiting of the tracer process\n");
9811.1Skamil		_exit(exitval_tracer);
9821.1Skamil	}
9831.1Skamil
9841.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
9851.1Skamil	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
9861.1Skamil
9871.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
9881.1Skamil	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
9891.1Skamil
9901.13Schristos	DPRINTF("Detect that tracee is zombie\n");
9911.1Skamil	await_zombie(tracee);
9921.1Skamil
9931.13Schristos	DPRINTF("Assert that there is no status about tracee - "
9941.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
9951.1Skamil	TWAIT_REQUIRE_SUCCESS(
9961.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
9971.1Skamil
9981.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
9991.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
10001.1Skamil
10011.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
10021.1Skamil	    TWAIT_FNAME);
10031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
10041.1Skamil	    tracer);
10051.1Skamil
10061.1Skamil	validate_status_exited(status, exitval_tracer);
10071.1Skamil
10081.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
10091.1Skamil	    TWAIT_FNAME);
10101.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
10111.1Skamil	    tracee);
10121.1Skamil
10131.1Skamil	validate_status_exited(status, exitval_tracee);
10141.1Skamil
10151.1Skamil	msg_close(&parent_tracee);
10161.1Skamil	msg_close(&parent_tracer);
10171.1Skamil}
10181.1Skamil#endif
10191.1Skamil
10201.1Skamil#if defined(TWAIT_HAVE_PID)
10211.1SkamilATF_TC(attach7);
10221.1SkamilATF_TC_HEAD(attach7, tc)
10231.1Skamil{
10241.1Skamil	atf_tc_set_md_var(tc, "descr",
10251.1Skamil	    "Assert that tracer sees its parent when attached to tracer "
10261.1Skamil	    "(check /proc/curproc/status 3rd column)");
10271.1Skamil}
10281.1Skamil
10291.1SkamilATF_TC_BODY(attach7, tc)
10301.1Skamil{
10311.1Skamil	struct msg_fds parent_tracee, parent_tracer;
10321.1Skamil	int rv;
10331.1Skamil	const int exitval_tracee = 5;
10341.1Skamil	const int exitval_tracer = 10;
10351.1Skamil	pid_t parent, tracee, tracer, wpid;
10361.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
10371.1Skamil#if defined(TWAIT_HAVE_STATUS)
10381.1Skamil	int status;
10391.1Skamil#endif
10401.1Skamil	FILE *fp;
10411.1Skamil	struct stat st;
10421.1Skamil	const char *fname = "/proc/curproc/status";
10431.1Skamil	char s_executable[MAXPATHLEN];
10441.1Skamil	int s_pid, s_ppid;
10451.1Skamil	/*
10461.1Skamil	 * Format:
10471.1Skamil	 *  EXECUTABLE PID PPID ...
10481.1Skamil	 */
10491.1Skamil
10501.13Schristos	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
10511.1Skamil	if (rv != 0) {
10521.1Skamil		atf_tc_skip("/proc/curproc/status not found");
10531.1Skamil	}
10541.1Skamil
10551.13Schristos	DPRINTF("Spawn tracee\n");
10561.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
10571.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
10581.1Skamil	tracee = atf_utils_fork();
10591.1Skamil	if (tracee == 0) {
10601.1Skamil		parent = getppid();
10611.1Skamil
10621.1Skamil		// Wait for parent to let us exit
10631.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
10641.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
10651.1Skamil
10661.1Skamil		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
10671.1Skamil		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
10681.1Skamil		FORKEE_ASSERT(fclose(fp) == 0);
10691.1Skamil		FORKEE_ASSERT_EQ(parent, s_ppid);
10701.1Skamil
10711.1Skamil		_exit(exitval_tracee);
10721.1Skamil	}
10731.1Skamil
10741.13Schristos	DPRINTF("Wait for child to record its parent identifier (pid)\n");
10751.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
10761.1Skamil
10771.13Schristos	DPRINTF("Spawn debugger\n");
10781.1Skamil	tracer = atf_utils_fork();
10791.1Skamil	if (tracer == 0) {
10801.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
10811.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
10821.1Skamil
10831.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
10841.1Skamil		FORKEE_REQUIRE_SUCCESS(
10851.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
10861.1Skamil
10871.1Skamil		forkee_status_stopped(status, SIGSTOP);
10881.1Skamil
10891.1Skamil		/* Resume tracee with PT_CONTINUE */
10901.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
10911.1Skamil
10921.1Skamil		/* Inform parent that tracer has attached to tracee */
10931.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
10941.1Skamil
10951.1Skamil		/* Wait for parent to tell use that tracee should have exited */
10961.1Skamil		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
10971.1Skamil
10981.1Skamil		/* Wait for tracee and assert that it exited */
10991.1Skamil		FORKEE_REQUIRE_SUCCESS(
11001.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
11011.1Skamil
11021.1Skamil		forkee_status_exited(status, exitval_tracee);
11031.1Skamil
11041.13Schristos		DPRINTF("Before exiting of the tracer process\n");
11051.1Skamil		_exit(exitval_tracer);
11061.1Skamil	}
11071.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
11081.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
11091.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
11101.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
11111.1Skamil
11121.13Schristos	DPRINTF("Detect that tracee is zombie\n");
11131.1Skamil	await_zombie(tracee);
11141.1Skamil
11151.13Schristos	DPRINTF("Assert that there is no status about tracee - "
11161.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
11171.1Skamil	TWAIT_REQUIRE_SUCCESS(
11181.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
11191.1Skamil
11201.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
11211.1Skamil	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
11221.1Skamil
11231.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
11241.1Skamil	    TWAIT_FNAME);
11251.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
11261.1Skamil	    tracer);
11271.1Skamil
11281.1Skamil	validate_status_exited(status, exitval_tracer);
11291.1Skamil
11301.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
11311.1Skamil	    TWAIT_FNAME);
11321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
11331.1Skamil	    tracee);
11341.1Skamil
11351.1Skamil	validate_status_exited(status, exitval_tracee);
11361.1Skamil
11371.1Skamil	msg_close(&parent_tracee);
11381.1Skamil	msg_close(&parent_tracer);
11391.1Skamil}
11401.1Skamil#endif
11411.1Skamil
11421.1SkamilATF_TC(eventmask1);
11431.1SkamilATF_TC_HEAD(eventmask1, tc)
11441.1Skamil{
11451.1Skamil	atf_tc_set_md_var(tc, "descr",
11461.1Skamil	    "Verify that empty EVENT_MASK is preserved");
11471.1Skamil}
11481.1Skamil
11491.1SkamilATF_TC_BODY(eventmask1, tc)
11501.1Skamil{
11511.1Skamil	const int exitval = 5;
11521.1Skamil	const int sigval = SIGSTOP;
11531.1Skamil	pid_t child, wpid;
11541.1Skamil#if defined(TWAIT_HAVE_STATUS)
11551.1Skamil	int status;
11561.1Skamil#endif
11571.1Skamil	ptrace_event_t set_event, get_event;
11581.1Skamil	const int len = sizeof(ptrace_event_t);
11591.1Skamil
11601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
11611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
11621.1Skamil	if (child == 0) {
11631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
11641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
11651.1Skamil
11661.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
11671.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
11681.1Skamil
11691.13Schristos		DPRINTF("Before exiting of the child process\n");
11701.1Skamil		_exit(exitval);
11711.1Skamil	}
11721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
11731.1Skamil
11741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11761.1Skamil
11771.1Skamil	validate_status_stopped(status, sigval);
11781.1Skamil
11791.1Skamil	set_event.pe_set_event = 0;
11801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
11811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
11821.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
11831.1Skamil
11841.13Schristos	DPRINTF("Before resuming the child process where it left off and "
11851.1Skamil	    "without signal to be sent\n");
11861.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
11871.1Skamil
11881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
11901.1Skamil
11911.1Skamil	validate_status_exited(status, exitval);
11921.1Skamil
11931.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
11941.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
11951.1Skamil}
11961.1Skamil
11971.1SkamilATF_TC(eventmask2);
11981.1SkamilATF_TC_HEAD(eventmask2, tc)
11991.1Skamil{
12001.1Skamil	atf_tc_set_md_var(tc, "descr",
12011.1Skamil	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
12021.1Skamil}
12031.1Skamil
12041.1SkamilATF_TC_BODY(eventmask2, tc)
12051.1Skamil{
12061.1Skamil	const int exitval = 5;
12071.1Skamil	const int sigval = SIGSTOP;
12081.1Skamil	pid_t child, wpid;
12091.1Skamil#if defined(TWAIT_HAVE_STATUS)
12101.1Skamil	int status;
12111.1Skamil#endif
12121.1Skamil	ptrace_event_t set_event, get_event;
12131.1Skamil	const int len = sizeof(ptrace_event_t);
12141.1Skamil
12151.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12161.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12171.1Skamil	if (child == 0) {
12181.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12191.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12201.1Skamil
12211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12231.1Skamil
12241.13Schristos		DPRINTF("Before exiting of the child process\n");
12251.1Skamil		_exit(exitval);
12261.1Skamil	}
12271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12281.1Skamil
12291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12311.1Skamil
12321.1Skamil	validate_status_stopped(status, sigval);
12331.1Skamil
12341.1Skamil	set_event.pe_set_event = PTRACE_FORK;
12351.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12371.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12381.1Skamil
12391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12401.1Skamil	    "without signal to be sent\n");
12411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12421.1Skamil
12431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12451.1Skamil
12461.1Skamil	validate_status_exited(status, exitval);
12471.1Skamil
12481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
12501.1Skamil}
12511.1Skamil
12521.1SkamilATF_TC(eventmask3);
12531.1SkamilATF_TC_HEAD(eventmask3, tc)
12541.1Skamil{
12551.1Skamil	atf_tc_set_md_var(tc, "descr",
12561.1Skamil	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
12571.1Skamil}
12581.1Skamil
12591.1SkamilATF_TC_BODY(eventmask3, tc)
12601.1Skamil{
12611.1Skamil	const int exitval = 5;
12621.1Skamil	const int sigval = SIGSTOP;
12631.1Skamil	pid_t child, wpid;
12641.1Skamil#if defined(TWAIT_HAVE_STATUS)
12651.1Skamil	int status;
12661.1Skamil#endif
12671.1Skamil	ptrace_event_t set_event, get_event;
12681.1Skamil	const int len = sizeof(ptrace_event_t);
12691.1Skamil
12701.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
12711.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
12721.1Skamil	if (child == 0) {
12731.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
12741.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
12751.1Skamil
12761.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
12771.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
12781.1Skamil
12791.13Schristos		DPRINTF("Before exiting of the child process\n");
12801.1Skamil		_exit(exitval);
12811.1Skamil	}
12821.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
12831.1Skamil
12841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
12861.1Skamil
12871.1Skamil	validate_status_stopped(status, sigval);
12881.1Skamil
12891.1Skamil	set_event.pe_set_event = PTRACE_VFORK;
12901.38Skamil	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
12911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
12921.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
12931.1Skamil
12941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
12951.1Skamil	    "without signal to be sent\n");
12961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
12971.1Skamil
12981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
12991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13001.1Skamil
13011.1Skamil	validate_status_exited(status, exitval);
13021.1Skamil
13031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13051.1Skamil}
13061.1Skamil
13071.1SkamilATF_TC(eventmask4);
13081.1SkamilATF_TC_HEAD(eventmask4, tc)
13091.1Skamil{
13101.1Skamil	atf_tc_set_md_var(tc, "descr",
13111.1Skamil	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
13121.1Skamil}
13131.1Skamil
13141.1SkamilATF_TC_BODY(eventmask4, tc)
13151.1Skamil{
13161.1Skamil	const int exitval = 5;
13171.1Skamil	const int sigval = SIGSTOP;
13181.1Skamil	pid_t child, wpid;
13191.1Skamil#if defined(TWAIT_HAVE_STATUS)
13201.1Skamil	int status;
13211.1Skamil#endif
13221.1Skamil	ptrace_event_t set_event, get_event;
13231.1Skamil	const int len = sizeof(ptrace_event_t);
13241.1Skamil
13251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13271.1Skamil	if (child == 0) {
13281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13301.1Skamil
13311.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13321.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13331.1Skamil
13341.13Schristos		DPRINTF("Before exiting of the child process\n");
13351.1Skamil		_exit(exitval);
13361.1Skamil	}
13371.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13381.1Skamil
13391.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13411.1Skamil
13421.1Skamil	validate_status_stopped(status, sigval);
13431.1Skamil
13441.1Skamil	set_event.pe_set_event = PTRACE_VFORK_DONE;
13451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
13461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
13471.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
13481.1Skamil
13491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
13501.1Skamil	    "without signal to be sent\n");
13511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
13521.1Skamil
13531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13551.1Skamil
13561.1Skamil	validate_status_exited(status, exitval);
13571.1Skamil
13581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
13601.1Skamil}
13611.1Skamil
13621.1SkamilATF_TC(eventmask5);
13631.1SkamilATF_TC_HEAD(eventmask5, tc)
13641.1Skamil{
13651.1Skamil	atf_tc_set_md_var(tc, "descr",
13661.1Skamil	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
13671.1Skamil}
13681.1Skamil
13691.1SkamilATF_TC_BODY(eventmask5, tc)
13701.1Skamil{
13711.1Skamil	const int exitval = 5;
13721.1Skamil	const int sigval = SIGSTOP;
13731.1Skamil	pid_t child, wpid;
13741.1Skamil#if defined(TWAIT_HAVE_STATUS)
13751.1Skamil	int status;
13761.1Skamil#endif
13771.1Skamil	ptrace_event_t set_event, get_event;
13781.1Skamil	const int len = sizeof(ptrace_event_t);
13791.1Skamil
13801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
13811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
13821.1Skamil	if (child == 0) {
13831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
13841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
13851.1Skamil
13861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
13871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
13881.1Skamil
13891.13Schristos		DPRINTF("Before exiting of the child process\n");
13901.1Skamil		_exit(exitval);
13911.1Skamil	}
13921.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
13931.1Skamil
13941.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
13951.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
13961.1Skamil
13971.1Skamil	validate_status_stopped(status, sigval);
13981.1Skamil
13991.1Skamil	set_event.pe_set_event = PTRACE_LWP_CREATE;
14001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
14011.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
14021.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
14031.1Skamil
14041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14051.1Skamil	    "without signal to be sent\n");
14061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14071.1Skamil
14081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14101.1Skamil
14111.1Skamil	validate_status_exited(status, exitval);
14121.1Skamil
14131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14151.1Skamil}
14161.1Skamil
14171.1SkamilATF_TC(eventmask6);
14181.1SkamilATF_TC_HEAD(eventmask6, tc)
14191.1Skamil{
14201.1Skamil	atf_tc_set_md_var(tc, "descr",
14211.1Skamil	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
14221.1Skamil}
14231.1Skamil
14241.1SkamilATF_TC_BODY(eventmask6, tc)
14251.1Skamil{
14261.1Skamil	const int exitval = 5;
14271.1Skamil	const int sigval = SIGSTOP;
14281.1Skamil	pid_t child, wpid;
14291.1Skamil#if defined(TWAIT_HAVE_STATUS)
14301.1Skamil	int status;
14311.1Skamil#endif
14321.1Skamil	ptrace_event_t set_event, get_event;
14331.1Skamil	const int len = sizeof(ptrace_event_t);
14341.1Skamil
14351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14371.1Skamil	if (child == 0) {
14381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14401.1Skamil
14411.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14421.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14431.1Skamil
14441.13Schristos		DPRINTF("Before exiting of the child process\n");
14451.1Skamil		_exit(exitval);
14461.1Skamil	}
14471.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
14481.1Skamil
14491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14511.1Skamil
14521.1Skamil	validate_status_stopped(status, sigval);
14531.1Skamil
14541.1Skamil	set_event.pe_set_event = PTRACE_LWP_EXIT;
14551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
14561.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
14571.1Skamil	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
14581.1Skamil
14591.13Schristos	DPRINTF("Before resuming the child process where it left off and "
14601.1Skamil	    "without signal to be sent\n");
14611.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
14621.1Skamil
14631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
14651.1Skamil
14661.1Skamil	validate_status_exited(status, exitval);
14671.1Skamil
14681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
14691.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
14701.1Skamil}
14711.1Skamil
14721.28Skamilstatic void
14731.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
14741.32Skamil          bool trackvforkdone, bool detachchild, bool detachparent)
14751.1Skamil{
14761.1Skamil	const int exitval = 5;
14771.1Skamil	const int exitval2 = 15;
14781.1Skamil	const int sigval = SIGSTOP;
14791.31Skamil	pid_t child, child2 = 0, wpid;
14801.1Skamil#if defined(TWAIT_HAVE_STATUS)
14811.1Skamil	int status;
14821.1Skamil#endif
14831.1Skamil	ptrace_state_t state;
14841.1Skamil	const int slen = sizeof(state);
14851.1Skamil	ptrace_event_t event;
14861.1Skamil	const int elen = sizeof(event);
14871.1Skamil
14881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
14891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
14901.1Skamil	if (child == 0) {
14911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
14921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
14931.1Skamil
14941.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
14951.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
14961.1Skamil
14971.30Skamil		FORKEE_ASSERT((child2 = (fn)()) != -1);
14981.1Skamil
14991.1Skamil		if (child2 == 0)
15001.1Skamil			_exit(exitval2);
15011.1Skamil
15021.1Skamil		FORKEE_REQUIRE_SUCCESS
15031.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
15041.1Skamil
15051.1Skamil		forkee_status_exited(status, exitval2);
15061.1Skamil
15071.13Schristos		DPRINTF("Before exiting of the child process\n");
15081.1Skamil		_exit(exitval);
15091.1Skamil	}
15101.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
15111.1Skamil
15121.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
15131.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
15141.1Skamil
15151.1Skamil	validate_status_stopped(status, sigval);
15161.1Skamil
15171.30Skamil	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
15181.30Skamil	        trackfork ? "|PTRACE_FORK" : "",
15191.30Skamil	        trackvfork ? "|PTRACE_VFORK" : "",
15201.30Skamil	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
15211.30Skamil	event.pe_set_event = 0;
15221.30Skamil	if (trackfork)
15231.30Skamil		event.pe_set_event |= PTRACE_FORK;
15241.30Skamil	if (trackvfork)
15251.30Skamil		event.pe_set_event |= PTRACE_VFORK;
15261.30Skamil	if (trackvforkdone)
15271.30Skamil		event.pe_set_event |= PTRACE_VFORK_DONE;
15281.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
15291.1Skamil
15301.13Schristos	DPRINTF("Before resuming the child process where it left off and "
15311.1Skamil	    "without signal to be sent\n");
15321.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15331.1Skamil
15341.29Skamil#if defined(TWAIT_HAVE_PID)
15351.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
15361.29Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
15371.29Skamil		        child);
15381.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
15391.29Skamil		                      child);
15401.1Skamil
15411.29Skamil		validate_status_stopped(status, SIGTRAP);
15421.1Skamil
15431.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
15441.29Skamil		                       slen) != -1);
15451.31Skamil		if (trackfork && fn == fork) {
15461.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
15471.30Skamil			       PTRACE_FORK);
15481.30Skamil		}
15491.31Skamil		if (trackvfork && fn == vfork) {
15501.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
15511.30Skamil			       PTRACE_VFORK);
15521.30Skamil		}
15531.29Skamil
15541.29Skamil		child2 = state.pe_other_pid;
15551.30Skamil		DPRINTF("Reported ptrace event with forkee %d\n", child2);
15561.29Skamil
15571.29Skamil		DPRINTF("Before calling %s() for the forkee %d of the child "
15581.29Skamil		        "%d\n", TWAIT_FNAME, child2, child);
15591.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
15601.29Skamil		    child2);
15611.1Skamil
15621.29Skamil		validate_status_stopped(status, SIGTRAP);
15631.1Skamil
15641.29Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
15651.29Skamil		                       slen) != -1);
15661.31Skamil		if (trackfork && fn == fork) {
15671.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
15681.30Skamil			       PTRACE_FORK);
15691.30Skamil		}
15701.31Skamil		if (trackvfork && fn == vfork) {
15711.30Skamil			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
15721.30Skamil			       PTRACE_VFORK);
15731.30Skamil		}
15741.30Skamil
15751.29Skamil		ATF_REQUIRE_EQ(state.pe_other_pid, child);
15761.29Skamil
15771.29Skamil		DPRINTF("Before resuming the forkee process where it left off "
15781.29Skamil		    "and without signal to be sent\n");
15791.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
15801.29Skamil		                != -1);
15811.29Skamil
15821.29Skamil		DPRINTF("Before resuming the child process where it left off "
15831.29Skamil		        "and without signal to be sent\n");
15841.29Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
15851.30Skamil	}
15861.30Skamil#endif
15871.30Skamil
15881.31Skamil	if (trackvforkdone && fn == vfork) {
15891.30Skamil		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
15901.30Skamil		        child);
15911.30Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
15921.30Skamil		                      child);
15931.30Skamil
15941.30Skamil		validate_status_stopped(status, SIGTRAP);
15951.30Skamil
15961.30Skamil		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
15971.30Skamil		                       slen) != -1);
15981.30Skamil		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
15991.30Skamil
16001.30Skamil		child2 = state.pe_other_pid;
16011.30Skamil		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
16021.30Skamil		        child2);
16031.30Skamil
16041.30Skamil		DPRINTF("Before resuming the child process where it left off "
16051.30Skamil		        "and without signal to be sent\n");
16061.30Skamil		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16071.30Skamil	}
16081.29Skamil
16091.30Skamil#if defined(TWAIT_HAVE_PID)
16101.31Skamil	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
16111.29Skamil		DPRINTF("Before calling %s() for the forkee - expected exited"
16121.29Skamil		        "\n", TWAIT_FNAME);
16131.29Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
16141.29Skamil		    child2);
16151.29Skamil
16161.29Skamil		validate_status_exited(status, exitval2);
16171.29Skamil
16181.29Skamil		DPRINTF("Before calling %s() for the forkee - expected no "
16191.29Skamil		        "process\n", TWAIT_FNAME);
16201.29Skamil		TWAIT_REQUIRE_FAILURE(ECHILD,
16211.29Skamil		    wpid = TWAIT_GENERIC(child2, &status, 0));
16221.29Skamil	}
16231.29Skamil#endif
16241.1Skamil
16251.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
16261.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
16271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16281.1Skamil
16291.1Skamil	validate_status_stopped(status, SIGCHLD);
16301.1Skamil
16311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
16321.1Skamil	    "without signal to be sent\n");
16331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
16341.1Skamil
16351.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
16361.1Skamil	    TWAIT_FNAME);
16371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
16381.1Skamil
16391.1Skamil	validate_status_exited(status, exitval);
16401.1Skamil
16411.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
16421.1Skamil	    TWAIT_FNAME);
16431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
16441.1Skamil}
16451.28Skamil
16461.32Skamil#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
16471.32SkamilATF_TC(name);									\
16481.32SkamilATF_TC_HEAD(name, tc)								\
16491.32Skamil{										\
16501.32Skamil	atf_tc_set_md_var(tc, "descr", descr);					\
16511.32Skamil}										\
16521.32Skamil										\
16531.32SkamilATF_TC_BODY(name, tc)								\
16541.32Skamil{										\
16551.32Skamil										\
16561.32Skamil	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
16571.32Skamil}
16581.32Skamil
16591.32Skamil#define F false
16601.32Skamil#define T true
16611.32Skamil
16621.32Skamil#define F_IF__0(x)
16631.32Skamil#define F_IF__1(x) x
16641.32Skamil#define F_IF__(x,y) F_IF__ ## x (y)
16651.32Skamil#define F_IF_(x,y) F_IF__(x,y)
16661.32Skamil#define F_IF(x,y) F_IF_(x,y)
16671.32Skamil
16681.32Skamil#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
16691.32Skamil        "Verify " #function "(2) called with 0"					\
16701.32Skamil        F_IF(forkbit,"|PTRACE_FORK")						\
16711.32Skamil        F_IF(vforkbit,"|PTRACE_VFORK")						\
16721.32Skamil        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
16731.32Skamil        " in EVENT_MASK."							\
16741.32Skamil        F_IF(dchildbit," Detach child in this test.")				\
16751.32Skamil        F_IF(dparentbit," Detach parent in this test.")
16761.1Skamil
16771.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
16781.31Skamil#if defined(TWAIT_HAVE_PID)
16791.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
16801.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
16811.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
16821.31Skamil#endif
16831.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
16841.31Skamil#if defined(TWAIT_HAVE_PID)
16851.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
16861.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
16871.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
16881.31Skamil#endif
16891.1Skamil
16901.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
16911.31Skamil#if defined(TWAIT_HAVE_PID)
16921.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
16931.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
16941.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
16951.31Skamil#endif
16961.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
16971.31Skamil#if defined(TWAIT_HAVE_PID)
16981.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
16991.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
17001.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
17011.31Skamil#endif
17021.31Skamil
17031.31Skamil
17041.31Skamil
17051.1Skamil
17061.1SkamilATF_TC(io_read_d1);
17071.1SkamilATF_TC_HEAD(io_read_d1, tc)
17081.1Skamil{
17091.1Skamil	atf_tc_set_md_var(tc, "descr",
17101.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
17111.1Skamil}
17121.1Skamil
17131.1SkamilATF_TC_BODY(io_read_d1, tc)
17141.1Skamil{
17151.1Skamil	const int exitval = 5;
17161.1Skamil	const int sigval = SIGSTOP;
17171.1Skamil	pid_t child, wpid;
17181.1Skamil	uint8_t lookup_me = 0;
17191.1Skamil	const uint8_t magic = 0xab;
17201.1Skamil	struct ptrace_io_desc io = {
17211.1Skamil		.piod_op = PIOD_READ_D,
17221.1Skamil		.piod_offs = &lookup_me,
17231.1Skamil		.piod_addr = &lookup_me,
17241.1Skamil		.piod_len = sizeof(lookup_me)
17251.1Skamil	};
17261.1Skamil#if defined(TWAIT_HAVE_STATUS)
17271.1Skamil	int status;
17281.1Skamil#endif
17291.1Skamil
17301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17321.1Skamil	if (child == 0) {
17331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
17351.1Skamil
17361.1Skamil		lookup_me = magic;
17371.1Skamil
17381.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
17391.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
17401.1Skamil
17411.13Schristos		DPRINTF("Before exiting of the child process\n");
17421.1Skamil		_exit(exitval);
17431.1Skamil	}
17441.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
17451.1Skamil
17461.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17471.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17481.1Skamil
17491.1Skamil	validate_status_stopped(status, sigval);
17501.1Skamil
17511.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
17521.1Skamil	    child, getpid());
17531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
17541.1Skamil
17551.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
17561.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
17571.1Skamil
17581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
17591.1Skamil	    "without signal to be sent\n");
17601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
17611.1Skamil
17621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
17641.1Skamil
17651.1Skamil	validate_status_exited(status, exitval);
17661.1Skamil
17671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
17681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
17691.1Skamil}
17701.1Skamil
17711.1SkamilATF_TC(io_read_d2);
17721.1SkamilATF_TC_HEAD(io_read_d2, tc)
17731.1Skamil{
17741.1Skamil	atf_tc_set_md_var(tc, "descr",
17751.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
17761.1Skamil}
17771.1Skamil
17781.1SkamilATF_TC_BODY(io_read_d2, tc)
17791.1Skamil{
17801.1Skamil	const int exitval = 5;
17811.1Skamil	const int sigval = SIGSTOP;
17821.1Skamil	pid_t child, wpid;
17831.1Skamil	uint16_t lookup_me = 0;
17841.1Skamil	const uint16_t magic = 0x1234;
17851.1Skamil	struct ptrace_io_desc io = {
17861.1Skamil		.piod_op = PIOD_READ_D,
17871.1Skamil		.piod_offs = &lookup_me,
17881.1Skamil		.piod_addr = &lookup_me,
17891.1Skamil		.piod_len = sizeof(lookup_me)
17901.1Skamil	};
17911.1Skamil#if defined(TWAIT_HAVE_STATUS)
17921.1Skamil	int status;
17931.1Skamil#endif
17941.1Skamil
17951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
17961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
17971.1Skamil	if (child == 0) {
17981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
17991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18001.1Skamil
18011.1Skamil		lookup_me = magic;
18021.1Skamil
18031.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18041.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18051.1Skamil
18061.13Schristos		DPRINTF("Before exiting of the child process\n");
18071.1Skamil		_exit(exitval);
18081.1Skamil	}
18091.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18101.1Skamil
18111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18121.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18131.1Skamil
18141.1Skamil	validate_status_stopped(status, sigval);
18151.1Skamil
18161.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
18171.1Skamil	    child, getpid());
18181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18191.1Skamil
18201.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
18211.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
18221.1Skamil
18231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18241.1Skamil	    "without signal to be sent\n");
18251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18261.1Skamil
18271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18291.1Skamil
18301.1Skamil	validate_status_exited(status, exitval);
18311.1Skamil
18321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18331.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18341.1Skamil}
18351.1Skamil
18361.1SkamilATF_TC(io_read_d3);
18371.1SkamilATF_TC_HEAD(io_read_d3, tc)
18381.1Skamil{
18391.1Skamil	atf_tc_set_md_var(tc, "descr",
18401.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
18411.1Skamil}
18421.1Skamil
18431.1SkamilATF_TC_BODY(io_read_d3, tc)
18441.1Skamil{
18451.1Skamil	const int exitval = 5;
18461.1Skamil	const int sigval = SIGSTOP;
18471.1Skamil	pid_t child, wpid;
18481.1Skamil	uint32_t lookup_me = 0;
18491.1Skamil	const uint32_t magic = 0x1234abcd;
18501.1Skamil	struct ptrace_io_desc io = {
18511.1Skamil		.piod_op = PIOD_READ_D,
18521.1Skamil		.piod_offs = &lookup_me,
18531.1Skamil		.piod_addr = &lookup_me,
18541.1Skamil		.piod_len = sizeof(lookup_me)
18551.1Skamil	};
18561.1Skamil#if defined(TWAIT_HAVE_STATUS)
18571.1Skamil	int status;
18581.1Skamil#endif
18591.1Skamil
18601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
18611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
18621.1Skamil	if (child == 0) {
18631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
18641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
18651.1Skamil
18661.1Skamil		lookup_me = magic;
18671.1Skamil
18681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
18691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
18701.1Skamil
18711.13Schristos		DPRINTF("Before exiting of the child process\n");
18721.1Skamil		_exit(exitval);
18731.1Skamil	}
18741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
18751.1Skamil
18761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18781.1Skamil
18791.1Skamil	validate_status_stopped(status, sigval);
18801.1Skamil
18811.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
18821.1Skamil	    child, getpid());
18831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
18841.1Skamil
18851.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
18861.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
18871.1Skamil
18881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
18891.1Skamil	    "without signal to be sent\n");
18901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
18911.1Skamil
18921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
18941.1Skamil
18951.1Skamil	validate_status_exited(status, exitval);
18961.1Skamil
18971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
18981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
18991.1Skamil}
19001.1Skamil
19011.1SkamilATF_TC(io_read_d4);
19021.1SkamilATF_TC_HEAD(io_read_d4, tc)
19031.1Skamil{
19041.1Skamil	atf_tc_set_md_var(tc, "descr",
19051.1Skamil	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
19061.1Skamil}
19071.1Skamil
19081.1SkamilATF_TC_BODY(io_read_d4, tc)
19091.1Skamil{
19101.1Skamil	const int exitval = 5;
19111.1Skamil	const int sigval = SIGSTOP;
19121.1Skamil	pid_t child, wpid;
19131.1Skamil	uint64_t lookup_me = 0;
19141.1Skamil	const uint64_t magic = 0x1234abcd9876dcfa;
19151.1Skamil	struct ptrace_io_desc io = {
19161.1Skamil		.piod_op = PIOD_READ_D,
19171.1Skamil		.piod_offs = &lookup_me,
19181.1Skamil		.piod_addr = &lookup_me,
19191.1Skamil		.piod_len = sizeof(lookup_me)
19201.1Skamil	};
19211.1Skamil#if defined(TWAIT_HAVE_STATUS)
19221.1Skamil	int status;
19231.1Skamil#endif
19241.1Skamil
19251.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19261.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19271.1Skamil	if (child == 0) {
19281.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19291.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19301.1Skamil
19311.1Skamil		lookup_me = magic;
19321.1Skamil
19331.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19341.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19351.1Skamil
19361.13Schristos		DPRINTF("Before exiting of the child process\n");
19371.1Skamil		_exit(exitval);
19381.1Skamil	}
19391.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
19401.1Skamil
19411.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19431.1Skamil
19441.1Skamil	validate_status_stopped(status, sigval);
19451.1Skamil
19461.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
19471.1Skamil	    child, getpid());
19481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
19491.1Skamil
19501.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
19511.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
19521.1Skamil
19531.13Schristos	DPRINTF("Before resuming the child process where it left off and "
19541.1Skamil	    "without signal to be sent\n");
19551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
19561.1Skamil
19571.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
19591.1Skamil
19601.1Skamil	validate_status_exited(status, exitval);
19611.1Skamil
19621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
19631.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
19641.1Skamil}
19651.1Skamil
19661.1SkamilATF_TC(io_write_d1);
19671.1SkamilATF_TC_HEAD(io_write_d1, tc)
19681.1Skamil{
19691.1Skamil	atf_tc_set_md_var(tc, "descr",
19701.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
19711.1Skamil}
19721.1Skamil
19731.1SkamilATF_TC_BODY(io_write_d1, tc)
19741.1Skamil{
19751.1Skamil	const int exitval = 5;
19761.1Skamil	const int sigval = SIGSTOP;
19771.1Skamil	pid_t child, wpid;
19781.1Skamil	uint8_t lookup_me = 0;
19791.1Skamil	const uint8_t magic = 0xab;
19801.1Skamil	struct ptrace_io_desc io = {
19811.1Skamil		.piod_op = PIOD_WRITE_D,
19821.1Skamil		.piod_offs = &lookup_me,
19831.1Skamil		.piod_addr = &lookup_me,
19841.1Skamil		.piod_len = sizeof(lookup_me)
19851.1Skamil	};
19861.1Skamil#if defined(TWAIT_HAVE_STATUS)
19871.1Skamil	int status;
19881.1Skamil#endif
19891.1Skamil
19901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
19911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
19921.1Skamil	if (child == 0) {
19931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
19941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
19951.1Skamil
19961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
19971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
19981.1Skamil
19991.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
20001.1Skamil
20011.13Schristos		DPRINTF("Before exiting of the child process\n");
20021.1Skamil		_exit(exitval);
20031.1Skamil	}
20041.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20051.1Skamil
20061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20081.1Skamil
20091.1Skamil	validate_status_stopped(status, sigval);
20101.1Skamil
20111.1Skamil	lookup_me = magic;
20121.1Skamil
20131.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20141.1Skamil	    child, getpid());
20151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20161.1Skamil
20171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20181.1Skamil	    "without signal to be sent\n");
20191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20201.1Skamil
20211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20221.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20231.1Skamil
20241.1Skamil	validate_status_exited(status, exitval);
20251.1Skamil
20261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20281.1Skamil}
20291.1Skamil
20301.1SkamilATF_TC(io_write_d2);
20311.1SkamilATF_TC_HEAD(io_write_d2, tc)
20321.1Skamil{
20331.1Skamil	atf_tc_set_md_var(tc, "descr",
20341.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
20351.1Skamil}
20361.1Skamil
20371.1SkamilATF_TC_BODY(io_write_d2, tc)
20381.1Skamil{
20391.1Skamil	const int exitval = 5;
20401.1Skamil	const int sigval = SIGSTOP;
20411.1Skamil	pid_t child, wpid;
20421.1Skamil	uint16_t lookup_me = 0;
20431.1Skamil	const uint16_t magic = 0xab12;
20441.1Skamil	struct ptrace_io_desc io = {
20451.1Skamil		.piod_op = PIOD_WRITE_D,
20461.1Skamil		.piod_offs = &lookup_me,
20471.1Skamil		.piod_addr = &lookup_me,
20481.1Skamil		.piod_len = sizeof(lookup_me)
20491.1Skamil	};
20501.1Skamil#if defined(TWAIT_HAVE_STATUS)
20511.1Skamil	int status;
20521.1Skamil#endif
20531.1Skamil
20541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
20551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
20561.1Skamil	if (child == 0) {
20571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
20581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
20591.1Skamil
20601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
20611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
20621.1Skamil
20631.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
20641.1Skamil
20651.13Schristos		DPRINTF("Before exiting of the child process\n");
20661.1Skamil		_exit(exitval);
20671.1Skamil	}
20681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
20691.1Skamil
20701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20721.1Skamil
20731.1Skamil	validate_status_stopped(status, sigval);
20741.1Skamil
20751.1Skamil	lookup_me = magic;
20761.1Skamil
20771.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
20781.1Skamil	    child, getpid());
20791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
20801.1Skamil
20811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
20821.1Skamil	    "without signal to be sent\n");
20831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
20841.1Skamil
20851.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
20871.1Skamil
20881.1Skamil	validate_status_exited(status, exitval);
20891.1Skamil
20901.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
20911.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
20921.1Skamil}
20931.1Skamil
20941.1SkamilATF_TC(io_write_d3);
20951.1SkamilATF_TC_HEAD(io_write_d3, tc)
20961.1Skamil{
20971.1Skamil	atf_tc_set_md_var(tc, "descr",
20981.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
20991.1Skamil}
21001.1Skamil
21011.1SkamilATF_TC_BODY(io_write_d3, tc)
21021.1Skamil{
21031.1Skamil	const int exitval = 5;
21041.1Skamil	const int sigval = SIGSTOP;
21051.1Skamil	pid_t child, wpid;
21061.1Skamil	uint32_t lookup_me = 0;
21071.1Skamil	const uint32_t magic = 0xab127643;
21081.1Skamil	struct ptrace_io_desc io = {
21091.1Skamil		.piod_op = PIOD_WRITE_D,
21101.1Skamil		.piod_offs = &lookup_me,
21111.1Skamil		.piod_addr = &lookup_me,
21121.1Skamil		.piod_len = sizeof(lookup_me)
21131.1Skamil	};
21141.1Skamil#if defined(TWAIT_HAVE_STATUS)
21151.1Skamil	int status;
21161.1Skamil#endif
21171.1Skamil
21181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21201.1Skamil	if (child == 0) {
21211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21231.1Skamil
21241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21261.1Skamil
21271.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
21281.1Skamil
21291.13Schristos		DPRINTF("Before exiting of the child process\n");
21301.1Skamil		_exit(exitval);
21311.1Skamil	}
21321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21331.1Skamil
21341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21361.1Skamil
21371.1Skamil	validate_status_stopped(status, sigval);
21381.1Skamil
21391.1Skamil	lookup_me = magic;
21401.1Skamil
21411.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
21421.1Skamil	    child, getpid());
21431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
21441.1Skamil
21451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
21461.1Skamil	    "without signal to be sent\n");
21471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
21481.1Skamil
21491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
21511.1Skamil
21521.1Skamil	validate_status_exited(status, exitval);
21531.1Skamil
21541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
21561.1Skamil}
21571.1Skamil
21581.1SkamilATF_TC(io_write_d4);
21591.1SkamilATF_TC_HEAD(io_write_d4, tc)
21601.1Skamil{
21611.1Skamil	atf_tc_set_md_var(tc, "descr",
21621.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
21631.1Skamil}
21641.1Skamil
21651.1SkamilATF_TC_BODY(io_write_d4, tc)
21661.1Skamil{
21671.1Skamil	const int exitval = 5;
21681.1Skamil	const int sigval = SIGSTOP;
21691.1Skamil	pid_t child, wpid;
21701.1Skamil	uint64_t lookup_me = 0;
21711.1Skamil	const uint64_t magic = 0xab12764376490123;
21721.1Skamil	struct ptrace_io_desc io = {
21731.1Skamil		.piod_op = PIOD_WRITE_D,
21741.1Skamil		.piod_offs = &lookup_me,
21751.1Skamil		.piod_addr = &lookup_me,
21761.1Skamil		.piod_len = sizeof(lookup_me)
21771.1Skamil	};
21781.1Skamil#if defined(TWAIT_HAVE_STATUS)
21791.1Skamil	int status;
21801.1Skamil#endif
21811.1Skamil
21821.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
21831.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
21841.1Skamil	if (child == 0) {
21851.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
21861.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
21871.1Skamil
21881.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
21891.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
21901.1Skamil
21911.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
21921.1Skamil
21931.13Schristos		DPRINTF("Before exiting of the child process\n");
21941.1Skamil		_exit(exitval);
21951.1Skamil	}
21961.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
21971.1Skamil
21981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
21991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22001.1Skamil
22011.1Skamil	validate_status_stopped(status, sigval);
22021.1Skamil
22031.1Skamil	lookup_me = magic;
22041.1Skamil
22051.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
22061.1Skamil	    child, getpid());
22071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22081.1Skamil
22091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22101.1Skamil	    "without signal to be sent\n");
22111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22121.1Skamil
22131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22151.1Skamil
22161.1Skamil	validate_status_exited(status, exitval);
22171.1Skamil
22181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22201.1Skamil}
22211.1Skamil
22221.1SkamilATF_TC(io_read_auxv1);
22231.1SkamilATF_TC_HEAD(io_read_auxv1, tc)
22241.1Skamil{
22251.1Skamil	atf_tc_set_md_var(tc, "descr",
22261.1Skamil	    "Verify PT_READ_AUXV called for tracee");
22271.1Skamil}
22281.1Skamil
22291.1SkamilATF_TC_BODY(io_read_auxv1, tc)
22301.1Skamil{
22311.1Skamil	const int exitval = 5;
22321.1Skamil	const int sigval = SIGSTOP;
22331.1Skamil	pid_t child, wpid;
22341.1Skamil#if defined(TWAIT_HAVE_STATUS)
22351.1Skamil	int status;
22361.1Skamil#endif
22371.1Skamil	AuxInfo ai[100], *aip;
22381.1Skamil	struct ptrace_io_desc io = {
22391.1Skamil		.piod_op = PIOD_READ_AUXV,
22401.1Skamil		.piod_offs = 0,
22411.1Skamil		.piod_addr = ai,
22421.1Skamil		.piod_len = sizeof(ai)
22431.1Skamil	};
22441.1Skamil
22451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
22461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
22471.1Skamil	if (child == 0) {
22481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
22491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
22501.1Skamil
22511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
22521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
22531.1Skamil
22541.13Schristos		DPRINTF("Before exiting of the child process\n");
22551.1Skamil		_exit(exitval);
22561.1Skamil	}
22571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
22581.1Skamil
22591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22611.1Skamil
22621.1Skamil	validate_status_stopped(status, sigval);
22631.1Skamil
22641.13Schristos	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
22651.1Skamil	    child, getpid());
22661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
22671.1Skamil
22681.13Schristos	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
22691.1Skamil	ATF_REQUIRE(io.piod_len > 0);
22701.1Skamil
22711.1Skamil	for (aip = ai; aip->a_type != AT_NULL; aip++)
22721.13Schristos		DPRINTF("a_type=%#llx a_v=%#llx\n",
22731.1Skamil		    (long long int)aip->a_type, (long long int)aip->a_v);
22741.1Skamil
22751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
22761.1Skamil	    "without signal to be sent\n");
22771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
22781.1Skamil
22791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
22811.1Skamil
22821.1Skamil	validate_status_exited(status, exitval);
22831.1Skamil
22841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
22851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
22861.1Skamil}
22871.1Skamil
22881.1SkamilATF_TC(read_d1);
22891.1SkamilATF_TC_HEAD(read_d1, tc)
22901.1Skamil{
22911.1Skamil	atf_tc_set_md_var(tc, "descr",
22921.1Skamil	    "Verify PT_READ_D called once");
22931.1Skamil}
22941.1Skamil
22951.1SkamilATF_TC_BODY(read_d1, tc)
22961.1Skamil{
22971.1Skamil	const int exitval = 5;
22981.1Skamil	const int sigval = SIGSTOP;
22991.1Skamil	pid_t child, wpid;
23001.1Skamil	int lookup_me = 0;
23011.1Skamil	const int magic = (int)random();
23021.1Skamil#if defined(TWAIT_HAVE_STATUS)
23031.1Skamil	int status;
23041.1Skamil#endif
23051.1Skamil
23061.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23071.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23081.1Skamil	if (child == 0) {
23091.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23101.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23111.1Skamil
23121.1Skamil		lookup_me = magic;
23131.1Skamil
23141.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23151.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23161.1Skamil
23171.13Schristos		DPRINTF("Before exiting of the child process\n");
23181.1Skamil		_exit(exitval);
23191.1Skamil	}
23201.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23211.1Skamil
23221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23231.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23241.1Skamil
23251.1Skamil	validate_status_stopped(status, sigval);
23261.1Skamil
23271.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
23281.1Skamil	    child, getpid());
23291.1Skamil	errno = 0;
23301.1Skamil	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
23311.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23321.1Skamil
23331.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
23341.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
23351.1Skamil
23361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
23371.1Skamil	    "without signal to be sent\n");
23381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
23391.1Skamil
23401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23421.1Skamil
23431.1Skamil	validate_status_exited(status, exitval);
23441.1Skamil
23451.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23461.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
23471.1Skamil}
23481.1Skamil
23491.1SkamilATF_TC(read_d2);
23501.1SkamilATF_TC_HEAD(read_d2, tc)
23511.1Skamil{
23521.1Skamil	atf_tc_set_md_var(tc, "descr",
23531.1Skamil	    "Verify PT_READ_D called twice");
23541.1Skamil}
23551.1Skamil
23561.1SkamilATF_TC_BODY(read_d2, tc)
23571.1Skamil{
23581.1Skamil	const int exitval = 5;
23591.1Skamil	const int sigval = SIGSTOP;
23601.1Skamil	pid_t child, wpid;
23611.1Skamil	int lookup_me1 = 0;
23621.1Skamil	int lookup_me2 = 0;
23631.1Skamil	const int magic1 = (int)random();
23641.1Skamil	const int magic2 = (int)random();
23651.1Skamil#if defined(TWAIT_HAVE_STATUS)
23661.1Skamil	int status;
23671.1Skamil#endif
23681.1Skamil
23691.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
23701.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
23711.1Skamil	if (child == 0) {
23721.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
23731.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
23741.1Skamil
23751.1Skamil		lookup_me1 = magic1;
23761.1Skamil		lookup_me2 = magic2;
23771.1Skamil
23781.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
23791.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
23801.1Skamil
23811.13Schristos		DPRINTF("Before exiting of the child process\n");
23821.1Skamil		_exit(exitval);
23831.1Skamil	}
23841.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
23851.1Skamil
23861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
23871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
23881.1Skamil
23891.1Skamil	validate_status_stopped(status, sigval);
23901.1Skamil
23911.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
23921.1Skamil	    child, getpid());
23931.1Skamil	errno = 0;
23941.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
23951.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
23961.1Skamil
23971.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
23981.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
23991.1Skamil
24001.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
24011.1Skamil	    child, getpid());
24021.1Skamil	errno = 0;
24031.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
24041.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24051.1Skamil
24061.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
24071.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
24081.1Skamil
24091.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24101.1Skamil	    "without signal to be sent\n");
24111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24121.1Skamil
24131.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24151.1Skamil
24161.1Skamil	validate_status_exited(status, exitval);
24171.1Skamil
24181.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24191.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
24201.1Skamil}
24211.1Skamil
24221.1SkamilATF_TC(read_d3);
24231.1SkamilATF_TC_HEAD(read_d3, tc)
24241.1Skamil{
24251.1Skamil	atf_tc_set_md_var(tc, "descr",
24261.1Skamil	    "Verify PT_READ_D called three times");
24271.1Skamil}
24281.1Skamil
24291.1SkamilATF_TC_BODY(read_d3, tc)
24301.1Skamil{
24311.1Skamil	const int exitval = 5;
24321.1Skamil	const int sigval = SIGSTOP;
24331.1Skamil	pid_t child, wpid;
24341.1Skamil	int lookup_me1 = 0;
24351.1Skamil	int lookup_me2 = 0;
24361.1Skamil	int lookup_me3 = 0;
24371.1Skamil	const int magic1 = (int)random();
24381.1Skamil	const int magic2 = (int)random();
24391.1Skamil	const int magic3 = (int)random();
24401.1Skamil#if defined(TWAIT_HAVE_STATUS)
24411.1Skamil	int status;
24421.1Skamil#endif
24431.1Skamil
24441.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
24451.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
24461.1Skamil	if (child == 0) {
24471.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
24481.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
24491.1Skamil
24501.1Skamil		lookup_me1 = magic1;
24511.1Skamil		lookup_me2 = magic2;
24521.1Skamil		lookup_me3 = magic3;
24531.1Skamil
24541.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
24551.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
24561.1Skamil
24571.13Schristos		DPRINTF("Before exiting of the child process\n");
24581.1Skamil		_exit(exitval);
24591.1Skamil	}
24601.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
24611.1Skamil
24621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
24641.1Skamil
24651.1Skamil	validate_status_stopped(status, sigval);
24661.1Skamil
24671.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
24681.1Skamil	    child, getpid());
24691.1Skamil	errno = 0;
24701.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
24711.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24721.1Skamil
24731.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
24741.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
24751.1Skamil
24761.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
24771.1Skamil	    child, getpid());
24781.1Skamil	errno = 0;
24791.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
24801.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24811.1Skamil
24821.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
24831.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
24841.1Skamil
24851.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
24861.1Skamil	    child, getpid());
24871.1Skamil	errno = 0;
24881.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
24891.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
24901.1Skamil
24911.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
24921.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
24931.1Skamil
24941.13Schristos	DPRINTF("Before resuming the child process where it left off and "
24951.1Skamil	    "without signal to be sent\n");
24961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
24971.1Skamil
24981.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
24991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25001.1Skamil
25011.1Skamil	validate_status_exited(status, exitval);
25021.1Skamil
25031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25041.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
25051.1Skamil}
25061.1Skamil
25071.1SkamilATF_TC(read_d4);
25081.1SkamilATF_TC_HEAD(read_d4, tc)
25091.1Skamil{
25101.1Skamil	atf_tc_set_md_var(tc, "descr",
25111.1Skamil	    "Verify PT_READ_D called four times");
25121.1Skamil}
25131.1Skamil
25141.1SkamilATF_TC_BODY(read_d4, tc)
25151.1Skamil{
25161.1Skamil	const int exitval = 5;
25171.1Skamil	const int sigval = SIGSTOP;
25181.1Skamil	pid_t child, wpid;
25191.1Skamil	int lookup_me1 = 0;
25201.1Skamil	int lookup_me2 = 0;
25211.1Skamil	int lookup_me3 = 0;
25221.1Skamil	int lookup_me4 = 0;
25231.1Skamil	const int magic1 = (int)random();
25241.1Skamil	const int magic2 = (int)random();
25251.1Skamil	const int magic3 = (int)random();
25261.1Skamil	const int magic4 = (int)random();
25271.1Skamil#if defined(TWAIT_HAVE_STATUS)
25281.1Skamil	int status;
25291.1Skamil#endif
25301.1Skamil
25311.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
25321.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
25331.1Skamil	if (child == 0) {
25341.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
25351.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
25361.1Skamil
25371.1Skamil		lookup_me1 = magic1;
25381.1Skamil		lookup_me2 = magic2;
25391.1Skamil		lookup_me3 = magic3;
25401.1Skamil		lookup_me4 = magic4;
25411.1Skamil
25421.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
25431.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
25441.1Skamil
25451.13Schristos		DPRINTF("Before exiting of the child process\n");
25461.1Skamil		_exit(exitval);
25471.1Skamil	}
25481.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
25491.1Skamil
25501.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25511.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25521.1Skamil
25531.1Skamil	validate_status_stopped(status, sigval);
25541.1Skamil
25551.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
25561.1Skamil	    child, getpid());
25571.1Skamil	errno = 0;
25581.1Skamil	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
25591.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25601.1Skamil
25611.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
25621.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
25631.1Skamil
25641.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
25651.1Skamil	    child, getpid());
25661.1Skamil	errno = 0;
25671.1Skamil	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
25681.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25691.1Skamil
25701.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
25711.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
25721.1Skamil
25731.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
25741.1Skamil	    child, getpid());
25751.1Skamil	errno = 0;
25761.1Skamil	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
25771.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25781.1Skamil
25791.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
25801.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
25811.1Skamil
25821.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
25831.1Skamil	    child, getpid());
25841.1Skamil	errno = 0;
25851.1Skamil	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
25861.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
25871.1Skamil
25881.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
25891.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
25901.1Skamil
25911.13Schristos	DPRINTF("Before resuming the child process where it left off and "
25921.1Skamil	    "without signal to be sent\n");
25931.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
25941.1Skamil
25951.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
25961.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
25971.1Skamil
25981.1Skamil	validate_status_exited(status, exitval);
25991.1Skamil
26001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26011.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26021.1Skamil}
26031.1Skamil
26041.1SkamilATF_TC(write_d1);
26051.1SkamilATF_TC_HEAD(write_d1, tc)
26061.1Skamil{
26071.1Skamil	atf_tc_set_md_var(tc, "descr",
26081.1Skamil	    "Verify PT_WRITE_D called once");
26091.1Skamil}
26101.1Skamil
26111.1SkamilATF_TC_BODY(write_d1, tc)
26121.1Skamil{
26131.1Skamil	const int exitval = 5;
26141.1Skamil	const int sigval = SIGSTOP;
26151.1Skamil	pid_t child, wpid;
26161.1Skamil	int lookup_me = 0;
26171.1Skamil	const int magic = (int)random();
26181.1Skamil#if defined(TWAIT_HAVE_STATUS)
26191.1Skamil	int status;
26201.1Skamil#endif
26211.1Skamil
26221.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26231.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26241.1Skamil	if (child == 0) {
26251.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26261.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26271.1Skamil
26281.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26291.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26301.1Skamil
26311.1Skamil		FORKEE_ASSERT_EQ(lookup_me, magic);
26321.1Skamil
26331.13Schristos		DPRINTF("Before exiting of the child process\n");
26341.1Skamil		_exit(exitval);
26351.1Skamil	}
26361.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26371.1Skamil
26381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26391.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26401.1Skamil
26411.1Skamil	validate_status_stopped(status, sigval);
26421.1Skamil
26431.13Schristos	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
26441.1Skamil	    child, getpid());
26451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
26461.1Skamil
26471.13Schristos	DPRINTF("Before resuming the child process where it left off and "
26481.1Skamil	    "without signal to be sent\n");
26491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
26501.1Skamil
26511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26531.1Skamil
26541.1Skamil	validate_status_exited(status, exitval);
26551.1Skamil
26561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26571.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
26581.1Skamil}
26591.1Skamil
26601.1SkamilATF_TC(write_d2);
26611.1SkamilATF_TC_HEAD(write_d2, tc)
26621.1Skamil{
26631.1Skamil	atf_tc_set_md_var(tc, "descr",
26641.1Skamil	    "Verify PT_WRITE_D called twice");
26651.1Skamil}
26661.1Skamil
26671.1SkamilATF_TC_BODY(write_d2, tc)
26681.1Skamil{
26691.1Skamil	const int exitval = 5;
26701.1Skamil	const int sigval = SIGSTOP;
26711.1Skamil	pid_t child, wpid;
26721.1Skamil	int lookup_me1 = 0;
26731.1Skamil	int lookup_me2 = 0;
26741.1Skamil	const int magic1 = (int)random();
26751.1Skamil	const int magic2 = (int)random();
26761.1Skamil#if defined(TWAIT_HAVE_STATUS)
26771.1Skamil	int status;
26781.1Skamil#endif
26791.1Skamil
26801.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
26811.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
26821.1Skamil	if (child == 0) {
26831.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
26841.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
26851.1Skamil
26861.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
26871.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
26881.1Skamil
26891.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
26901.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
26911.1Skamil
26921.13Schristos		DPRINTF("Before exiting of the child process\n");
26931.1Skamil		_exit(exitval);
26941.1Skamil	}
26951.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
26961.1Skamil
26971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
26981.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
26991.1Skamil
27001.1Skamil	validate_status_stopped(status, sigval);
27011.1Skamil
27021.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
27031.1Skamil	    child, getpid());
27041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
27051.1Skamil
27061.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
27071.1Skamil	    child, getpid());
27081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
27091.1Skamil
27101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27111.1Skamil	    "without signal to be sent\n");
27121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27131.1Skamil
27141.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27151.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27161.1Skamil
27171.1Skamil	validate_status_exited(status, exitval);
27181.1Skamil
27191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27201.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27211.1Skamil}
27221.1Skamil
27231.1SkamilATF_TC(write_d3);
27241.1SkamilATF_TC_HEAD(write_d3, tc)
27251.1Skamil{
27261.1Skamil	atf_tc_set_md_var(tc, "descr",
27271.1Skamil	    "Verify PT_WRITE_D called three times");
27281.1Skamil}
27291.1Skamil
27301.1SkamilATF_TC_BODY(write_d3, tc)
27311.1Skamil{
27321.1Skamil	const int exitval = 5;
27331.1Skamil	const int sigval = SIGSTOP;
27341.1Skamil	pid_t child, wpid;
27351.1Skamil	int lookup_me1 = 0;
27361.1Skamil	int lookup_me2 = 0;
27371.1Skamil	int lookup_me3 = 0;
27381.1Skamil	const int magic1 = (int)random();
27391.1Skamil	const int magic2 = (int)random();
27401.1Skamil	const int magic3 = (int)random();
27411.1Skamil#if defined(TWAIT_HAVE_STATUS)
27421.1Skamil	int status;
27431.1Skamil#endif
27441.1Skamil
27451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
27461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
27471.1Skamil	if (child == 0) {
27481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
27491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
27501.1Skamil
27511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
27521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
27531.1Skamil
27541.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
27551.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
27561.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
27571.1Skamil
27581.13Schristos		DPRINTF("Before exiting of the child process\n");
27591.1Skamil		_exit(exitval);
27601.1Skamil	}
27611.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
27621.1Skamil
27631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27641.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27651.1Skamil
27661.1Skamil	validate_status_stopped(status, sigval);
27671.1Skamil
27681.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
27691.1Skamil	    child, getpid());
27701.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
27711.1Skamil
27721.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
27731.1Skamil	    child, getpid());
27741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
27751.1Skamil
27761.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
27771.1Skamil	    child, getpid());
27781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
27791.1Skamil
27801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
27811.1Skamil	    "without signal to be sent\n");
27821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
27831.1Skamil
27841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
27861.1Skamil
27871.1Skamil	validate_status_exited(status, exitval);
27881.1Skamil
27891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
27901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
27911.1Skamil}
27921.1Skamil
27931.1SkamilATF_TC(write_d4);
27941.1SkamilATF_TC_HEAD(write_d4, tc)
27951.1Skamil{
27961.1Skamil	atf_tc_set_md_var(tc, "descr",
27971.1Skamil	    "Verify PT_WRITE_D called four times");
27981.1Skamil}
27991.1Skamil
28001.1SkamilATF_TC_BODY(write_d4, tc)
28011.1Skamil{
28021.1Skamil	const int exitval = 5;
28031.1Skamil	const int sigval = SIGSTOP;
28041.1Skamil	pid_t child, wpid;
28051.1Skamil	int lookup_me1 = 0;
28061.1Skamil	int lookup_me2 = 0;
28071.1Skamil	int lookup_me3 = 0;
28081.1Skamil	int lookup_me4 = 0;
28091.1Skamil	const int magic1 = (int)random();
28101.1Skamil	const int magic2 = (int)random();
28111.1Skamil	const int magic3 = (int)random();
28121.1Skamil	const int magic4 = (int)random();
28131.1Skamil#if defined(TWAIT_HAVE_STATUS)
28141.1Skamil	int status;
28151.1Skamil#endif
28161.1Skamil
28171.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
28181.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
28191.1Skamil	if (child == 0) {
28201.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
28211.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
28221.1Skamil
28231.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
28241.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
28251.1Skamil
28261.1Skamil		FORKEE_ASSERT_EQ(lookup_me1, magic1);
28271.1Skamil		FORKEE_ASSERT_EQ(lookup_me2, magic2);
28281.1Skamil		FORKEE_ASSERT_EQ(lookup_me3, magic3);
28291.1Skamil		FORKEE_ASSERT_EQ(lookup_me4, magic4);
28301.1Skamil
28311.13Schristos		DPRINTF("Before exiting of the child process\n");
28321.1Skamil		_exit(exitval);
28331.1Skamil	}
28341.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
28351.1Skamil
28361.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28381.1Skamil
28391.1Skamil	validate_status_stopped(status, sigval);
28401.1Skamil
28411.13Schristos	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
28421.1Skamil	    child, getpid());
28431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
28441.1Skamil
28451.13Schristos	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
28461.1Skamil	    child, getpid());
28471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
28481.1Skamil
28491.13Schristos	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
28501.1Skamil	    child, getpid());
28511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
28521.1Skamil
28531.13Schristos	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
28541.1Skamil	    child, getpid());
28551.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
28561.1Skamil
28571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
28581.1Skamil	    "without signal to be sent\n");
28591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
28601.1Skamil
28611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
28631.1Skamil
28641.1Skamil	validate_status_exited(status, exitval);
28651.1Skamil
28661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
28671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
28681.1Skamil}
28691.1Skamil
28701.1SkamilATF_TC(io_read_d_write_d_handshake1);
28711.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
28721.1Skamil{
28731.1Skamil	atf_tc_set_md_var(tc, "descr",
28741.1Skamil	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
28751.1Skamil}
28761.1Skamil
28771.1SkamilATF_TC_BODY(io_read_d_write_d_handshake1, tc)
28781.1Skamil{
28791.1Skamil	const int exitval = 5;
28801.1Skamil	const int sigval = SIGSTOP;
28811.1Skamil	pid_t child, wpid;
28821.1Skamil	uint8_t lookup_me_fromtracee = 0;
28831.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
28841.1Skamil	uint8_t lookup_me_totracee = 0;
28851.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
28861.1Skamil	struct ptrace_io_desc io_fromtracee = {
28871.1Skamil		.piod_op = PIOD_READ_D,
28881.1Skamil		.piod_offs = &lookup_me_fromtracee,
28891.1Skamil		.piod_addr = &lookup_me_fromtracee,
28901.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
28911.1Skamil	};
28921.1Skamil	struct ptrace_io_desc io_totracee = {
28931.1Skamil		.piod_op = PIOD_WRITE_D,
28941.1Skamil		.piod_offs = &lookup_me_totracee,
28951.1Skamil		.piod_addr = &lookup_me_totracee,
28961.1Skamil		.piod_len = sizeof(lookup_me_totracee)
28971.1Skamil	};
28981.1Skamil#if defined(TWAIT_HAVE_STATUS)
28991.1Skamil	int status;
29001.1Skamil#endif
29011.1Skamil
29021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29041.1Skamil	if (child == 0) {
29051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29071.1Skamil
29081.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29091.1Skamil
29101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29121.1Skamil
29131.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
29141.1Skamil
29151.13Schristos		DPRINTF("Before exiting of the child process\n");
29161.1Skamil		_exit(exitval);
29171.1Skamil	}
29181.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
29191.1Skamil
29201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29221.1Skamil
29231.1Skamil	validate_status_stopped(status, sigval);
29241.1Skamil
29251.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
29261.1Skamil	    child, getpid());
29271.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
29281.1Skamil
29291.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
29301.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
29311.1Skamil	    magic_fromtracee);
29321.1Skamil
29331.1Skamil	lookup_me_totracee = magic_totracee;
29341.1Skamil
29351.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
29361.1Skamil	    child, getpid());
29371.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
29381.1Skamil
29391.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
29401.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
29411.1Skamil	    magic_totracee);
29421.1Skamil
29431.13Schristos	DPRINTF("Before resuming the child process where it left off and "
29441.1Skamil	    "without signal to be sent\n");
29451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
29461.1Skamil
29471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
29491.1Skamil
29501.1Skamil	validate_status_exited(status, exitval);
29511.1Skamil
29521.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
29531.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
29541.1Skamil}
29551.1Skamil
29561.1SkamilATF_TC(io_read_d_write_d_handshake2);
29571.1SkamilATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
29581.1Skamil{
29591.1Skamil	atf_tc_set_md_var(tc, "descr",
29601.1Skamil	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
29611.1Skamil}
29621.1Skamil
29631.1SkamilATF_TC_BODY(io_read_d_write_d_handshake2, tc)
29641.1Skamil{
29651.1Skamil	const int exitval = 5;
29661.1Skamil	const int sigval = SIGSTOP;
29671.1Skamil	pid_t child, wpid;
29681.1Skamil	uint8_t lookup_me_fromtracee = 0;
29691.1Skamil	const uint8_t magic_fromtracee = (uint8_t)random();
29701.1Skamil	uint8_t lookup_me_totracee = 0;
29711.1Skamil	const uint8_t magic_totracee = (uint8_t)random();
29721.1Skamil	struct ptrace_io_desc io_fromtracee = {
29731.1Skamil		.piod_op = PIOD_READ_D,
29741.1Skamil		.piod_offs = &lookup_me_fromtracee,
29751.1Skamil		.piod_addr = &lookup_me_fromtracee,
29761.1Skamil		.piod_len = sizeof(lookup_me_fromtracee)
29771.1Skamil	};
29781.1Skamil	struct ptrace_io_desc io_totracee = {
29791.1Skamil		.piod_op = PIOD_WRITE_D,
29801.1Skamil		.piod_offs = &lookup_me_totracee,
29811.1Skamil		.piod_addr = &lookup_me_totracee,
29821.1Skamil		.piod_len = sizeof(lookup_me_totracee)
29831.1Skamil	};
29841.1Skamil#if defined(TWAIT_HAVE_STATUS)
29851.1Skamil	int status;
29861.1Skamil#endif
29871.1Skamil
29881.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
29891.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
29901.1Skamil	if (child == 0) {
29911.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
29921.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
29931.1Skamil
29941.1Skamil		lookup_me_fromtracee = magic_fromtracee;
29951.1Skamil
29961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
29971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
29981.1Skamil
29991.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
30001.1Skamil
30011.13Schristos		DPRINTF("Before exiting of the child process\n");
30021.1Skamil		_exit(exitval);
30031.1Skamil	}
30041.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30051.1Skamil
30061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30081.1Skamil
30091.1Skamil	validate_status_stopped(status, sigval);
30101.1Skamil
30111.1Skamil	lookup_me_totracee = magic_totracee;
30121.1Skamil
30131.13Schristos	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
30141.1Skamil	    child, getpid());
30151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
30161.1Skamil
30171.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
30181.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
30191.1Skamil	    magic_totracee);
30201.1Skamil
30211.13Schristos	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
30221.1Skamil	    child, getpid());
30231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
30241.1Skamil
30251.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
30261.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
30271.1Skamil	    magic_fromtracee);
30281.1Skamil
30291.13Schristos	DPRINTF("Before resuming the child process where it left off and "
30301.1Skamil	    "without signal to be sent\n");
30311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
30321.1Skamil
30331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30351.1Skamil
30361.1Skamil	validate_status_exited(status, exitval);
30371.1Skamil
30381.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
30401.1Skamil}
30411.1Skamil
30421.1SkamilATF_TC(read_d_write_d_handshake1);
30431.1SkamilATF_TC_HEAD(read_d_write_d_handshake1, tc)
30441.1Skamil{
30451.1Skamil	atf_tc_set_md_var(tc, "descr",
30461.1Skamil	    "Verify PT_READ_D with PT_WRITE_D handshake");
30471.1Skamil}
30481.1Skamil
30491.1SkamilATF_TC_BODY(read_d_write_d_handshake1, tc)
30501.1Skamil{
30511.1Skamil	const int exitval = 5;
30521.1Skamil	const int sigval = SIGSTOP;
30531.1Skamil	pid_t child, wpid;
30541.1Skamil	int lookup_me_fromtracee = 0;
30551.1Skamil	const int magic_fromtracee = (int)random();
30561.1Skamil	int lookup_me_totracee = 0;
30571.1Skamil	const int magic_totracee = (int)random();
30581.1Skamil#if defined(TWAIT_HAVE_STATUS)
30591.1Skamil	int status;
30601.1Skamil#endif
30611.1Skamil
30621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
30631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
30641.1Skamil	if (child == 0) {
30651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
30661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
30671.1Skamil
30681.1Skamil		lookup_me_fromtracee = magic_fromtracee;
30691.1Skamil
30701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
30711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
30721.1Skamil
30731.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
30741.1Skamil
30751.13Schristos		DPRINTF("Before exiting of the child process\n");
30761.1Skamil		_exit(exitval);
30771.1Skamil	}
30781.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
30791.1Skamil
30801.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
30811.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
30821.1Skamil
30831.1Skamil	validate_status_stopped(status, sigval);
30841.1Skamil
30851.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
30861.1Skamil	    child, getpid());
30871.1Skamil	errno = 0;
30881.1Skamil	lookup_me_fromtracee =
30891.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
30901.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
30911.1Skamil
30921.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
30931.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
30941.1Skamil	    magic_fromtracee);
30951.1Skamil
30961.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
30971.1Skamil	    child, getpid());
30981.1Skamil	ATF_REQUIRE
30991.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
31001.1Skamil	    != -1);
31011.1Skamil
31021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31031.1Skamil	    "without signal to be sent\n");
31041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31051.1Skamil
31061.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31071.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31081.1Skamil
31091.1Skamil	validate_status_exited(status, exitval);
31101.1Skamil
31111.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31121.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31131.1Skamil}
31141.1Skamil
31151.1SkamilATF_TC(read_d_write_d_handshake2);
31161.1SkamilATF_TC_HEAD(read_d_write_d_handshake2, tc)
31171.1Skamil{
31181.1Skamil	atf_tc_set_md_var(tc, "descr",
31191.1Skamil	    "Verify PT_WRITE_D with PT_READ_D handshake");
31201.1Skamil}
31211.1Skamil
31221.1SkamilATF_TC_BODY(read_d_write_d_handshake2, tc)
31231.1Skamil{
31241.1Skamil	const int exitval = 5;
31251.1Skamil	const int sigval = SIGSTOP;
31261.1Skamil	pid_t child, wpid;
31271.1Skamil	int lookup_me_fromtracee = 0;
31281.1Skamil	const int magic_fromtracee = (int)random();
31291.1Skamil	int lookup_me_totracee = 0;
31301.1Skamil	const int magic_totracee = (int)random();
31311.1Skamil#if defined(TWAIT_HAVE_STATUS)
31321.1Skamil	int status;
31331.1Skamil#endif
31341.1Skamil
31351.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
31361.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
31371.1Skamil	if (child == 0) {
31381.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
31391.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
31401.1Skamil
31411.1Skamil		lookup_me_fromtracee = magic_fromtracee;
31421.1Skamil
31431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
31441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
31451.1Skamil
31461.1Skamil		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
31471.1Skamil
31481.13Schristos		DPRINTF("Before exiting of the child process\n");
31491.1Skamil		_exit(exitval);
31501.1Skamil	}
31511.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
31521.1Skamil
31531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31551.1Skamil
31561.1Skamil	validate_status_stopped(status, sigval);
31571.1Skamil
31581.13Schristos	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
31591.1Skamil	    child, getpid());
31601.1Skamil	ATF_REQUIRE
31611.1Skamil	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
31621.1Skamil	    != -1);
31631.1Skamil
31641.13Schristos	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
31651.1Skamil	    child, getpid());
31661.1Skamil	errno = 0;
31671.1Skamil	lookup_me_fromtracee =
31681.1Skamil	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
31691.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
31701.1Skamil
31711.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
31721.1Skamil	    "got value %#x != expected %#x", lookup_me_fromtracee,
31731.1Skamil	    magic_fromtracee);
31741.1Skamil
31751.13Schristos	DPRINTF("Before resuming the child process where it left off and "
31761.1Skamil	    "without signal to be sent\n");
31771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
31781.1Skamil
31791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
31811.1Skamil
31821.1Skamil	validate_status_exited(status, exitval);
31831.1Skamil
31841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
31851.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
31861.1Skamil}
31871.1Skamil
31881.1Skamil/* These dummy functions are used to be copied with ptrace(2) calls */
31891.1Skamilstatic int __used
31901.1Skamildummy_fn1(int a, int b, int c, int d)
31911.1Skamil{
31921.1Skamil
31931.1Skamil	a *= 1;
31941.1Skamil	b += 2;
31951.1Skamil	c -= 3;
31961.1Skamil	d /= 4;
31971.1Skamil
31981.1Skamil	return a + b * c - d;
31991.1Skamil}
32001.1Skamil
32011.1Skamilstatic int __used
32021.1Skamildummy_fn2(int a, int b, int c, int d)
32031.1Skamil{
32041.1Skamil
32051.1Skamil	a *= 4;
32061.1Skamil	b += 3;
32071.1Skamil	c -= 2;
32081.1Skamil	d /= 1;
32091.1Skamil
32101.1Skamil	return a + b * c - d;
32111.1Skamil}
32121.1Skamil
32131.1Skamilstatic int __used
32141.1Skamildummy_fn3(int a, int b, int c, int d)
32151.1Skamil{
32161.1Skamil
32171.1Skamil	a *= 10;
32181.1Skamil	b += 20;
32191.1Skamil	c -= 30;
32201.1Skamil	d /= 40;
32211.1Skamil
32221.1Skamil	return a + b * c - d;
32231.1Skamil}
32241.1Skamil
32251.1Skamilstatic int __used
32261.1Skamildummy_fn4(int a, int b, int c, int d)
32271.1Skamil{
32281.1Skamil
32291.1Skamil	a *= 40;
32301.1Skamil	b += 30;
32311.1Skamil	c -= 20;
32321.1Skamil	d /= 10;
32331.1Skamil
32341.1Skamil	return a + b * c - d;
32351.1Skamil}
32361.1Skamil
32371.1SkamilATF_TC(io_read_i1);
32381.1SkamilATF_TC_HEAD(io_read_i1, tc)
32391.1Skamil{
32401.1Skamil	atf_tc_set_md_var(tc, "descr",
32411.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
32421.1Skamil}
32431.1Skamil
32441.1SkamilATF_TC_BODY(io_read_i1, tc)
32451.1Skamil{
32461.1Skamil	const int exitval = 5;
32471.1Skamil	const int sigval = SIGSTOP;
32481.1Skamil	pid_t child, wpid;
32491.1Skamil	uint8_t lookup_me = 0;
32501.1Skamil	uint8_t magic;
32511.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
32521.1Skamil	struct ptrace_io_desc io = {
32531.1Skamil		.piod_op = PIOD_READ_I,
32541.1Skamil		.piod_offs = dummy_fn1,
32551.1Skamil		.piod_addr = &lookup_me,
32561.1Skamil		.piod_len = sizeof(lookup_me)
32571.1Skamil	};
32581.1Skamil#if defined(TWAIT_HAVE_STATUS)
32591.1Skamil	int status;
32601.1Skamil#endif
32611.1Skamil
32621.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
32631.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
32641.1Skamil	if (child == 0) {
32651.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
32661.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
32671.1Skamil
32681.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
32691.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
32701.1Skamil
32711.13Schristos		DPRINTF("Before exiting of the child process\n");
32721.1Skamil		_exit(exitval);
32731.1Skamil	}
32741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
32751.1Skamil
32761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32781.1Skamil
32791.1Skamil	validate_status_stopped(status, sigval);
32801.1Skamil
32811.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
32821.1Skamil	    child, getpid());
32831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
32841.1Skamil
32851.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
32861.1Skamil	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
32871.1Skamil
32881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
32891.1Skamil	    "without signal to be sent\n");
32901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
32911.1Skamil
32921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
32941.1Skamil
32951.1Skamil	validate_status_exited(status, exitval);
32961.1Skamil
32971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
32981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
32991.1Skamil}
33001.1Skamil
33011.1SkamilATF_TC(io_read_i2);
33021.1SkamilATF_TC_HEAD(io_read_i2, tc)
33031.1Skamil{
33041.1Skamil	atf_tc_set_md_var(tc, "descr",
33051.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
33061.1Skamil}
33071.1Skamil
33081.1SkamilATF_TC_BODY(io_read_i2, tc)
33091.1Skamil{
33101.1Skamil	const int exitval = 5;
33111.1Skamil	const int sigval = SIGSTOP;
33121.1Skamil	pid_t child, wpid;
33131.1Skamil	uint16_t lookup_me = 0;
33141.1Skamil	uint16_t magic;
33151.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33161.1Skamil	struct ptrace_io_desc io = {
33171.1Skamil		.piod_op = PIOD_READ_I,
33181.1Skamil		.piod_offs = dummy_fn1,
33191.1Skamil		.piod_addr = &lookup_me,
33201.1Skamil		.piod_len = sizeof(lookup_me)
33211.1Skamil	};
33221.1Skamil#if defined(TWAIT_HAVE_STATUS)
33231.1Skamil	int status;
33241.1Skamil#endif
33251.1Skamil
33261.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33271.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33281.1Skamil	if (child == 0) {
33291.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33301.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33311.1Skamil
33321.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33331.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33341.1Skamil
33351.13Schristos		DPRINTF("Before exiting of the child process\n");
33361.1Skamil		_exit(exitval);
33371.1Skamil	}
33381.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
33391.1Skamil
33401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33421.1Skamil
33431.1Skamil	validate_status_stopped(status, sigval);
33441.1Skamil
33451.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
33461.1Skamil	    child, getpid());
33471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
33481.1Skamil
33491.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
33501.1Skamil	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
33511.1Skamil
33521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
33531.1Skamil	    "without signal to be sent\n");
33541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
33551.1Skamil
33561.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33571.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
33581.1Skamil
33591.1Skamil	validate_status_exited(status, exitval);
33601.1Skamil
33611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
33621.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
33631.1Skamil}
33641.1Skamil
33651.1SkamilATF_TC(io_read_i3);
33661.1SkamilATF_TC_HEAD(io_read_i3, tc)
33671.1Skamil{
33681.1Skamil	atf_tc_set_md_var(tc, "descr",
33691.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
33701.1Skamil}
33711.1Skamil
33721.1SkamilATF_TC_BODY(io_read_i3, tc)
33731.1Skamil{
33741.1Skamil	const int exitval = 5;
33751.1Skamil	const int sigval = SIGSTOP;
33761.1Skamil	pid_t child, wpid;
33771.1Skamil	uint32_t lookup_me = 0;
33781.1Skamil	uint32_t magic;
33791.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
33801.1Skamil	struct ptrace_io_desc io = {
33811.1Skamil		.piod_op = PIOD_READ_I,
33821.1Skamil		.piod_offs = dummy_fn1,
33831.1Skamil		.piod_addr = &lookup_me,
33841.1Skamil		.piod_len = sizeof(lookup_me)
33851.1Skamil	};
33861.1Skamil#if defined(TWAIT_HAVE_STATUS)
33871.1Skamil	int status;
33881.1Skamil#endif
33891.1Skamil
33901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
33911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
33921.1Skamil	if (child == 0) {
33931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
33941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
33951.1Skamil
33961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
33971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
33981.1Skamil
33991.13Schristos		DPRINTF("Before exiting of the child process\n");
34001.1Skamil		_exit(exitval);
34011.1Skamil	}
34021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34031.1Skamil
34041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34061.1Skamil
34071.1Skamil	validate_status_stopped(status, sigval);
34081.1Skamil
34091.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34101.1Skamil	    child, getpid());
34111.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34121.1Skamil
34131.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34141.1Skamil	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
34151.1Skamil
34161.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34171.1Skamil	    "without signal to be sent\n");
34181.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34191.1Skamil
34201.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34211.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34221.1Skamil
34231.1Skamil	validate_status_exited(status, exitval);
34241.1Skamil
34251.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34261.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34271.1Skamil}
34281.1Skamil
34291.1SkamilATF_TC(io_read_i4);
34301.1SkamilATF_TC_HEAD(io_read_i4, tc)
34311.1Skamil{
34321.1Skamil	atf_tc_set_md_var(tc, "descr",
34331.1Skamil	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
34341.1Skamil}
34351.1Skamil
34361.1SkamilATF_TC_BODY(io_read_i4, tc)
34371.1Skamil{
34381.1Skamil	const int exitval = 5;
34391.1Skamil	const int sigval = SIGSTOP;
34401.1Skamil	pid_t child, wpid;
34411.1Skamil	uint64_t lookup_me = 0;
34421.1Skamil	uint64_t magic;
34431.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
34441.1Skamil	struct ptrace_io_desc io = {
34451.1Skamil		.piod_op = PIOD_READ_I,
34461.1Skamil		.piod_offs = dummy_fn1,
34471.1Skamil		.piod_addr = &lookup_me,
34481.1Skamil		.piod_len = sizeof(lookup_me)
34491.1Skamil	};
34501.1Skamil#if defined(TWAIT_HAVE_STATUS)
34511.1Skamil	int status;
34521.1Skamil#endif
34531.1Skamil
34541.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
34551.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
34561.1Skamil	if (child == 0) {
34571.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
34581.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
34591.1Skamil
34601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
34611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
34621.1Skamil
34631.13Schristos		DPRINTF("Before exiting of the child process\n");
34641.1Skamil		_exit(exitval);
34651.1Skamil	}
34661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
34671.1Skamil
34681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34701.1Skamil
34711.1Skamil	validate_status_stopped(status, sigval);
34721.1Skamil
34731.13Schristos	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
34741.1Skamil	    child, getpid());
34751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
34761.1Skamil
34771.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
34781.1Skamil	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
34791.1Skamil
34801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
34811.1Skamil	    "without signal to be sent\n");
34821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
34831.1Skamil
34841.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34851.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
34861.1Skamil
34871.1Skamil	validate_status_exited(status, exitval);
34881.1Skamil
34891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
34901.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
34911.1Skamil}
34921.1Skamil
34931.1SkamilATF_TC(read_i1);
34941.1SkamilATF_TC_HEAD(read_i1, tc)
34951.1Skamil{
34961.1Skamil	atf_tc_set_md_var(tc, "descr",
34971.1Skamil	    "Verify PT_READ_I called once");
34981.1Skamil}
34991.1Skamil
35001.1SkamilATF_TC_BODY(read_i1, tc)
35011.1Skamil{
35021.1Skamil	const int exitval = 5;
35031.1Skamil	const int sigval = SIGSTOP;
35041.1Skamil	pid_t child, wpid;
35051.1Skamil	int lookup_me = 0;
35061.1Skamil	int magic;
35071.1Skamil	memcpy(&magic, dummy_fn1, sizeof(magic));
35081.1Skamil#if defined(TWAIT_HAVE_STATUS)
35091.1Skamil	int status;
35101.1Skamil#endif
35111.1Skamil
35121.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35131.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35141.1Skamil	if (child == 0) {
35151.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35161.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35171.1Skamil
35181.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35191.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35201.1Skamil
35211.13Schristos		DPRINTF("Before exiting of the child process\n");
35221.1Skamil		_exit(exitval);
35231.1Skamil	}
35241.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35251.1Skamil
35261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35271.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35281.1Skamil
35291.1Skamil	validate_status_stopped(status, sigval);
35301.1Skamil
35311.13Schristos	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
35321.1Skamil	    child, getpid());
35331.1Skamil	errno = 0;
35341.1Skamil	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
35351.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35361.1Skamil
35371.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
35381.1Skamil	    "got value %#x != expected %#x", lookup_me, magic);
35391.1Skamil
35401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
35411.1Skamil	    "without signal to be sent\n");
35421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
35431.1Skamil
35441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35461.1Skamil
35471.1Skamil	validate_status_exited(status, exitval);
35481.1Skamil
35491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35501.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
35511.1Skamil}
35521.1Skamil
35531.1SkamilATF_TC(read_i2);
35541.1SkamilATF_TC_HEAD(read_i2, tc)
35551.1Skamil{
35561.1Skamil	atf_tc_set_md_var(tc, "descr",
35571.1Skamil	    "Verify PT_READ_I called twice");
35581.1Skamil}
35591.1Skamil
35601.1SkamilATF_TC_BODY(read_i2, tc)
35611.1Skamil{
35621.1Skamil	const int exitval = 5;
35631.1Skamil	const int sigval = SIGSTOP;
35641.1Skamil	pid_t child, wpid;
35651.1Skamil	int lookup_me1 = 0;
35661.1Skamil	int lookup_me2 = 0;
35671.1Skamil	int magic1;
35681.1Skamil	int magic2;
35691.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
35701.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
35711.1Skamil#if defined(TWAIT_HAVE_STATUS)
35721.1Skamil	int status;
35731.1Skamil#endif
35741.1Skamil
35751.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
35761.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
35771.1Skamil	if (child == 0) {
35781.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
35791.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
35801.1Skamil
35811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
35821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
35831.1Skamil
35841.13Schristos		DPRINTF("Before exiting of the child process\n");
35851.1Skamil		_exit(exitval);
35861.1Skamil	}
35871.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
35881.1Skamil
35891.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
35901.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
35911.1Skamil
35921.1Skamil	validate_status_stopped(status, sigval);
35931.1Skamil
35941.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
35951.1Skamil	    child, getpid());
35961.1Skamil	errno = 0;
35971.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
35981.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
35991.1Skamil
36001.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
36011.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
36021.1Skamil
36031.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
36041.1Skamil	    child, getpid());
36051.1Skamil	errno = 0;
36061.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
36071.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36081.1Skamil
36091.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
36101.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
36111.1Skamil
36121.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36131.1Skamil	    "without signal to be sent\n");
36141.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36151.1Skamil
36161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36181.1Skamil
36191.1Skamil	validate_status_exited(status, exitval);
36201.1Skamil
36211.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
36231.1Skamil}
36241.1Skamil
36251.1SkamilATF_TC(read_i3);
36261.1SkamilATF_TC_HEAD(read_i3, tc)
36271.1Skamil{
36281.1Skamil	atf_tc_set_md_var(tc, "descr",
36291.1Skamil	    "Verify PT_READ_I called three times");
36301.1Skamil}
36311.1Skamil
36321.1SkamilATF_TC_BODY(read_i3, tc)
36331.1Skamil{
36341.1Skamil	const int exitval = 5;
36351.1Skamil	const int sigval = SIGSTOP;
36361.1Skamil	pid_t child, wpid;
36371.1Skamil	int lookup_me1 = 0;
36381.1Skamil	int lookup_me2 = 0;
36391.1Skamil	int lookup_me3 = 0;
36401.1Skamil	int magic1;
36411.1Skamil	int magic2;
36421.1Skamil	int magic3;
36431.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
36441.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
36451.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
36461.1Skamil#if defined(TWAIT_HAVE_STATUS)
36471.1Skamil	int status;
36481.1Skamil#endif
36491.1Skamil
36501.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
36511.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
36521.1Skamil	if (child == 0) {
36531.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
36541.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
36551.1Skamil
36561.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
36571.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
36581.1Skamil
36591.13Schristos		DPRINTF("Before exiting of the child process\n");
36601.1Skamil		_exit(exitval);
36611.1Skamil	}
36621.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
36631.1Skamil
36641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
36651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
36661.1Skamil
36671.1Skamil	validate_status_stopped(status, sigval);
36681.1Skamil
36691.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
36701.1Skamil	    child, getpid());
36711.1Skamil	errno = 0;
36721.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
36731.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36741.1Skamil
36751.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
36761.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
36771.1Skamil
36781.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
36791.1Skamil	    child, getpid());
36801.1Skamil	errno = 0;
36811.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
36821.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36831.1Skamil
36841.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
36851.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
36861.1Skamil
36871.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
36881.1Skamil	    child, getpid());
36891.1Skamil	errno = 0;
36901.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
36911.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
36921.1Skamil
36931.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
36941.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
36951.1Skamil
36961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
36971.1Skamil	    "without signal to be sent\n");
36981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
36991.1Skamil
37001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37021.1Skamil
37031.1Skamil	validate_status_exited(status, exitval);
37041.1Skamil
37051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
37071.1Skamil}
37081.1Skamil
37091.1SkamilATF_TC(read_i4);
37101.1SkamilATF_TC_HEAD(read_i4, tc)
37111.1Skamil{
37121.1Skamil	atf_tc_set_md_var(tc, "descr",
37131.1Skamil	    "Verify PT_READ_I called four times");
37141.1Skamil}
37151.1Skamil
37161.1SkamilATF_TC_BODY(read_i4, tc)
37171.1Skamil{
37181.1Skamil	const int exitval = 5;
37191.1Skamil	const int sigval = SIGSTOP;
37201.1Skamil	pid_t child, wpid;
37211.1Skamil	int lookup_me1 = 0;
37221.1Skamil	int lookup_me2 = 0;
37231.1Skamil	int lookup_me3 = 0;
37241.1Skamil	int lookup_me4 = 0;
37251.1Skamil	int magic1;
37261.1Skamil	int magic2;
37271.1Skamil	int magic3;
37281.1Skamil	int magic4;
37291.1Skamil	memcpy(&magic1, dummy_fn1, sizeof(magic1));
37301.1Skamil	memcpy(&magic2, dummy_fn2, sizeof(magic2));
37311.1Skamil	memcpy(&magic3, dummy_fn3, sizeof(magic3));
37321.1Skamil	memcpy(&magic4, dummy_fn4, sizeof(magic4));
37331.1Skamil#if defined(TWAIT_HAVE_STATUS)
37341.1Skamil	int status;
37351.1Skamil#endif
37361.1Skamil
37371.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
37381.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
37391.1Skamil	if (child == 0) {
37401.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
37411.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
37421.1Skamil
37431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
37441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
37451.1Skamil
37461.13Schristos		DPRINTF("Before exiting of the child process\n");
37471.1Skamil		_exit(exitval);
37481.1Skamil	}
37491.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
37501.1Skamil
37511.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37531.1Skamil
37541.1Skamil	validate_status_stopped(status, sigval);
37551.1Skamil
37561.13Schristos	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
37571.1Skamil	    child, getpid());
37581.1Skamil	errno = 0;
37591.1Skamil	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
37601.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37611.1Skamil
37621.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
37631.1Skamil	    "got value %#x != expected %#x", lookup_me1, magic1);
37641.1Skamil
37651.13Schristos	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
37661.1Skamil	    child, getpid());
37671.1Skamil	errno = 0;
37681.1Skamil	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
37691.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37701.1Skamil
37711.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
37721.1Skamil	    "got value %#x != expected %#x", lookup_me2, magic2);
37731.1Skamil
37741.13Schristos	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
37751.1Skamil	    child, getpid());
37761.1Skamil	errno = 0;
37771.1Skamil	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
37781.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37791.1Skamil
37801.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
37811.1Skamil	    "got value %#x != expected %#x", lookup_me3, magic3);
37821.1Skamil
37831.13Schristos	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
37841.1Skamil	    child, getpid());
37851.1Skamil	errno = 0;
37861.1Skamil	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
37871.18Schristos	SYSCALL_REQUIRE_ERRNO(errno, 0);
37881.1Skamil
37891.1Skamil	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
37901.1Skamil	    "got value %#x != expected %#x", lookup_me4, magic4);
37911.1Skamil
37921.13Schristos	DPRINTF("Before resuming the child process where it left off and "
37931.1Skamil	    "without signal to be sent\n");
37941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
37951.1Skamil
37961.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
37971.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
37981.1Skamil
37991.1Skamil	validate_status_exited(status, exitval);
38001.1Skamil
38011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38021.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38031.1Skamil}
38041.1Skamil
38051.1Skamil#if defined(HAVE_GPREGS)
38061.1SkamilATF_TC(regs1);
38071.1SkamilATF_TC_HEAD(regs1, tc)
38081.1Skamil{
38091.1Skamil	atf_tc_set_md_var(tc, "descr",
38101.1Skamil	    "Verify plain PT_GETREGS call without further steps");
38111.1Skamil}
38121.1Skamil
38131.1SkamilATF_TC_BODY(regs1, tc)
38141.1Skamil{
38151.1Skamil	const int exitval = 5;
38161.1Skamil	const int sigval = SIGSTOP;
38171.1Skamil	pid_t child, wpid;
38181.1Skamil#if defined(TWAIT_HAVE_STATUS)
38191.1Skamil	int status;
38201.1Skamil#endif
38211.1Skamil	struct reg r;
38221.1Skamil
38231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38251.1Skamil	if (child == 0) {
38261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38281.1Skamil
38291.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38301.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38311.1Skamil
38321.13Schristos		DPRINTF("Before exiting of the child process\n");
38331.1Skamil		_exit(exitval);
38341.1Skamil	}
38351.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38361.1Skamil
38371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38381.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38391.1Skamil
38401.1Skamil	validate_status_stopped(status, sigval);
38411.1Skamil
38421.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38431.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38441.1Skamil
38451.13Schristos	DPRINTF("Before resuming the child process where it left off and "
38461.1Skamil	    "without signal to be sent\n");
38471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
38481.1Skamil
38491.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38501.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38511.1Skamil
38521.1Skamil	validate_status_exited(status, exitval);
38531.1Skamil
38541.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38551.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
38561.1Skamil}
38571.1Skamil#endif
38581.1Skamil
38591.1Skamil#if defined(HAVE_GPREGS)
38601.1SkamilATF_TC(regs2);
38611.1SkamilATF_TC_HEAD(regs2, tc)
38621.1Skamil{
38631.1Skamil	atf_tc_set_md_var(tc, "descr",
38641.1Skamil	    "Verify plain PT_GETREGS call and retrieve PC");
38651.1Skamil}
38661.1Skamil
38671.1SkamilATF_TC_BODY(regs2, tc)
38681.1Skamil{
38691.1Skamil	const int exitval = 5;
38701.1Skamil	const int sigval = SIGSTOP;
38711.1Skamil	pid_t child, wpid;
38721.1Skamil#if defined(TWAIT_HAVE_STATUS)
38731.1Skamil	int status;
38741.1Skamil#endif
38751.1Skamil	struct reg r;
38761.1Skamil
38771.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
38781.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
38791.1Skamil	if (child == 0) {
38801.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
38811.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
38821.1Skamil
38831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
38841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
38851.1Skamil
38861.13Schristos		DPRINTF("Before exiting of the child process\n");
38871.1Skamil		_exit(exitval);
38881.1Skamil	}
38891.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
38901.1Skamil
38911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
38921.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
38931.1Skamil
38941.1Skamil	validate_status_stopped(status, sigval);
38951.1Skamil
38961.13Schristos	DPRINTF("Call GETREGS for the child process\n");
38971.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
38981.1Skamil
38991.13Schristos	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
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#endif
39141.1Skamil
39151.1Skamil#if defined(HAVE_GPREGS)
39161.1SkamilATF_TC(regs3);
39171.1SkamilATF_TC_HEAD(regs3, tc)
39181.1Skamil{
39191.1Skamil	atf_tc_set_md_var(tc, "descr",
39201.1Skamil	    "Verify plain PT_GETREGS call and retrieve SP");
39211.1Skamil}
39221.1Skamil
39231.1SkamilATF_TC_BODY(regs3, tc)
39241.1Skamil{
39251.1Skamil	const int exitval = 5;
39261.1Skamil	const int sigval = SIGSTOP;
39271.1Skamil	pid_t child, wpid;
39281.1Skamil#if defined(TWAIT_HAVE_STATUS)
39291.1Skamil	int status;
39301.1Skamil#endif
39311.1Skamil	struct reg r;
39321.1Skamil
39331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39351.1Skamil	if (child == 0) {
39361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39381.1Skamil
39391.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39401.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39411.1Skamil
39421.13Schristos		DPRINTF("Before exiting of the child process\n");
39431.1Skamil		_exit(exitval);
39441.1Skamil	}
39451.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
39461.1Skamil
39471.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39481.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39491.1Skamil
39501.1Skamil	validate_status_stopped(status, sigval);
39511.1Skamil
39521.13Schristos	DPRINTF("Call GETREGS for the child process\n");
39531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
39541.1Skamil
39551.13Schristos	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
39561.1Skamil
39571.13Schristos	DPRINTF("Before resuming the child process where it left off and "
39581.1Skamil	    "without signal to be sent\n");
39591.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
39601.1Skamil
39611.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
39631.1Skamil
39641.1Skamil	validate_status_exited(status, exitval);
39651.1Skamil
39661.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
39671.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
39681.1Skamil}
39691.1Skamil#endif
39701.1Skamil
39711.1Skamil#if defined(HAVE_GPREGS)
39721.1SkamilATF_TC(regs4);
39731.1SkamilATF_TC_HEAD(regs4, tc)
39741.1Skamil{
39751.1Skamil	atf_tc_set_md_var(tc, "descr",
39761.1Skamil	    "Verify plain PT_GETREGS call and retrieve INTRV");
39771.1Skamil}
39781.1Skamil
39791.1SkamilATF_TC_BODY(regs4, tc)
39801.1Skamil{
39811.1Skamil	const int exitval = 5;
39821.1Skamil	const int sigval = SIGSTOP;
39831.1Skamil	pid_t child, wpid;
39841.1Skamil#if defined(TWAIT_HAVE_STATUS)
39851.1Skamil	int status;
39861.1Skamil#endif
39871.1Skamil	struct reg r;
39881.1Skamil
39891.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
39901.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
39911.1Skamil	if (child == 0) {
39921.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
39931.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
39941.1Skamil
39951.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
39961.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
39971.1Skamil
39981.13Schristos		DPRINTF("Before exiting of the child process\n");
39991.1Skamil		_exit(exitval);
40001.1Skamil	}
40011.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40021.1Skamil
40031.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40051.1Skamil
40061.1Skamil	validate_status_stopped(status, sigval);
40071.1Skamil
40081.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40091.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40101.1Skamil
40111.13Schristos	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
40121.1Skamil
40131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40141.1Skamil	    "without signal to be sent\n");
40151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40161.1Skamil
40171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40191.1Skamil
40201.1Skamil	validate_status_exited(status, exitval);
40211.1Skamil
40221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40231.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40241.1Skamil}
40251.1Skamil#endif
40261.1Skamil
40271.1Skamil#if defined(HAVE_GPREGS)
40281.1SkamilATF_TC(regs5);
40291.1SkamilATF_TC_HEAD(regs5, tc)
40301.1Skamil{
40311.1Skamil	atf_tc_set_md_var(tc, "descr",
40321.1Skamil	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
40331.1Skamil}
40341.1Skamil
40351.1SkamilATF_TC_BODY(regs5, tc)
40361.1Skamil{
40371.1Skamil	const int exitval = 5;
40381.1Skamil	const int sigval = SIGSTOP;
40391.1Skamil	pid_t child, wpid;
40401.1Skamil#if defined(TWAIT_HAVE_STATUS)
40411.1Skamil	int status;
40421.1Skamil#endif
40431.1Skamil	struct reg r;
40441.1Skamil
40451.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
40461.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
40471.1Skamil	if (child == 0) {
40481.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
40491.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
40501.1Skamil
40511.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
40521.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
40531.1Skamil
40541.13Schristos		DPRINTF("Before exiting of the child process\n");
40551.1Skamil		_exit(exitval);
40561.1Skamil	}
40571.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
40581.1Skamil
40591.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40601.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40611.1Skamil
40621.1Skamil	validate_status_stopped(status, sigval);
40631.1Skamil
40641.13Schristos	DPRINTF("Call GETREGS for the child process\n");
40651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40661.1Skamil
40671.13Schristos	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
40681.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
40691.1Skamil
40701.13Schristos	DPRINTF("Before resuming the child process where it left off and "
40711.1Skamil	    "without signal to be sent\n");
40721.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
40731.1Skamil
40741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
40761.1Skamil
40771.1Skamil	validate_status_exited(status, exitval);
40781.1Skamil
40791.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
40801.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
40811.1Skamil}
40821.1Skamil#endif
40831.1Skamil
40841.1Skamil#if defined(HAVE_FPREGS)
40851.1SkamilATF_TC(fpregs1);
40861.1SkamilATF_TC_HEAD(fpregs1, tc)
40871.1Skamil{
40881.1Skamil	atf_tc_set_md_var(tc, "descr",
40891.1Skamil	    "Verify plain PT_GETFPREGS call without further steps");
40901.1Skamil}
40911.1Skamil
40921.1SkamilATF_TC_BODY(fpregs1, tc)
40931.1Skamil{
40941.1Skamil	const int exitval = 5;
40951.1Skamil	const int sigval = SIGSTOP;
40961.1Skamil	pid_t child, wpid;
40971.1Skamil#if defined(TWAIT_HAVE_STATUS)
40981.1Skamil	int status;
40991.1Skamil#endif
41001.1Skamil	struct fpreg r;
41011.1Skamil
41021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41041.1Skamil	if (child == 0) {
41051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41071.1Skamil
41081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41101.1Skamil
41111.13Schristos		DPRINTF("Before exiting of the child process\n");
41121.1Skamil		_exit(exitval);
41131.1Skamil	}
41141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41151.1Skamil
41161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41181.1Skamil
41191.1Skamil	validate_status_stopped(status, sigval);
41201.1Skamil
41211.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
41221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
41231.1Skamil
41241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41251.1Skamil	    "without signal to be sent\n");
41261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41271.1Skamil
41281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41301.1Skamil
41311.1Skamil	validate_status_exited(status, exitval);
41321.1Skamil
41331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41351.1Skamil}
41361.1Skamil#endif
41371.1Skamil
41381.1Skamil#if defined(HAVE_FPREGS)
41391.1SkamilATF_TC(fpregs2);
41401.1SkamilATF_TC_HEAD(fpregs2, tc)
41411.1Skamil{
41421.1Skamil	atf_tc_set_md_var(tc, "descr",
41431.1Skamil	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
41441.1Skamil	    "regs");
41451.1Skamil}
41461.1Skamil
41471.1SkamilATF_TC_BODY(fpregs2, tc)
41481.1Skamil{
41491.1Skamil	const int exitval = 5;
41501.1Skamil	const int sigval = SIGSTOP;
41511.1Skamil	pid_t child, wpid;
41521.1Skamil#if defined(TWAIT_HAVE_STATUS)
41531.1Skamil	int status;
41541.1Skamil#endif
41551.1Skamil	struct fpreg r;
41561.1Skamil
41571.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
41581.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
41591.1Skamil	if (child == 0) {
41601.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
41611.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
41621.1Skamil
41631.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
41641.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
41651.1Skamil
41661.13Schristos		DPRINTF("Before exiting of the child process\n");
41671.1Skamil		_exit(exitval);
41681.1Skamil	}
41691.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
41701.1Skamil
41711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41731.1Skamil
41741.1Skamil	validate_status_stopped(status, sigval);
41751.1Skamil
41761.13Schristos	DPRINTF("Call GETFPREGS for the child process\n");
41771.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
41781.1Skamil
41791.13Schristos	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
41801.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
41811.1Skamil
41821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
41831.1Skamil	    "without signal to be sent\n");
41841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
41851.1Skamil
41861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
41881.1Skamil
41891.1Skamil	validate_status_exited(status, exitval);
41901.1Skamil
41911.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
41921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
41931.1Skamil}
41941.1Skamil#endif
41951.1Skamil
41961.1Skamil#if defined(PT_STEP)
41971.1Skamilstatic void
41981.2Skamilptrace_step(int N, int setstep)
41991.1Skamil{
42001.1Skamil	const int exitval = 5;
42011.1Skamil	const int sigval = SIGSTOP;
42021.1Skamil	pid_t child, wpid;
42031.1Skamil#if defined(TWAIT_HAVE_STATUS)
42041.1Skamil	int status;
42051.1Skamil#endif
42061.1Skamil	int happy;
42071.1Skamil
42081.1Skamil#if defined(__arm__)
42091.1Skamil	/* PT_STEP not supported on arm 32-bit */
42101.1Skamil	atf_tc_expect_fail("PR kern/52119");
42111.1Skamil#endif
42121.1Skamil
42131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
42141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
42151.1Skamil	if (child == 0) {
42161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
42171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
42181.1Skamil
42191.1Skamil		happy = check_happy(999);
42201.1Skamil
42211.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
42221.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
42231.1Skamil
42241.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(999));
42251.1Skamil
42261.13Schristos		DPRINTF("Before exiting of the child process\n");
42271.1Skamil		_exit(exitval);
42281.1Skamil	}
42291.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
42301.1Skamil
42311.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42321.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42331.1Skamil
42341.1Skamil	validate_status_stopped(status, sigval);
42351.1Skamil
42361.1Skamil	while (N --> 0) {
42371.2Skamil		if (setstep) {
42381.13Schristos			DPRINTF("Before resuming the child process where it "
42391.2Skamil			    "left off and without signal to be sent (use "
42401.9Skamil			    "PT_SETSTEP and PT_CONTINUE)\n");
42411.13Schristos			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
42421.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
42431.2Skamil			    != -1);
42441.2Skamil		} else {
42451.13Schristos			DPRINTF("Before resuming the child process where it "
42461.2Skamil			    "left off and without signal to be sent (use "
42471.2Skamil			    "PT_STEP)\n");
42481.13Schristos			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
42491.2Skamil			    != -1);
42501.2Skamil		}
42511.1Skamil
42521.13Schristos		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42531.1Skamil		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
42541.1Skamil		    child);
42551.1Skamil
42561.1Skamil		validate_status_stopped(status, SIGTRAP);
42571.2Skamil
42581.2Skamil		if (setstep) {
42591.13Schristos			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
42601.2Skamil		}
42611.1Skamil	}
42621.1Skamil
42631.13Schristos	DPRINTF("Before resuming the child process where it left off and "
42641.1Skamil	    "without signal to be sent\n");
42651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
42661.1Skamil
42671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
42691.1Skamil
42701.1Skamil	validate_status_exited(status, exitval);
42711.1Skamil
42721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
42731.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
42741.1Skamil}
42751.1Skamil#endif
42761.1Skamil
42771.1Skamil#if defined(PT_STEP)
42781.1SkamilATF_TC(step1);
42791.1SkamilATF_TC_HEAD(step1, tc)
42801.1Skamil{
42811.1Skamil	atf_tc_set_md_var(tc, "descr",
42821.1Skamil	    "Verify single PT_STEP call");
42831.1Skamil}
42841.1Skamil
42851.1SkamilATF_TC_BODY(step1, tc)
42861.1Skamil{
42871.2Skamil	ptrace_step(1, 0);
42881.1Skamil}
42891.1Skamil#endif
42901.1Skamil
42911.1Skamil#if defined(PT_STEP)
42921.1SkamilATF_TC(step2);
42931.1SkamilATF_TC_HEAD(step2, tc)
42941.1Skamil{
42951.1Skamil	atf_tc_set_md_var(tc, "descr",
42961.1Skamil	    "Verify PT_STEP called twice");
42971.1Skamil}
42981.1Skamil
42991.1SkamilATF_TC_BODY(step2, tc)
43001.1Skamil{
43011.2Skamil	ptrace_step(2, 0);
43021.1Skamil}
43031.1Skamil#endif
43041.1Skamil
43051.1Skamil#if defined(PT_STEP)
43061.1SkamilATF_TC(step3);
43071.1SkamilATF_TC_HEAD(step3, tc)
43081.1Skamil{
43091.1Skamil	atf_tc_set_md_var(tc, "descr",
43101.1Skamil	    "Verify PT_STEP called three times");
43111.1Skamil}
43121.1Skamil
43131.1SkamilATF_TC_BODY(step3, tc)
43141.1Skamil{
43151.2Skamil	ptrace_step(3, 0);
43161.1Skamil}
43171.1Skamil#endif
43181.1Skamil
43191.1Skamil#if defined(PT_STEP)
43201.1SkamilATF_TC(step4);
43211.1SkamilATF_TC_HEAD(step4, tc)
43221.1Skamil{
43231.1Skamil	atf_tc_set_md_var(tc, "descr",
43241.1Skamil	    "Verify PT_STEP called four times");
43251.1Skamil}
43261.1Skamil
43271.1SkamilATF_TC_BODY(step4, tc)
43281.1Skamil{
43291.2Skamil	ptrace_step(4, 0);
43301.2Skamil}
43311.2Skamil#endif
43321.2Skamil
43331.2Skamil#if defined(PT_STEP)
43341.2SkamilATF_TC(setstep1);
43351.2SkamilATF_TC_HEAD(setstep1, tc)
43361.2Skamil{
43371.2Skamil	atf_tc_set_md_var(tc, "descr",
43381.2Skamil	    "Verify single PT_SETSTEP call");
43391.2Skamil}
43401.2Skamil
43411.2SkamilATF_TC_BODY(setstep1, tc)
43421.2Skamil{
43431.2Skamil	ptrace_step(1, 1);
43441.2Skamil}
43451.2Skamil#endif
43461.2Skamil
43471.2Skamil#if defined(PT_STEP)
43481.2SkamilATF_TC(setstep2);
43491.2SkamilATF_TC_HEAD(setstep2, tc)
43501.2Skamil{
43511.2Skamil	atf_tc_set_md_var(tc, "descr",
43521.2Skamil	    "Verify PT_SETSTEP called twice");
43531.2Skamil}
43541.2Skamil
43551.2SkamilATF_TC_BODY(setstep2, tc)
43561.2Skamil{
43571.2Skamil	ptrace_step(2, 1);
43581.2Skamil}
43591.2Skamil#endif
43601.2Skamil
43611.2Skamil#if defined(PT_STEP)
43621.2SkamilATF_TC(setstep3);
43631.2SkamilATF_TC_HEAD(setstep3, tc)
43641.2Skamil{
43651.2Skamil	atf_tc_set_md_var(tc, "descr",
43661.2Skamil	    "Verify PT_SETSTEP called three times");
43671.2Skamil}
43681.2Skamil
43691.2SkamilATF_TC_BODY(setstep3, tc)
43701.2Skamil{
43711.2Skamil	ptrace_step(3, 1);
43721.2Skamil}
43731.2Skamil#endif
43741.2Skamil
43751.2Skamil#if defined(PT_STEP)
43761.2SkamilATF_TC(setstep4);
43771.2SkamilATF_TC_HEAD(setstep4, tc)
43781.2Skamil{
43791.2Skamil	atf_tc_set_md_var(tc, "descr",
43801.2Skamil	    "Verify PT_SETSTEP called four times");
43811.2Skamil}
43821.2Skamil
43831.2SkamilATF_TC_BODY(setstep4, tc)
43841.2Skamil{
43851.2Skamil	ptrace_step(4, 1);
43861.1Skamil}
43871.1Skamil#endif
43881.1Skamil
43891.1SkamilATF_TC(kill1);
43901.1SkamilATF_TC_HEAD(kill1, tc)
43911.1Skamil{
43921.1Skamil	atf_tc_set_md_var(tc, "descr",
43931.1Skamil	    "Verify that PT_CONTINUE with SIGKILL terminates child");
43941.1Skamil}
43951.1Skamil
43961.1SkamilATF_TC_BODY(kill1, tc)
43971.1Skamil{
43981.1Skamil	const int sigval = SIGSTOP, sigsent = SIGKILL;
43991.1Skamil	pid_t child, wpid;
44001.1Skamil#if defined(TWAIT_HAVE_STATUS)
44011.1Skamil	int status;
44021.1Skamil#endif
44031.1Skamil
44041.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44051.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44061.1Skamil	if (child == 0) {
44071.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44081.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44091.1Skamil
44101.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44111.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44121.1Skamil
44131.1Skamil		/* NOTREACHED */
44141.1Skamil		FORKEE_ASSERTX(0 &&
44151.1Skamil		    "Child should be terminated by a signal from its parent");
44161.1Skamil	}
44171.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44181.1Skamil
44191.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44211.1Skamil
44221.1Skamil	validate_status_stopped(status, sigval);
44231.1Skamil
44241.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44251.1Skamil	    "without signal to be sent\n");
44261.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
44271.1Skamil
44281.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44301.1Skamil
44311.1Skamil	validate_status_signaled(status, sigsent, 0);
44321.1Skamil
44331.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44341.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44351.1Skamil}
44361.1Skamil
44371.1SkamilATF_TC(kill2);
44381.1SkamilATF_TC_HEAD(kill2, tc)
44391.1Skamil{
44401.1Skamil	atf_tc_set_md_var(tc, "descr",
44411.1Skamil	    "Verify that PT_KILL terminates child");
44421.1Skamil}
44431.1Skamil
44441.1SkamilATF_TC_BODY(kill2, tc)
44451.1Skamil{
44461.1Skamil	const int sigval = SIGSTOP;
44471.1Skamil	pid_t child, wpid;
44481.1Skamil#if defined(TWAIT_HAVE_STATUS)
44491.1Skamil	int status;
44501.1Skamil#endif
44511.1Skamil
44521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
44531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
44541.1Skamil	if (child == 0) {
44551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
44561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
44571.1Skamil
44581.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
44591.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
44601.1Skamil
44611.1Skamil		/* NOTREACHED */
44621.1Skamil		FORKEE_ASSERTX(0 &&
44631.1Skamil		    "Child should be terminated by a signal from its parent");
44641.1Skamil	}
44651.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
44661.1Skamil
44671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44681.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44691.1Skamil
44701.1Skamil	validate_status_stopped(status, sigval);
44711.1Skamil
44721.13Schristos	DPRINTF("Before resuming the child process where it left off and "
44731.1Skamil	    "without signal to be sent\n");
44741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
44751.1Skamil
44761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
44781.1Skamil
44791.1Skamil	validate_status_signaled(status, SIGKILL, 0);
44801.1Skamil
44811.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
44821.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
44831.1Skamil}
44841.1Skamil
44851.1SkamilATF_TC(lwpinfo1);
44861.1SkamilATF_TC_HEAD(lwpinfo1, tc)
44871.1Skamil{
44881.1Skamil	atf_tc_set_md_var(tc, "descr",
44891.1Skamil	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
44901.1Skamil}
44911.1Skamil
44921.1SkamilATF_TC_BODY(lwpinfo1, tc)
44931.1Skamil{
44941.1Skamil	const int exitval = 5;
44951.1Skamil	const int sigval = SIGSTOP;
44961.1Skamil	pid_t child, wpid;
44971.1Skamil#if defined(TWAIT_HAVE_STATUS)
44981.1Skamil	int status;
44991.1Skamil#endif
45001.1Skamil	struct ptrace_lwpinfo info = {0, 0};
45011.1Skamil
45021.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
45031.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
45041.1Skamil	if (child == 0) {
45051.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
45061.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
45071.1Skamil
45081.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
45091.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
45101.1Skamil
45111.13Schristos		DPRINTF("Before exiting of the child process\n");
45121.1Skamil		_exit(exitval);
45131.1Skamil	}
45141.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
45151.1Skamil
45161.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45171.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45181.1Skamil
45191.1Skamil	validate_status_stopped(status, sigval);
45201.1Skamil
45211.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
45221.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
45231.1Skamil
45241.13Schristos	DPRINTF("Assert that there exists a thread\n");
45251.1Skamil	ATF_REQUIRE(info.pl_lwpid > 0);
45261.1Skamil
45271.13Schristos	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
45281.1Skamil	    info.pl_lwpid);
45291.1Skamil	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
45301.1Skamil	    "Received event %d != expected event %d",
45311.1Skamil	    info.pl_event, PL_EVENT_SIGNAL);
45321.1Skamil
45331.13Schristos	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
45341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
45351.1Skamil
45361.13Schristos	DPRINTF("Assert that there are no more lwp threads in child\n");
45371.1Skamil	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
45381.1Skamil
45391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
45401.1Skamil	    "without signal to be sent\n");
45411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
45421.1Skamil
45431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
45451.1Skamil
45461.1Skamil	validate_status_exited(status, exitval);
45471.1Skamil
45481.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
45491.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
45501.1Skamil}
45511.1Skamil
45521.1Skamil#if defined(TWAIT_HAVE_PID)
45531.1SkamilATF_TC(lwpinfo2);
45541.1SkamilATF_TC_HEAD(lwpinfo2, tc)
45551.1Skamil{
45561.1Skamil	atf_tc_set_md_var(tc, "descr",
45571.1Skamil	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
45581.1Skamil	    "tracer)");
45591.1Skamil}
45601.1Skamil
45611.1SkamilATF_TC_BODY(lwpinfo2, tc)
45621.1Skamil{
45631.1Skamil	struct msg_fds parent_tracee, parent_tracer;
45641.1Skamil	const int exitval_tracee = 5;
45651.1Skamil	const int exitval_tracer = 10;
45661.1Skamil	pid_t tracee, tracer, wpid;
45671.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
45681.1Skamil#if defined(TWAIT_HAVE_STATUS)
45691.1Skamil	int status;
45701.1Skamil#endif
45711.1Skamil	struct ptrace_lwpinfo info = {0, 0};
45721.1Skamil
45731.13Schristos	DPRINTF("Spawn tracee\n");
45741.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
45751.13Schristos	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
45761.1Skamil	tracee = atf_utils_fork();
45771.1Skamil	if (tracee == 0) {
45781.1Skamil
45791.1Skamil		/* Wait for message from the parent */
45801.1Skamil		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
45811.1Skamil		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
45821.1Skamil
45831.1Skamil		_exit(exitval_tracee);
45841.1Skamil	}
45851.1Skamil	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
45861.1Skamil
45871.13Schristos	DPRINTF("Spawn debugger\n");
45881.1Skamil	tracer = atf_utils_fork();
45891.1Skamil	if (tracer == 0) {
45901.1Skamil		/* No IPC to communicate with the child */
45911.13Schristos		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
45921.1Skamil		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
45931.1Skamil
45941.1Skamil		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
45951.1Skamil		FORKEE_REQUIRE_SUCCESS(
45961.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
45971.1Skamil
45981.1Skamil		forkee_status_stopped(status, SIGSTOP);
45991.1Skamil
46001.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
46011.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
46021.1Skamil		    != -1);
46031.1Skamil
46041.13Schristos		DPRINTF("Assert that there exists a thread\n");
46051.1Skamil		FORKEE_ASSERTX(info.pl_lwpid > 0);
46061.1Skamil
46071.13Schristos		DPRINTF("Assert that lwp thread %d received event "
46081.1Skamil		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
46091.1Skamil		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
46101.1Skamil
46111.13Schristos		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
46121.1Skamil		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
46131.1Skamil		    != -1);
46141.1Skamil
46151.13Schristos		DPRINTF("Assert that there are no more lwp threads in child\n");
46161.1Skamil		FORKEE_ASSERTX(info.pl_lwpid == 0);
46171.1Skamil
46181.1Skamil		/* Resume tracee with PT_CONTINUE */
46191.1Skamil		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
46201.1Skamil
46211.1Skamil		/* Inform parent that tracer has attached to tracee */
46221.1Skamil		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
46231.1Skamil		/* Wait for parent */
46241.1Skamil		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
46251.1Skamil
46261.1Skamil		/* Wait for tracee and assert that it exited */
46271.1Skamil		FORKEE_REQUIRE_SUCCESS(
46281.1Skamil		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
46291.1Skamil
46301.1Skamil		forkee_status_exited(status, exitval_tracee);
46311.1Skamil
46321.13Schristos		DPRINTF("Before exiting of the tracer process\n");
46331.1Skamil		_exit(exitval_tracer);
46341.1Skamil	}
46351.1Skamil
46361.13Schristos	DPRINTF("Wait for the tracer to attach to the tracee\n");
46371.1Skamil	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
46381.1Skamil
46391.13Schristos	DPRINTF("Resume the tracee and let it exit\n");
46401.1Skamil	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
46411.1Skamil
46421.13Schristos	DPRINTF("Detect that tracee is zombie\n");
46431.1Skamil	await_zombie(tracee);
46441.1Skamil
46451.13Schristos	DPRINTF("Assert that there is no status about tracee - "
46461.1Skamil	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
46471.1Skamil	TWAIT_REQUIRE_SUCCESS(
46481.1Skamil	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
46491.1Skamil
46501.13Schristos	DPRINTF("Resume the tracer and let it detect exited tracee\n");
46511.1Skamil	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
46521.1Skamil
46531.13Schristos	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
46541.1Skamil	    TWAIT_FNAME);
46551.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
46561.1Skamil	    tracer);
46571.1Skamil
46581.1Skamil	validate_status_exited(status, exitval_tracer);
46591.1Skamil
46601.13Schristos	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
46611.1Skamil	    TWAIT_FNAME);
46621.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
46631.1Skamil	    tracee);
46641.1Skamil
46651.1Skamil	validate_status_exited(status, exitval_tracee);
46661.1Skamil
46671.1Skamil	msg_close(&parent_tracer);
46681.1Skamil	msg_close(&parent_tracee);
46691.1Skamil}
46701.1Skamil#endif
46711.1Skamil
46721.1SkamilATF_TC(siginfo1);
46731.1SkamilATF_TC_HEAD(siginfo1, tc)
46741.1Skamil{
46751.1Skamil	atf_tc_set_md_var(tc, "descr",
46761.1Skamil	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
46771.1Skamil}
46781.1Skamil
46791.1SkamilATF_TC_BODY(siginfo1, tc)
46801.1Skamil{
46811.1Skamil	const int exitval = 5;
46821.1Skamil	const int sigval = SIGTRAP;
46831.1Skamil	pid_t child, wpid;
46841.1Skamil#if defined(TWAIT_HAVE_STATUS)
46851.1Skamil	int status;
46861.1Skamil#endif
46871.1Skamil	struct ptrace_siginfo info;
46881.1Skamil	memset(&info, 0, sizeof(info));
46891.1Skamil
46901.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
46911.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
46921.1Skamil	if (child == 0) {
46931.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
46941.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
46951.1Skamil
46961.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
46971.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
46981.1Skamil
46991.13Schristos		DPRINTF("Before exiting of the child process\n");
47001.1Skamil		_exit(exitval);
47011.1Skamil	}
47021.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47031.1Skamil
47041.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47051.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47061.1Skamil
47071.1Skamil	validate_status_stopped(status, sigval);
47081.1Skamil
47091.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47101.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47111.1Skamil
47121.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47131.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47141.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47151.1Skamil	    info.psi_siginfo.si_errno);
47161.1Skamil
47171.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47181.1Skamil	    "without signal to be sent\n");
47191.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
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_exited(status, exitval);
47251.1Skamil
47261.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47271.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
47281.1Skamil}
47291.1Skamil
47301.1SkamilATF_TC(siginfo2);
47311.1SkamilATF_TC_HEAD(siginfo2, tc)
47321.1Skamil{
47331.1Skamil	atf_tc_set_md_var(tc, "descr",
47341.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
47351.1Skamil	    "modification of SIGINT from tracee");
47361.1Skamil}
47371.1Skamil
47381.1Skamilstatic int siginfo2_caught = 0;
47391.1Skamil
47401.1Skamilstatic void
47411.1Skamilsiginfo2_sighandler(int sig)
47421.1Skamil{
47431.1Skamil	FORKEE_ASSERT_EQ(sig, SIGINT);
47441.1Skamil
47451.1Skamil	++siginfo2_caught;
47461.1Skamil}
47471.1Skamil
47481.1SkamilATF_TC_BODY(siginfo2, tc)
47491.1Skamil{
47501.1Skamil	const int exitval = 5;
47511.1Skamil	const int sigval = SIGINT;
47521.1Skamil	pid_t child, wpid;
47531.1Skamil	struct sigaction sa;
47541.1Skamil#if defined(TWAIT_HAVE_STATUS)
47551.1Skamil	int status;
47561.1Skamil#endif
47571.1Skamil	struct ptrace_siginfo info;
47581.1Skamil	memset(&info, 0, sizeof(info));
47591.1Skamil
47601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
47611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
47621.1Skamil	if (child == 0) {
47631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
47641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
47651.1Skamil
47661.1Skamil		sa.sa_handler = siginfo2_sighandler;
47671.1Skamil		sa.sa_flags = SA_SIGINFO;
47681.1Skamil		sigemptyset(&sa.sa_mask);
47691.1Skamil
47701.1Skamil		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
47711.1Skamil
47721.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
47731.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
47741.1Skamil
47751.1Skamil		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
47761.1Skamil
47771.13Schristos		DPRINTF("Before exiting of the child process\n");
47781.1Skamil		_exit(exitval);
47791.1Skamil	}
47801.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
47811.1Skamil
47821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
47831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
47841.1Skamil
47851.1Skamil	validate_status_stopped(status, sigval);
47861.1Skamil
47871.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
47881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
47891.1Skamil
47901.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
47911.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
47921.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
47931.1Skamil	    info.psi_siginfo.si_errno);
47941.1Skamil
47951.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
47961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
47971.1Skamil
47981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
47991.1Skamil	    "without signal to be sent\n");
48001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
48011.1Skamil
48021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48041.1Skamil
48051.1Skamil	validate_status_exited(status, exitval);
48061.1Skamil
48071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
48091.1Skamil}
48101.1Skamil
48111.1SkamilATF_TC(siginfo3);
48121.1SkamilATF_TC_HEAD(siginfo3, tc)
48131.1Skamil{
48141.1Skamil	atf_tc_set_md_var(tc, "descr",
48151.1Skamil	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
48161.1Skamil	    "setting signal to new value");
48171.1Skamil}
48181.1Skamil
48191.1Skamilstatic int siginfo3_caught = 0;
48201.1Skamil
48211.1Skamilstatic void
48221.1Skamilsiginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
48231.1Skamil{
48241.1Skamil	FORKEE_ASSERT_EQ(sig, SIGTRAP);
48251.1Skamil
48261.1Skamil	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
48271.1Skamil	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
48281.1Skamil
48291.1Skamil	++siginfo3_caught;
48301.1Skamil}
48311.1Skamil
48321.1SkamilATF_TC_BODY(siginfo3, tc)
48331.1Skamil{
48341.1Skamil	const int exitval = 5;
48351.1Skamil	const int sigval = SIGINT;
48361.1Skamil	const int sigfaked = SIGTRAP;
48371.1Skamil	const int sicodefaked = TRAP_BRKPT;
48381.1Skamil	pid_t child, wpid;
48391.1Skamil	struct sigaction sa;
48401.1Skamil#if defined(TWAIT_HAVE_STATUS)
48411.1Skamil	int status;
48421.1Skamil#endif
48431.1Skamil	struct ptrace_siginfo info;
48441.1Skamil	memset(&info, 0, sizeof(info));
48451.1Skamil
48461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
48471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
48481.1Skamil	if (child == 0) {
48491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
48501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
48511.1Skamil
48521.1Skamil		sa.sa_sigaction = siginfo3_sigaction;
48531.1Skamil		sa.sa_flags = SA_SIGINFO;
48541.1Skamil		sigemptyset(&sa.sa_mask);
48551.1Skamil
48561.1Skamil		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
48571.1Skamil
48581.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
48591.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
48601.1Skamil
48611.1Skamil		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
48621.1Skamil
48631.13Schristos		DPRINTF("Before exiting of the child process\n");
48641.1Skamil		_exit(exitval);
48651.1Skamil	}
48661.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
48671.1Skamil
48681.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
48691.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
48701.1Skamil
48711.1Skamil	validate_status_stopped(status, sigval);
48721.1Skamil
48731.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48741.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48751.1Skamil
48761.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
48771.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
48781.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
48791.1Skamil	    info.psi_siginfo.si_errno);
48801.1Skamil
48811.13Schristos	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
48821.1Skamil	    sigfaked, sicodefaked);
48831.1Skamil	info.psi_siginfo.si_signo = sigfaked;
48841.1Skamil	info.psi_siginfo.si_code = sicodefaked;
48851.1Skamil
48861.13Schristos	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
48871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
48881.1Skamil
48891.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
48901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
48911.1Skamil
48921.13Schristos	DPRINTF("Before checking siginfo_t\n");
48931.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
48941.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
48951.1Skamil
48961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
48971.1Skamil	    "without signal to be sent\n");
48981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
48991.1Skamil
49001.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49011.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49021.1Skamil
49031.1Skamil	validate_status_exited(status, exitval);
49041.1Skamil
49051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49061.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49071.1Skamil}
49081.1Skamil
49091.1SkamilATF_TC(siginfo4);
49101.1SkamilATF_TC_HEAD(siginfo4, tc)
49111.1Skamil{
49121.1Skamil	atf_tc_set_md_var(tc, "descr",
49131.1Skamil	    "Detect SIGTRAP TRAP_EXEC from tracee");
49141.1Skamil}
49151.1Skamil
49161.1SkamilATF_TC_BODY(siginfo4, tc)
49171.1Skamil{
49181.1Skamil	const int sigval = SIGTRAP;
49191.1Skamil	pid_t child, wpid;
49201.1Skamil#if defined(TWAIT_HAVE_STATUS)
49211.1Skamil	int status;
49221.1Skamil#endif
49231.1Skamil
49241.1Skamil	struct ptrace_siginfo info;
49251.1Skamil	memset(&info, 0, sizeof(info));
49261.1Skamil
49271.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49281.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49291.1Skamil	if (child == 0) {
49301.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49311.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49321.1Skamil
49331.13Schristos		DPRINTF("Before calling execve(2) from child\n");
49341.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
49351.1Skamil
49361.1Skamil		FORKEE_ASSERT(0 && "Not reached");
49371.1Skamil	}
49381.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
49391.1Skamil
49401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49421.1Skamil
49431.1Skamil	validate_status_stopped(status, sigval);
49441.1Skamil
49451.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
49461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
49471.1Skamil
49481.13Schristos	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
49491.13Schristos	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
49501.1Skamil	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
49511.1Skamil	    info.psi_siginfo.si_errno);
49521.1Skamil
49531.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
49541.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
49551.1Skamil
49561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
49571.1Skamil	    "without signal to be sent\n");
49581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
49591.1Skamil
49601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
49621.1Skamil
49631.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
49641.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
49651.1Skamil}
49661.1Skamil
49671.1Skamil#if defined(TWAIT_HAVE_PID)
49681.1SkamilATF_TC(siginfo5);
49691.1SkamilATF_TC_HEAD(siginfo5, tc)
49701.1Skamil{
49711.1Skamil	atf_tc_set_md_var(tc, "descr",
49721.1Skamil	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
49731.1Skamil	    "set to PTRACE_FORK and reports correct signal information");
49741.1Skamil}
49751.1Skamil
49761.1SkamilATF_TC_BODY(siginfo5, tc)
49771.1Skamil{
49781.1Skamil	const int exitval = 5;
49791.1Skamil	const int exitval2 = 15;
49801.1Skamil	const int sigval = SIGSTOP;
49811.1Skamil	pid_t child, child2, wpid;
49821.1Skamil#if defined(TWAIT_HAVE_STATUS)
49831.1Skamil	int status;
49841.1Skamil#endif
49851.1Skamil	ptrace_state_t state;
49861.1Skamil	const int slen = sizeof(state);
49871.1Skamil	ptrace_event_t event;
49881.1Skamil	const int elen = sizeof(event);
49891.1Skamil	struct ptrace_siginfo info;
49901.1Skamil
49911.1Skamil	memset(&info, 0, sizeof(info));
49921.1Skamil
49931.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
49941.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
49951.1Skamil	if (child == 0) {
49961.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
49971.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
49981.1Skamil
49991.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
50001.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
50011.1Skamil
50021.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
50031.1Skamil
50041.1Skamil		if (child2 == 0)
50051.1Skamil			_exit(exitval2);
50061.1Skamil
50071.1Skamil		FORKEE_REQUIRE_SUCCESS
50081.1Skamil		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
50091.1Skamil
50101.1Skamil		forkee_status_exited(status, exitval2);
50111.1Skamil
50121.13Schristos		DPRINTF("Before exiting of the child process\n");
50131.1Skamil		_exit(exitval);
50141.1Skamil	}
50151.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
50161.1Skamil
50171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
50181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50191.1Skamil
50201.1Skamil	validate_status_stopped(status, sigval);
50211.1Skamil
50221.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50231.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50241.1Skamil
50251.13Schristos	DPRINTF("Before checking siginfo_t\n");
50261.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
50271.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
50281.1Skamil
50291.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
50301.1Skamil	event.pe_set_event = PTRACE_FORK;
50311.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
50321.1Skamil
50331.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50341.1Skamil	    "without signal to be sent\n");
50351.13Schristos        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
50361.1Skamil               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
50371.1Skamil               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
50381.1Skamil                "state.pe_other_pid=child)\n", child);
50391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50401.1Skamil
50411.13Schristos	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
50421.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
50431.1Skamil
50441.1Skamil	validate_status_stopped(status, SIGTRAP);
50451.1Skamil
50461.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50471.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50481.1Skamil
50491.13Schristos	DPRINTF("Before checking siginfo_t\n");
50501.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
50511.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
50521.1Skamil
50531.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
50541.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
50551.1Skamil
50561.1Skamil	child2 = state.pe_other_pid;
50571.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
50581.1Skamil
50591.13Schristos	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
50601.1Skamil	    TWAIT_FNAME, child2, child);
50611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
50621.1Skamil	    child2);
50631.1Skamil
50641.1Skamil	validate_status_stopped(status, SIGTRAP);
50651.1Skamil
50661.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
50671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
50681.1Skamil
50691.13Schristos	DPRINTF("Before checking siginfo_t\n");
50701.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
50711.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
50721.1Skamil
50731.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
50741.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
50751.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
50761.1Skamil
50771.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
50781.1Skamil	    "without signal to be sent\n");
50791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
50801.1Skamil
50811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
50821.1Skamil	    "without signal to be sent\n");
50831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
50841.1Skamil
50851.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
50861.1Skamil	    TWAIT_FNAME);
50871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
50881.1Skamil	    child2);
50891.1Skamil
50901.1Skamil	validate_status_exited(status, exitval2);
50911.1Skamil
50921.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
50931.1Skamil	    TWAIT_FNAME);
50941.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
50951.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
50961.1Skamil
50971.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
50981.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
50991.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51001.1Skamil
51011.1Skamil	validate_status_stopped(status, SIGCHLD);
51021.1Skamil
51031.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51051.1Skamil
51061.13Schristos	DPRINTF("Before checking siginfo_t\n");
51071.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
51081.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
51091.1Skamil
51101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51111.1Skamil	    "without signal to be sent\n");
51121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
51131.1Skamil
51141.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
51151.1Skamil	    TWAIT_FNAME);
51161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51171.1Skamil
51181.1Skamil	validate_status_exited(status, exitval);
51191.1Skamil
51201.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
51211.1Skamil	    TWAIT_FNAME);
51221.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
51231.1Skamil}
51241.1Skamil#endif
51251.1Skamil
51261.1Skamil#if defined(PT_STEP)
51271.1SkamilATF_TC(siginfo6);
51281.1SkamilATF_TC_HEAD(siginfo6, tc)
51291.1Skamil{
51301.1Skamil	atf_tc_set_md_var(tc, "descr",
51311.1Skamil	    "Verify single PT_STEP call with signal information check");
51321.1Skamil}
51331.1Skamil
51341.1SkamilATF_TC_BODY(siginfo6, tc)
51351.1Skamil{
51361.1Skamil	const int exitval = 5;
51371.1Skamil	const int sigval = SIGSTOP;
51381.1Skamil	pid_t child, wpid;
51391.1Skamil#if defined(TWAIT_HAVE_STATUS)
51401.1Skamil	int status;
51411.1Skamil#endif
51421.1Skamil	int happy;
51431.1Skamil	struct ptrace_siginfo info;
51441.1Skamil
51451.1Skamil#if defined(__arm__)
51461.1Skamil	/* PT_STEP not supported on arm 32-bit */
51471.1Skamil	atf_tc_expect_fail("PR kern/52119");
51481.1Skamil#endif
51491.1Skamil
51501.1Skamil	memset(&info, 0, sizeof(info));
51511.1Skamil
51521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
51531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
51541.1Skamil	if (child == 0) {
51551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
51561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
51571.1Skamil
51581.1Skamil		happy = check_happy(100);
51591.1Skamil
51601.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
51611.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
51621.1Skamil
51631.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
51641.1Skamil
51651.13Schristos		DPRINTF("Before exiting of the child process\n");
51661.1Skamil		_exit(exitval);
51671.1Skamil	}
51681.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
51691.1Skamil
51701.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51721.1Skamil
51731.1Skamil	validate_status_stopped(status, sigval);
51741.1Skamil
51751.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51771.1Skamil
51781.13Schristos	DPRINTF("Before checking siginfo_t\n");
51791.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
51801.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
51811.1Skamil
51821.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51831.1Skamil	    "without signal to be sent (use PT_STEP)\n");
51841.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
51851.1Skamil
51861.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
51871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
51881.1Skamil
51891.1Skamil	validate_status_stopped(status, SIGTRAP);
51901.1Skamil
51911.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
51921.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
51931.1Skamil
51941.13Schristos	DPRINTF("Before checking siginfo_t\n");
51951.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
51961.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
51971.1Skamil
51981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
51991.1Skamil	    "without signal to be sent\n");
52001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52011.1Skamil
52021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52041.1Skamil
52051.1Skamil	validate_status_exited(status, exitval);
52061.1Skamil
52071.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52081.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
52091.1Skamil}
52101.1Skamil#endif
52111.1Skamil
52121.1Skamilvolatile lwpid_t the_lwp_id = 0;
52131.1Skamil
52141.1Skamilstatic void
52151.1Skamillwp_main_func(void *arg)
52161.1Skamil{
52171.1Skamil	the_lwp_id = _lwp_self();
52181.1Skamil	_lwp_exit();
52191.1Skamil}
52201.1Skamil
52211.1SkamilATF_TC(lwp_create1);
52221.1SkamilATF_TC_HEAD(lwp_create1, tc)
52231.1Skamil{
52241.1Skamil	atf_tc_set_md_var(tc, "descr",
52251.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
52261.1Skamil	    "EVENT_MASK set to PTRACE_LWP_CREATE");
52271.1Skamil}
52281.1Skamil
52291.1SkamilATF_TC_BODY(lwp_create1, tc)
52301.1Skamil{
52311.1Skamil	const int exitval = 5;
52321.1Skamil	const int sigval = SIGSTOP;
52331.1Skamil	pid_t child, wpid;
52341.1Skamil#if defined(TWAIT_HAVE_STATUS)
52351.1Skamil	int status;
52361.1Skamil#endif
52371.1Skamil	ptrace_state_t state;
52381.1Skamil	const int slen = sizeof(state);
52391.1Skamil	ptrace_event_t event;
52401.1Skamil	const int elen = sizeof(event);
52411.1Skamil	ucontext_t uc;
52421.1Skamil	lwpid_t lid;
52431.1Skamil	static const size_t ssize = 16*1024;
52441.1Skamil	void *stack;
52451.1Skamil
52461.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
52471.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
52481.1Skamil	if (child == 0) {
52491.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
52501.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
52511.1Skamil
52521.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
52531.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
52541.1Skamil
52551.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
52561.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
52571.1Skamil
52581.13Schristos		DPRINTF("Before making context for new lwp in child\n");
52591.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
52601.1Skamil
52611.13Schristos		DPRINTF("Before creating new in child\n");
52621.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
52631.1Skamil
52641.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
52651.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
52661.1Skamil
52671.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
52681.1Skamil		    "are the same\n", lid, the_lwp_id);
52691.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
52701.1Skamil
52711.13Schristos		DPRINTF("Before exiting of the child process\n");
52721.1Skamil		_exit(exitval);
52731.1Skamil	}
52741.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
52751.1Skamil
52761.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
52771.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52781.1Skamil
52791.1Skamil	validate_status_stopped(status, sigval);
52801.1Skamil
52811.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
52821.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
52831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
52841.1Skamil
52851.13Schristos	DPRINTF("Before resuming the child process where it left off and "
52861.1Skamil	    "without signal to be sent\n");
52871.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
52881.1Skamil
52891.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
52901.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
52911.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
52921.1Skamil
52931.1Skamil	validate_status_stopped(status, SIGTRAP);
52941.1Skamil
52951.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
52961.1Skamil
52971.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
52981.1Skamil
52991.1Skamil	lid = state.pe_lwp;
53001.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
53011.1Skamil
53021.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53031.1Skamil	    "without signal to be sent\n");
53041.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53051.1Skamil
53061.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
53071.1Skamil	    TWAIT_FNAME);
53081.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53091.1Skamil
53101.1Skamil	validate_status_exited(status, exitval);
53111.1Skamil
53121.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
53131.1Skamil	    TWAIT_FNAME);
53141.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
53151.1Skamil}
53161.1Skamil
53171.1SkamilATF_TC(lwp_exit1);
53181.1SkamilATF_TC_HEAD(lwp_exit1, tc)
53191.1Skamil{
53201.1Skamil	atf_tc_set_md_var(tc, "descr",
53211.1Skamil	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
53221.1Skamil	    "EVENT_MASK set to PTRACE_LWP_EXIT");
53231.1Skamil}
53241.1Skamil
53251.1SkamilATF_TC_BODY(lwp_exit1, tc)
53261.1Skamil{
53271.1Skamil	const int exitval = 5;
53281.1Skamil	const int sigval = SIGSTOP;
53291.1Skamil	pid_t child, wpid;
53301.1Skamil#if defined(TWAIT_HAVE_STATUS)
53311.1Skamil	int status;
53321.1Skamil#endif
53331.1Skamil	ptrace_state_t state;
53341.1Skamil	const int slen = sizeof(state);
53351.1Skamil	ptrace_event_t event;
53361.1Skamil	const int elen = sizeof(event);
53371.1Skamil	ucontext_t uc;
53381.1Skamil	lwpid_t lid;
53391.1Skamil	static const size_t ssize = 16*1024;
53401.1Skamil	void *stack;
53411.1Skamil
53421.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
53431.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
53441.1Skamil	if (child == 0) {
53451.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
53461.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
53471.1Skamil
53481.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
53491.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
53501.1Skamil
53511.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
53521.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
53531.1Skamil
53541.13Schristos		DPRINTF("Before making context for new lwp in child\n");
53551.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
53561.1Skamil
53571.13Schristos		DPRINTF("Before creating new in child\n");
53581.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
53591.1Skamil
53601.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
53611.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
53621.1Skamil
53631.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
53641.1Skamil		    "are the same\n", lid, the_lwp_id);
53651.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
53661.1Skamil
53671.13Schristos		DPRINTF("Before exiting of the child process\n");
53681.1Skamil		_exit(exitval);
53691.1Skamil	}
53701.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
53711.1Skamil
53721.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
53731.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53741.1Skamil
53751.1Skamil	validate_status_stopped(status, sigval);
53761.1Skamil
53771.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
53781.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
53791.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
53801.1Skamil
53811.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53821.1Skamil	    "without signal to be sent\n");
53831.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
53841.1Skamil
53851.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
53861.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
53871.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
53881.1Skamil
53891.1Skamil	validate_status_stopped(status, SIGTRAP);
53901.1Skamil
53911.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
53921.1Skamil
53931.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
53941.1Skamil
53951.1Skamil	lid = state.pe_lwp;
53961.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
53971.1Skamil
53981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
53991.1Skamil	    "without signal to be sent\n");
54001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54011.1Skamil
54021.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
54031.1Skamil	    TWAIT_FNAME);
54041.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54051.1Skamil
54061.1Skamil	validate_status_exited(status, exitval);
54071.1Skamil
54081.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
54091.1Skamil	    TWAIT_FNAME);
54101.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54111.1Skamil}
54121.1Skamil
54131.1SkamilATF_TC(signal1);
54141.1SkamilATF_TC_HEAD(signal1, tc)
54151.1Skamil{
54161.1Skamil	atf_tc_set_md_var(tc, "descr",
54171.1Skamil	    "Verify that masking single unrelated signal does not stop tracer "
54181.1Skamil	    "from catching other signals");
54191.1Skamil}
54201.1Skamil
54211.1SkamilATF_TC_BODY(signal1, tc)
54221.1Skamil{
54231.1Skamil	const int exitval = 5;
54241.1Skamil	const int sigval = SIGSTOP;
54251.1Skamil	const int sigmasked = SIGTRAP;
54261.1Skamil	const int signotmasked = SIGINT;
54271.1Skamil	pid_t child, wpid;
54281.1Skamil#if defined(TWAIT_HAVE_STATUS)
54291.1Skamil	int status;
54301.1Skamil#endif
54311.1Skamil	sigset_t intmask;
54321.1Skamil
54331.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
54341.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
54351.1Skamil	if (child == 0) {
54361.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
54371.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
54381.1Skamil
54391.1Skamil		sigemptyset(&intmask);
54401.1Skamil		sigaddset(&intmask, sigmasked);
54411.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
54421.1Skamil
54431.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
54441.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
54451.1Skamil
54461.13Schristos		DPRINTF("Before raising %s from child\n",
54471.1Skamil		    strsignal(signotmasked));
54481.1Skamil		FORKEE_ASSERT(raise(signotmasked) == 0);
54491.1Skamil
54501.13Schristos		DPRINTF("Before exiting of the child process\n");
54511.1Skamil		_exit(exitval);
54521.1Skamil	}
54531.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
54541.1Skamil
54551.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54561.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54571.1Skamil
54581.1Skamil	validate_status_stopped(status, sigval);
54591.1Skamil
54601.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54611.1Skamil	    "without signal to be sent\n");
54621.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54631.1Skamil
54641.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54651.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54661.1Skamil
54671.1Skamil	validate_status_stopped(status, signotmasked);
54681.1Skamil
54691.13Schristos	DPRINTF("Before resuming the child process where it left off and "
54701.1Skamil	    "without signal to be sent\n");
54711.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
54721.1Skamil
54731.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54741.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
54751.1Skamil
54761.1Skamil	validate_status_exited(status, exitval);
54771.1Skamil
54781.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
54791.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
54801.1Skamil}
54811.1Skamil
54821.1SkamilATF_TC(signal2);
54831.1SkamilATF_TC_HEAD(signal2, tc)
54841.1Skamil{
54851.1Skamil	atf_tc_set_md_var(tc, "descr",
54861.1Skamil	    "Verify that masking SIGTRAP in tracee stops tracer from "
54871.1Skamil	    "catching this raised signal");
54881.1Skamil}
54891.1Skamil
54901.1SkamilATF_TC_BODY(signal2, tc)
54911.1Skamil{
54921.1Skamil	const int exitval = 5;
54931.1Skamil	const int sigval = SIGSTOP;
54941.1Skamil	const int sigmasked = SIGTRAP;
54951.1Skamil	pid_t child, wpid;
54961.1Skamil#if defined(TWAIT_HAVE_STATUS)
54971.1Skamil	int status;
54981.1Skamil#endif
54991.1Skamil	sigset_t intmask;
55001.1Skamil
55011.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55021.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55031.1Skamil	if (child == 0) {
55041.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55051.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55061.1Skamil
55071.1Skamil		sigemptyset(&intmask);
55081.1Skamil		sigaddset(&intmask, sigmasked);
55091.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55101.1Skamil
55111.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55121.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55131.1Skamil
55141.13Schristos		DPRINTF("Before raising %s breakpoint from child\n",
55151.1Skamil		    strsignal(sigmasked));
55161.1Skamil		FORKEE_ASSERT(raise(sigmasked) == 0);
55171.1Skamil
55181.13Schristos		DPRINTF("Before exiting of the child process\n");
55191.1Skamil		_exit(exitval);
55201.1Skamil	}
55211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55221.1Skamil
55231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55251.1Skamil
55261.1Skamil	validate_status_stopped(status, sigval);
55271.1Skamil
55281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
55291.1Skamil	    "without signal to be sent\n");
55301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
55311.1Skamil
55321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
55341.1Skamil
55351.1Skamil	validate_status_exited(status, exitval);
55361.1Skamil
55371.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
55381.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
55391.1Skamil}
55401.1Skamil
55411.1SkamilATF_TC(signal3);
55421.1SkamilATF_TC_HEAD(signal3, tc)
55431.1Skamil{
55441.7Skamil	atf_tc_set_md_var(tc, "timeout", "5");
55451.1Skamil	atf_tc_set_md_var(tc, "descr",
55461.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
55471.1Skamil	    "catching software breakpoints");
55481.1Skamil}
55491.1Skamil
55501.1SkamilATF_TC_BODY(signal3, tc)
55511.1Skamil{
55521.1Skamil	const int exitval = 5;
55531.1Skamil	const int sigval = SIGSTOP;
55541.1Skamil	const int sigmasked = SIGTRAP;
55551.1Skamil	pid_t child, wpid;
55561.1Skamil#if defined(TWAIT_HAVE_STATUS)
55571.1Skamil	int status;
55581.1Skamil#endif
55591.1Skamil	sigset_t intmask;
55601.1Skamil
55611.20Skamil	atf_tc_expect_fail("PR kern/51918");
55621.20Skamil
55631.20Skamil	// This test breaks now on some ports, temporarily disable it
55641.20Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
55651.20Skamil
55661.10Smartin#if defined(__sparc__)
55671.7Skamil	atf_tc_expect_timeout("PR kern/52167");
55681.7Skamil
55691.7Skamil	// timeout wins, failure still valid
55701.7Skamil	// atf_tc_expect_fail("PR kern/51918");
55711.7Skamil#endif
55721.1Skamil
55731.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
55741.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
55751.1Skamil	if (child == 0) {
55761.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
55771.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
55781.1Skamil
55791.1Skamil		sigemptyset(&intmask);
55801.1Skamil		sigaddset(&intmask, sigmasked);
55811.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
55821.1Skamil
55831.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
55841.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
55851.1Skamil
55861.13Schristos		DPRINTF("Before raising software breakpoint from child\n");
55871.4Skamil
55881.4Skamil#ifdef PTRACE_BREAKPOINT_ASM
55891.4Skamil		PTRACE_BREAKPOINT_ASM;
55901.1Skamil#else
55911.4Skamil		/* port me */
55921.1Skamil#endif
55931.1Skamil
55941.13Schristos		DPRINTF("Before exiting of the child process\n");
55951.1Skamil		_exit(exitval);
55961.1Skamil	}
55971.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
55981.1Skamil
55991.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56001.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56011.1Skamil
56021.1Skamil	validate_status_stopped(status, sigval);
56031.1Skamil
56041.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56051.1Skamil	    "without signal to be sent\n");
56061.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56071.1Skamil
56081.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56091.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56101.1Skamil
56111.1Skamil	validate_status_stopped(status, sigmasked);
56121.1Skamil
56131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56141.1Skamil	    "without signal to be sent\n");
56151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56161.1Skamil
56171.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56181.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56191.1Skamil
56201.1Skamil	validate_status_exited(status, exitval);
56211.1Skamil
56221.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56231.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56241.1Skamil}
56251.1Skamil
56261.1Skamil#if defined(PT_STEP)
56271.1SkamilATF_TC(signal4);
56281.1SkamilATF_TC_HEAD(signal4, tc)
56291.1Skamil{
56301.1Skamil	atf_tc_set_md_var(tc, "descr",
56311.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
56321.1Skamil	    "catching single step trap");
56331.1Skamil}
56341.1Skamil
56351.1SkamilATF_TC_BODY(signal4, tc)
56361.1Skamil{
56371.1Skamil	const int exitval = 5;
56381.1Skamil	const int sigval = SIGSTOP;
56391.1Skamil	const int sigmasked = SIGTRAP;
56401.1Skamil	pid_t child, wpid;
56411.1Skamil#if defined(TWAIT_HAVE_STATUS)
56421.1Skamil	int status;
56431.1Skamil#endif
56441.1Skamil	sigset_t intmask;
56451.1Skamil	int happy;
56461.1Skamil
56471.1Skamil#if defined(__arm__)
56481.5Skamil	/* PT_STEP not supported on arm 32-bit */
56491.5Skamil	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
56501.1Skamil#endif
56511.1Skamil
56521.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
56531.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
56541.1Skamil	if (child == 0) {
56551.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
56561.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
56571.1Skamil
56581.1Skamil		happy = check_happy(100);
56591.1Skamil
56601.1Skamil		sigemptyset(&intmask);
56611.1Skamil		sigaddset(&intmask, sigmasked);
56621.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
56631.1Skamil
56641.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
56651.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
56661.1Skamil
56671.1Skamil		FORKEE_ASSERT_EQ(happy, check_happy(100));
56681.1Skamil
56691.13Schristos		DPRINTF("Before exiting of the child process\n");
56701.1Skamil		_exit(exitval);
56711.1Skamil	}
56721.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
56731.1Skamil
56741.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56751.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56761.1Skamil
56771.1Skamil	validate_status_stopped(status, sigval);
56781.1Skamil
56791.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56801.1Skamil	    "without signal to be sent\n");
56811.13Schristos	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
56821.1Skamil
56831.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56841.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56851.1Skamil
56861.1Skamil	validate_status_stopped(status, sigmasked);
56871.1Skamil
56881.13Schristos	DPRINTF("Before resuming the child process where it left off and "
56891.1Skamil	    "without signal to be sent\n");
56901.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
56911.1Skamil
56921.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56931.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
56941.1Skamil
56951.1Skamil	validate_status_exited(status, exitval);
56961.1Skamil
56971.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
56981.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
56991.1Skamil}
57001.1Skamil#endif
57011.1Skamil
57021.1SkamilATF_TC(signal5);
57031.1SkamilATF_TC_HEAD(signal5, tc)
57041.1Skamil{
57051.1Skamil	atf_tc_set_md_var(tc, "descr",
57061.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57071.1Skamil	    "catching exec() breakpoint");
57081.1Skamil}
57091.1Skamil
57101.1SkamilATF_TC_BODY(signal5, tc)
57111.1Skamil{
57121.1Skamil	const int exitval = 5;
57131.1Skamil	const int sigval = SIGSTOP;
57141.1Skamil	const int sigmasked = SIGTRAP;
57151.1Skamil	pid_t child, wpid;
57161.1Skamil#if defined(TWAIT_HAVE_STATUS)
57171.1Skamil	int status;
57181.1Skamil#endif
57191.1Skamil	sigset_t intmask;
57201.1Skamil
57211.14Schristos	atf_tc_expect_fail("wrong signal");
57221.14Schristos
57231.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
57241.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
57251.1Skamil	if (child == 0) {
57261.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
57271.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
57281.1Skamil
57291.1Skamil		sigemptyset(&intmask);
57301.1Skamil		sigaddset(&intmask, sigmasked);
57311.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
57321.1Skamil
57331.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
57341.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
57351.1Skamil
57361.13Schristos		DPRINTF("Before calling execve(2) from child\n");
57371.1Skamil		execlp("/bin/echo", "/bin/echo", NULL);
57381.1Skamil
57391.13Schristos		DPRINTF("Before exiting of the child process\n");
57401.1Skamil		_exit(exitval);
57411.1Skamil	}
57421.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
57431.1Skamil
57441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57461.1Skamil
57471.1Skamil	validate_status_stopped(status, sigval);
57481.1Skamil
57491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57501.1Skamil	    "without signal to be sent\n");
57511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57521.1Skamil
57531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57551.1Skamil
57561.1Skamil	validate_status_stopped(status, sigmasked);
57571.1Skamil
57581.13Schristos	DPRINTF("Before resuming the child process where it left off and "
57591.1Skamil	    "without signal to be sent\n");
57601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
57611.1Skamil
57621.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57631.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
57641.1Skamil
57651.1Skamil	validate_status_exited(status, exitval);
57661.1Skamil
57671.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
57681.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
57691.1Skamil}
57701.1Skamil
57711.1Skamil#if defined(TWAIT_HAVE_PID)
57721.1SkamilATF_TC(signal6);
57731.1SkamilATF_TC_HEAD(signal6, tc)
57741.1Skamil{
57751.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
57761.1Skamil	atf_tc_set_md_var(tc, "descr",
57771.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
57781.1Skamil	    "catching PTRACE_FORK breakpoint");
57791.1Skamil}
57801.1Skamil
57811.1SkamilATF_TC_BODY(signal6, tc)
57821.1Skamil{
57831.1Skamil	const int exitval = 5;
57841.1Skamil	const int exitval2 = 15;
57851.1Skamil	const int sigval = SIGSTOP;
57861.1Skamil	const int sigmasked = SIGTRAP;
57871.1Skamil	pid_t child, child2, wpid;
57881.1Skamil#if defined(TWAIT_HAVE_STATUS)
57891.1Skamil	int status;
57901.1Skamil#endif
57911.1Skamil	sigset_t intmask;
57921.1Skamil	ptrace_state_t state;
57931.1Skamil	const int slen = sizeof(state);
57941.1Skamil	ptrace_event_t event;
57951.1Skamil	const int elen = sizeof(event);
57961.1Skamil
57971.38Skamil	atf_tc_expect_fail("PR kern/51918");
57981.14Schristos
57991.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
58001.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
58011.1Skamil	if (child == 0) {
58021.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
58031.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
58041.1Skamil
58051.1Skamil		sigemptyset(&intmask);
58061.1Skamil		sigaddset(&intmask, sigmasked);
58071.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
58081.1Skamil
58091.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
58101.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
58111.1Skamil
58121.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
58131.1Skamil
58141.1Skamil		if (child2 == 0)
58151.1Skamil			_exit(exitval2);
58161.1Skamil
58171.1Skamil		FORKEE_REQUIRE_SUCCESS
58181.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
58191.1Skamil
58201.1Skamil		forkee_status_exited(status, exitval2);
58211.1Skamil
58221.13Schristos		DPRINTF("Before exiting of the child process\n");
58231.1Skamil		_exit(exitval);
58241.1Skamil	}
58251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
58261.1Skamil
58271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58291.1Skamil
58301.1Skamil	validate_status_stopped(status, sigval);
58311.1Skamil
58321.13Schristos	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
58331.1Skamil	event.pe_set_event = PTRACE_FORK;
58341.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
58351.1Skamil
58361.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58371.1Skamil	    "without signal to be sent\n");
58381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58391.1Skamil
58401.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
58411.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58421.1Skamil
58431.1Skamil	validate_status_stopped(status, sigmasked);
58441.1Skamil
58451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
58461.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
58471.1Skamil
58481.1Skamil	child2 = state.pe_other_pid;
58491.13Schristos	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
58501.1Skamil
58511.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
58521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58531.1Skamil	    child2);
58541.1Skamil
58551.1Skamil	validate_status_stopped(status, SIGTRAP);
58561.1Skamil
58571.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
58581.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
58591.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
58601.1Skamil
58611.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
58621.1Skamil	    "without signal to be sent\n");
58631.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
58641.1Skamil
58651.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58661.1Skamil	    "without signal to be sent\n");
58671.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58681.1Skamil
58691.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
58701.1Skamil	    TWAIT_FNAME);
58711.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
58721.1Skamil	    child2);
58731.1Skamil
58741.1Skamil	validate_status_exited(status, exitval2);
58751.1Skamil
58761.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
58771.1Skamil	    TWAIT_FNAME);
58781.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
58791.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
58801.1Skamil
58811.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
58821.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
58831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
58841.1Skamil
58851.1Skamil	validate_status_stopped(status, SIGCHLD);
58861.1Skamil
58871.13Schristos	DPRINTF("Before resuming the child process where it left off and "
58881.1Skamil	    "without signal to be sent\n");
58891.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
58901.1Skamil
58911.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
58921.1Skamil	    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 - expected no process\n",
58981.1Skamil	    TWAIT_FNAME);
58991.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
59001.1Skamil}
59011.1Skamil#endif
59021.1Skamil
59031.1Skamil#if defined(TWAIT_HAVE_PID)
59041.1SkamilATF_TC(signal7);
59051.1SkamilATF_TC_HEAD(signal7, tc)
59061.1Skamil{
59071.1Skamil	atf_tc_set_md_var(tc, "descr",
59081.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
59091.1Skamil	    "catching PTRACE_VFORK breakpoint");
59101.1Skamil}
59111.1Skamil
59121.1SkamilATF_TC_BODY(signal7, tc)
59131.1Skamil{
59141.1Skamil	const int exitval = 5;
59151.1Skamil	const int exitval2 = 15;
59161.1Skamil	const int sigval = SIGSTOP;
59171.1Skamil	const int sigmasked = SIGTRAP;
59181.1Skamil	pid_t child, child2, wpid;
59191.1Skamil#if defined(TWAIT_HAVE_STATUS)
59201.1Skamil	int status;
59211.1Skamil#endif
59221.1Skamil	sigset_t intmask;
59231.1Skamil	ptrace_state_t state;
59241.1Skamil	const int slen = sizeof(state);
59251.1Skamil	ptrace_event_t event;
59261.1Skamil	const int elen = sizeof(event);
59271.1Skamil
59281.38Skamil	atf_tc_expect_fail("PR kern/51918");
59291.14Schristos
59301.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
59311.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
59321.1Skamil	if (child == 0) {
59331.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
59341.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
59351.1Skamil
59361.1Skamil		sigemptyset(&intmask);
59371.1Skamil		sigaddset(&intmask, sigmasked);
59381.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
59391.1Skamil
59401.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
59411.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
59421.1Skamil
59431.1Skamil		FORKEE_ASSERT((child2 = fork()) != -1);
59441.1Skamil
59451.1Skamil		if (child2 == 0)
59461.1Skamil			_exit(exitval2);
59471.1Skamil
59481.1Skamil		FORKEE_REQUIRE_SUCCESS
59491.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
59501.1Skamil
59511.1Skamil		forkee_status_exited(status, exitval2);
59521.1Skamil
59531.13Schristos		DPRINTF("Before exiting of the child process\n");
59541.1Skamil		_exit(exitval);
59551.1Skamil	}
59561.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
59571.1Skamil
59581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59591.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59601.1Skamil
59611.1Skamil	validate_status_stopped(status, sigval);
59621.1Skamil
59631.13Schristos	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
59641.1Skamil	event.pe_set_event = PTRACE_VFORK;
59651.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
59661.1Skamil
59671.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59681.1Skamil	    "without signal to be sent\n");
59691.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59701.1Skamil
59711.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
59721.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
59731.1Skamil
59741.1Skamil	validate_status_stopped(status, sigmasked);
59751.1Skamil
59761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
59771.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
59781.1Skamil
59791.1Skamil	child2 = state.pe_other_pid;
59801.13Schristos	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
59811.1Skamil
59821.13Schristos	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
59831.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
59841.1Skamil	    child2);
59851.1Skamil
59861.1Skamil	validate_status_stopped(status, SIGTRAP);
59871.1Skamil
59881.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
59891.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
59901.1Skamil	ATF_REQUIRE_EQ(state.pe_other_pid, child);
59911.1Skamil
59921.13Schristos	DPRINTF("Before resuming the forkee process where it left off and "
59931.1Skamil	    "without signal to be sent\n");
59941.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
59951.1Skamil
59961.13Schristos	DPRINTF("Before resuming the child process where it left off and "
59971.1Skamil	    "without signal to be sent\n");
59981.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
59991.1Skamil
60001.13Schristos	DPRINTF("Before calling %s() for the forkee - expected exited\n",
60011.1Skamil	    TWAIT_FNAME);
60021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
60031.1Skamil	    child2);
60041.1Skamil
60051.1Skamil	validate_status_exited(status, exitval2);
60061.1Skamil
60071.13Schristos	DPRINTF("Before calling %s() for the forkee - expected no process\n",
60081.1Skamil	    TWAIT_FNAME);
60091.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD,
60101.1Skamil	    wpid = TWAIT_GENERIC(child2, &status, 0));
60111.1Skamil
60121.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
60131.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
60141.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60151.1Skamil
60161.1Skamil	validate_status_stopped(status, SIGCHLD);
60171.1Skamil
60181.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60191.1Skamil	    "without signal to be sent\n");
60201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
60211.1Skamil
60221.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
60231.1Skamil	    TWAIT_FNAME);
60241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60251.1Skamil
60261.1Skamil	validate_status_exited(status, exitval);
60271.1Skamil
60281.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
60291.1Skamil	    TWAIT_FNAME);
60301.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
60311.1Skamil}
60321.1Skamil#endif
60331.1Skamil
60341.1SkamilATF_TC(signal8);
60351.1SkamilATF_TC_HEAD(signal8, tc)
60361.1Skamil{
60371.1Skamil	atf_tc_set_md_var(tc, "descr",
60381.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
60391.1Skamil	    "catching PTRACE_VFORK_DONE breakpoint");
60401.1Skamil}
60411.1Skamil
60421.1SkamilATF_TC_BODY(signal8, tc)
60431.1Skamil{
60441.1Skamil	const int exitval = 5;
60451.1Skamil	const int exitval2 = 15;
60461.1Skamil	const int sigval = SIGSTOP;
60471.1Skamil	const int sigmasked = SIGTRAP;
60481.1Skamil	pid_t child, child2, wpid;
60491.1Skamil#if defined(TWAIT_HAVE_STATUS)
60501.1Skamil	int status;
60511.1Skamil#endif
60521.1Skamil	sigset_t intmask;
60531.1Skamil	ptrace_state_t state;
60541.1Skamil	const int slen = sizeof(state);
60551.1Skamil	ptrace_event_t event;
60561.1Skamil	const int elen = sizeof(event);
60571.1Skamil
60581.14Schristos	atf_tc_expect_fail("PR kern/51918");
60591.14Schristos
60601.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
60611.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
60621.1Skamil	if (child == 0) {
60631.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
60641.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
60651.1Skamil
60661.1Skamil		sigemptyset(&intmask);
60671.1Skamil		sigaddset(&intmask, sigmasked);
60681.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
60691.1Skamil
60701.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
60711.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
60721.1Skamil
60731.1Skamil		FORKEE_ASSERT((child2 = vfork()) != -1);
60741.1Skamil
60751.1Skamil		if (child2 == 0)
60761.1Skamil			_exit(exitval2);
60771.1Skamil
60781.1Skamil		FORKEE_REQUIRE_SUCCESS
60791.1Skamil			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
60801.1Skamil
60811.1Skamil		forkee_status_exited(status, exitval2);
60821.1Skamil
60831.13Schristos		DPRINTF("Before exiting of the child process\n");
60841.1Skamil		_exit(exitval);
60851.1Skamil	}
60861.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
60871.1Skamil
60881.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
60891.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
60901.1Skamil
60911.1Skamil	validate_status_stopped(status, sigval);
60921.1Skamil
60931.13Schristos	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
60941.1Skamil	    child);
60951.1Skamil	event.pe_set_event = PTRACE_VFORK_DONE;
60961.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
60971.1Skamil
60981.13Schristos	DPRINTF("Before resuming the child process where it left off and "
60991.1Skamil	    "without signal to be sent\n");
61001.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61011.1Skamil
61021.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
61031.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61041.1Skamil
61051.1Skamil	validate_status_stopped(status, sigmasked);
61061.1Skamil
61071.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
61081.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
61091.1Skamil
61101.1Skamil	child2 = state.pe_other_pid;
61111.13Schristos	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
61121.1Skamil
61131.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61141.1Skamil	    "without signal to be sent\n");
61151.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61161.1Skamil
61171.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
61181.1Skamil	    "SIGCHLD\n", TWAIT_FNAME);
61191.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61201.1Skamil
61211.1Skamil	validate_status_stopped(status, SIGCHLD);
61221.1Skamil
61231.13Schristos	DPRINTF("Before resuming the child process where it left off and "
61241.1Skamil	    "without signal to be sent\n");
61251.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
61261.1Skamil
61271.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
61281.1Skamil	    TWAIT_FNAME);
61291.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
61301.1Skamil
61311.1Skamil	validate_status_exited(status, exitval);
61321.1Skamil
61331.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
61341.1Skamil	    TWAIT_FNAME);
61351.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
61361.1Skamil}
61371.1Skamil
61381.1SkamilATF_TC(signal9);
61391.1SkamilATF_TC_HEAD(signal9, tc)
61401.1Skamil{
61411.1Skamil	atf_tc_set_md_var(tc, "descr",
61421.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
61431.1Skamil	    "catching PTRACE_LWP_CREATE breakpoint");
61441.1Skamil}
61451.1Skamil
61461.1SkamilATF_TC_BODY(signal9, tc)
61471.1Skamil{
61481.1Skamil	const int exitval = 5;
61491.1Skamil	const int sigval = SIGSTOP;
61501.1Skamil	const int sigmasked = SIGTRAP;
61511.1Skamil	pid_t child, wpid;
61521.1Skamil#if defined(TWAIT_HAVE_STATUS)
61531.1Skamil	int status;
61541.1Skamil#endif
61551.1Skamil	sigset_t intmask;
61561.1Skamil	ptrace_state_t state;
61571.1Skamil	const int slen = sizeof(state);
61581.1Skamil	ptrace_event_t event;
61591.1Skamil	const int elen = sizeof(event);
61601.1Skamil	ucontext_t uc;
61611.1Skamil	lwpid_t lid;
61621.1Skamil	static const size_t ssize = 16*1024;
61631.1Skamil	void *stack;
61641.1Skamil
61651.14Schristos	atf_tc_expect_fail("PR kern/51918");
61661.14Schristos
61671.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
61681.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
61691.1Skamil	if (child == 0) {
61701.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
61711.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
61721.1Skamil
61731.1Skamil		sigemptyset(&intmask);
61741.1Skamil		sigaddset(&intmask, sigmasked);
61751.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
61761.1Skamil
61771.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
61781.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
61791.1Skamil
61801.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
61811.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
61821.1Skamil
61831.13Schristos		DPRINTF("Before making context for new lwp in child\n");
61841.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
61851.1Skamil
61861.13Schristos		DPRINTF("Before creating new in child\n");
61871.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
61881.1Skamil
61891.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
61901.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
61911.1Skamil
61921.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
61931.1Skamil		    "are the same\n", lid, the_lwp_id);
61941.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
61951.1Skamil
61961.13Schristos		DPRINTF("Before exiting of the child process\n");
61971.1Skamil		_exit(exitval);
61981.1Skamil	}
61991.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
62001.1Skamil
62011.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
62021.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62031.1Skamil
62041.1Skamil	validate_status_stopped(status, sigval);
62051.1Skamil
62061.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
62071.1Skamil	event.pe_set_event = PTRACE_LWP_CREATE;
62081.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
62091.1Skamil
62101.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62111.1Skamil	    "without signal to be sent\n");
62121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62131.1Skamil
62141.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
62151.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
62161.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62171.1Skamil
62181.1Skamil	validate_status_stopped(status, sigmasked);
62191.1Skamil
62201.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
62211.1Skamil
62221.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
62231.1Skamil
62241.1Skamil	lid = state.pe_lwp;
62251.13Schristos	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
62261.1Skamil
62271.13Schristos	DPRINTF("Before resuming the child process where it left off and "
62281.1Skamil	    "without signal to be sent\n");
62291.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
62301.1Skamil
62311.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
62321.1Skamil	    TWAIT_FNAME);
62331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
62341.1Skamil
62351.1Skamil	validate_status_exited(status, exitval);
62361.1Skamil
62371.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
62381.1Skamil	    TWAIT_FNAME);
62391.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
62401.1Skamil}
62411.1Skamil
62421.1SkamilATF_TC(signal10);
62431.1SkamilATF_TC_HEAD(signal10, tc)
62441.1Skamil{
62451.1Skamil	atf_tc_set_md_var(tc, "descr",
62461.1Skamil	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
62471.1Skamil	    "catching PTRACE_LWP_EXIT breakpoint");
62481.1Skamil}
62491.1Skamil
62501.1SkamilATF_TC_BODY(signal10, tc)
62511.1Skamil{
62521.1Skamil	const int exitval = 5;
62531.1Skamil	const int sigval = SIGSTOP;
62541.1Skamil	const int sigmasked = SIGTRAP;
62551.1Skamil	pid_t child, wpid;
62561.1Skamil#if defined(TWAIT_HAVE_STATUS)
62571.1Skamil	int status;
62581.1Skamil#endif
62591.1Skamil	sigset_t intmask;
62601.1Skamil	ptrace_state_t state;
62611.1Skamil	const int slen = sizeof(state);
62621.1Skamil	ptrace_event_t event;
62631.1Skamil	const int elen = sizeof(event);
62641.1Skamil	ucontext_t uc;
62651.1Skamil	lwpid_t lid;
62661.1Skamil	static const size_t ssize = 16*1024;
62671.1Skamil	void *stack;
62681.1Skamil
62691.14Schristos	atf_tc_expect_fail("PR kern/51918");
62701.14Schristos
62711.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
62721.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
62731.1Skamil	if (child == 0) {
62741.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
62751.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
62761.1Skamil
62771.1Skamil		sigemptyset(&intmask);
62781.1Skamil		sigaddset(&intmask, sigmasked);
62791.1Skamil		sigprocmask(SIG_BLOCK, &intmask, NULL);
62801.1Skamil
62811.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
62821.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
62831.1Skamil
62841.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
62851.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
62861.1Skamil
62871.13Schristos		DPRINTF("Before making context for new lwp in child\n");
62881.1Skamil		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
62891.1Skamil
62901.13Schristos		DPRINTF("Before creating new in child\n");
62911.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
62921.1Skamil
62931.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
62941.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
62951.1Skamil
62961.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
62971.1Skamil		    "are the same\n", lid, the_lwp_id);
62981.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
62991.1Skamil
63001.13Schristos		DPRINTF("Before exiting of the child process\n");
63011.1Skamil		_exit(exitval);
63021.1Skamil	}
63031.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
63041.1Skamil
63051.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
63061.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63071.1Skamil
63081.1Skamil	validate_status_stopped(status, sigval);
63091.1Skamil
63101.13Schristos	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
63111.1Skamil	event.pe_set_event = PTRACE_LWP_EXIT;
63121.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
63131.1Skamil
63141.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63151.1Skamil	    "without signal to be sent\n");
63161.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63171.1Skamil
63181.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
63191.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
63201.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63211.1Skamil
63221.1Skamil	validate_status_stopped(status, sigmasked);
63231.1Skamil
63241.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
63251.1Skamil
63261.1Skamil	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
63271.1Skamil
63281.1Skamil	lid = state.pe_lwp;
63291.13Schristos	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
63301.1Skamil
63311.13Schristos	DPRINTF("Before resuming the child process where it left off and "
63321.1Skamil	    "without signal to be sent\n");
63331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
63341.1Skamil
63351.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
63361.1Skamil	    TWAIT_FNAME);
63371.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
63381.1Skamil
63391.1Skamil	validate_status_exited(status, exitval);
63401.1Skamil
63411.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
63421.1Skamil	    TWAIT_FNAME);
63431.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
63441.1Skamil}
63451.1Skamil
63461.1Skamilstatic void
63471.1Skamillwp_main_stop(void *arg)
63481.1Skamil{
63491.1Skamil	the_lwp_id = _lwp_self();
63501.1Skamil
63511.1Skamil	raise(SIGTRAP);
63521.1Skamil
63531.1Skamil	_lwp_exit();
63541.1Skamil}
63551.1Skamil
63561.1SkamilATF_TC(suspend1);
63571.1SkamilATF_TC_HEAD(suspend1, tc)
63581.1Skamil{
63591.1Skamil	atf_tc_set_md_var(tc, "descr",
63601.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
63611.1Skamil	    "resumed by a tracee");
63621.1Skamil}
63631.1Skamil
63641.1SkamilATF_TC_BODY(suspend1, tc)
63651.1Skamil{
63661.1Skamil	const int exitval = 5;
63671.1Skamil	const int sigval = SIGSTOP;
63681.1Skamil	pid_t child, wpid;
63691.1Skamil#if defined(TWAIT_HAVE_STATUS)
63701.1Skamil	int status;
63711.1Skamil#endif
63721.1Skamil	ucontext_t uc;
63731.1Skamil	lwpid_t lid;
63741.1Skamil	static const size_t ssize = 16*1024;
63751.1Skamil	void *stack;
63761.1Skamil	struct ptrace_lwpinfo pl;
63771.1Skamil	struct ptrace_siginfo psi;
63781.1Skamil	volatile int go = 0;
63791.1Skamil
63801.17Skamil	// Feature pending for refactoring
63811.17Skamil	atf_tc_expect_fail("PR kern/51995");
63821.17Skamil
63831.16Skamil	// Hangs with qemu
63841.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
63851.16Skamil
63861.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
63871.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
63881.1Skamil	if (child == 0) {
63891.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
63901.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
63911.1Skamil
63921.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
63931.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
63941.1Skamil
63951.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
63961.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
63971.1Skamil
63981.13Schristos		DPRINTF("Before making context for new lwp in child\n");
63991.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
64001.1Skamil
64011.13Schristos		DPRINTF("Before creating new in child\n");
64021.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
64031.1Skamil
64041.1Skamil		while (go == 0)
64051.1Skamil			continue;
64061.1Skamil
64071.1Skamil		raise(SIGINT);
64081.1Skamil
64091.1Skamil		FORKEE_ASSERT(_lwp_continue(lid) == 0);
64101.1Skamil
64111.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
64121.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
64131.1Skamil
64141.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
64151.1Skamil		    "are the same\n", lid, the_lwp_id);
64161.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
64171.1Skamil
64181.13Schristos		DPRINTF("Before exiting of the child process\n");
64191.1Skamil		_exit(exitval);
64201.1Skamil	}
64211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
64221.1Skamil
64231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
64241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64251.1Skamil
64261.1Skamil	validate_status_stopped(status, sigval);
64271.1Skamil
64281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64291.1Skamil	    "without signal to be sent\n");
64301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64311.1Skamil
64321.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64331.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
64341.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64351.1Skamil
64361.1Skamil	validate_status_stopped(status, SIGTRAP);
64371.1Skamil
64381.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
64391.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
64401.1Skamil
64411.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
64421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
64431.1Skamil
64441.13Schristos        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
64451.1Skamil	    child, getpid());
64461.13Schristos	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
64471.1Skamil
64481.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64491.1Skamil	    "without signal to be sent\n");
64501.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64511.1Skamil
64521.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
64531.1Skamil	    "SIGINT\n", TWAIT_FNAME);
64541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64551.1Skamil
64561.1Skamil	validate_status_stopped(status, SIGINT);
64571.1Skamil
64581.1Skamil	pl.pl_lwpid = 0;
64591.1Skamil
64601.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
64611.1Skamil	while (pl.pl_lwpid != 0) {
64621.1Skamil
64631.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
64641.1Skamil		switch (pl.pl_lwpid) {
64651.1Skamil		case 1:
64661.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
64671.1Skamil			break;
64681.1Skamil		case 2:
64691.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
64701.1Skamil			break;
64711.1Skamil		}
64721.1Skamil	}
64731.1Skamil
64741.13Schristos	DPRINTF("Before resuming the child process where it left off and "
64751.1Skamil	    "without signal to be sent\n");
64761.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
64771.1Skamil
64781.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
64791.1Skamil	    TWAIT_FNAME);
64801.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
64811.1Skamil
64821.1Skamil	validate_status_exited(status, exitval);
64831.1Skamil
64841.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
64851.1Skamil	    TWAIT_FNAME);
64861.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
64871.1Skamil}
64881.1Skamil
64891.1SkamilATF_TC(suspend2);
64901.1SkamilATF_TC_HEAD(suspend2, tc)
64911.1Skamil{
64921.1Skamil	atf_tc_set_md_var(tc, "descr",
64931.1Skamil	    "Verify that the while the only thread within a process is "
64941.1Skamil	    "suspended, the whole process cannot be unstopped");
64951.1Skamil}
64961.1Skamil
64971.1SkamilATF_TC_BODY(suspend2, tc)
64981.1Skamil{
64991.1Skamil	const int exitval = 5;
65001.1Skamil	const int sigval = SIGSTOP;
65011.1Skamil	pid_t child, wpid;
65021.1Skamil#if defined(TWAIT_HAVE_STATUS)
65031.1Skamil	int status;
65041.1Skamil#endif
65051.1Skamil	struct ptrace_siginfo psi;
65061.1Skamil
65071.17Skamil	// Feature pending for refactoring
65081.17Skamil	atf_tc_expect_fail("PR kern/51995");
65091.17Skamil
65101.16Skamil	// Hangs with qemu
65111.16Skamil	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
65121.16Skamil
65131.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65141.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65151.1Skamil	if (child == 0) {
65161.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65171.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
65181.1Skamil
65191.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
65201.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
65211.1Skamil
65221.13Schristos		DPRINTF("Before exiting of the child process\n");
65231.1Skamil		_exit(exitval);
65241.1Skamil	}
65251.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
65261.1Skamil
65271.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
65281.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65291.1Skamil
65301.1Skamil	validate_status_stopped(status, sigval);
65311.1Skamil
65321.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
65331.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
65341.1Skamil
65351.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
65361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
65371.1Skamil
65381.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65391.1Skamil	    "without signal to be sent\n");
65401.1Skamil	ATF_REQUIRE_ERRNO(EDEADLK,
65411.1Skamil	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
65421.1Skamil
65431.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
65441.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
65451.1Skamil
65461.13Schristos	DPRINTF("Before resuming the child process where it left off and "
65471.1Skamil	    "without signal to be sent\n");
65481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
65491.1Skamil
65501.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
65511.1Skamil	    TWAIT_FNAME);
65521.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
65531.1Skamil
65541.1Skamil	validate_status_exited(status, exitval);
65551.1Skamil
65561.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
65571.1Skamil	    TWAIT_FNAME);
65581.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
65591.1Skamil}
65601.1Skamil
65611.1SkamilATF_TC(resume1);
65621.1SkamilATF_TC_HEAD(resume1, tc)
65631.1Skamil{
65641.1Skamil	atf_tc_set_md_var(tc, "timeout", "5");
65651.1Skamil	atf_tc_set_md_var(tc, "descr",
65661.1Skamil	    "Verify that a thread can be suspended by a debugger and later "
65671.1Skamil	    "resumed by the debugger");
65681.1Skamil}
65691.1Skamil
65701.1SkamilATF_TC_BODY(resume1, tc)
65711.1Skamil{
65721.1Skamil	struct msg_fds fds;
65731.1Skamil	const int exitval = 5;
65741.1Skamil	const int sigval = SIGSTOP;
65751.1Skamil	pid_t child, wpid;
65761.1Skamil	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
65771.1Skamil#if defined(TWAIT_HAVE_STATUS)
65781.1Skamil	int status;
65791.1Skamil#endif
65801.1Skamil	ucontext_t uc;
65811.1Skamil	lwpid_t lid;
65821.1Skamil	static const size_t ssize = 16*1024;
65831.1Skamil	void *stack;
65841.1Skamil	struct ptrace_lwpinfo pl;
65851.1Skamil	struct ptrace_siginfo psi;
65861.1Skamil
65871.17Skamil	// Feature pending for refactoring
65881.17Skamil	atf_tc_expect_fail("PR kern/51995");
65891.17Skamil
65901.15Schristos	// Hangs with qemu
65911.15Schristos	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
65921.1Skamil
65931.13Schristos	SYSCALL_REQUIRE(msg_open(&fds) == 0);
65941.1Skamil
65951.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
65961.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
65971.1Skamil	if (child == 0) {
65981.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
65991.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
66001.1Skamil
66011.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
66021.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
66031.1Skamil
66041.13Schristos		DPRINTF("Before allocating memory for stack in child\n");
66051.1Skamil		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
66061.1Skamil
66071.13Schristos		DPRINTF("Before making context for new lwp in child\n");
66081.1Skamil		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
66091.1Skamil
66101.13Schristos		DPRINTF("Before creating new in child\n");
66111.1Skamil		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
66121.1Skamil
66131.1Skamil		CHILD_TO_PARENT("Message", fds, msg);
66141.1Skamil
66151.1Skamil		raise(SIGINT);
66161.1Skamil
66171.13Schristos		DPRINTF("Before waiting for lwp %d to exit\n", lid);
66181.1Skamil		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
66191.1Skamil
66201.13Schristos		DPRINTF("Before verifying that reported %d and running lid %d "
66211.1Skamil		    "are the same\n", lid, the_lwp_id);
66221.1Skamil		FORKEE_ASSERT_EQ(lid, the_lwp_id);
66231.1Skamil
66241.13Schristos		DPRINTF("Before exiting of the child process\n");
66251.1Skamil		_exit(exitval);
66261.1Skamil	}
66271.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
66281.1Skamil
66291.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
66301.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66311.1Skamil
66321.1Skamil	validate_status_stopped(status, sigval);
66331.1Skamil
66341.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66351.1Skamil	    "without signal to be sent\n");
66361.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66371.1Skamil
66381.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66391.1Skamil	    "SIGTRAP\n", TWAIT_FNAME);
66401.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66411.1Skamil
66421.1Skamil	validate_status_stopped(status, SIGTRAP);
66431.1Skamil
66441.13Schristos	DPRINTF("Before reading siginfo and lwpid_t\n");
66451.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
66461.1Skamil
66471.13Schristos	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
66481.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
66491.1Skamil
66501.1Skamil	PARENT_FROM_CHILD("Message", fds, msg);
66511.1Skamil
66521.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66531.1Skamil	    "without signal to be sent\n");
66541.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66551.1Skamil
66561.13Schristos	DPRINTF("Before calling %s() for the child - expected stopped "
66571.1Skamil	    "SIGINT\n", TWAIT_FNAME);
66581.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66591.1Skamil
66601.1Skamil	validate_status_stopped(status, SIGINT);
66611.1Skamil
66621.1Skamil	pl.pl_lwpid = 0;
66631.1Skamil
66641.13Schristos	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66651.1Skamil	while (pl.pl_lwpid != 0) {
66661.13Schristos		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
66671.1Skamil		switch (pl.pl_lwpid) {
66681.1Skamil		case 1:
66691.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
66701.1Skamil			break;
66711.1Skamil		case 2:
66721.1Skamil			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
66731.1Skamil			break;
66741.1Skamil		}
66751.1Skamil	}
66761.1Skamil
66771.13Schristos	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
66781.13Schristos	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
66791.1Skamil
66801.13Schristos	DPRINTF("Before resuming the child process where it left off and "
66811.1Skamil	    "without signal to be sent\n");
66821.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
66831.1Skamil
66841.13Schristos	DPRINTF("Before calling %s() for the child - expected exited\n",
66851.1Skamil	    TWAIT_FNAME);
66861.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
66871.1Skamil
66881.1Skamil	validate_status_exited(status, exitval);
66891.1Skamil
66901.13Schristos	DPRINTF("Before calling %s() for the child - expected no process\n",
66911.1Skamil	    TWAIT_FNAME);
66921.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
66931.1Skamil
66941.1Skamil	msg_close(&fds);
66951.1Skamil
66961.13Schristos	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
66971.1Skamil	sleep(10);
66981.1Skamil}
66991.1Skamil
67001.1SkamilATF_TC(syscall1);
67011.1SkamilATF_TC_HEAD(syscall1, tc)
67021.1Skamil{
67031.1Skamil	atf_tc_set_md_var(tc, "descr",
67041.1Skamil	    "Verify that getpid(2) can be traced with PT_SYSCALL");
67051.1Skamil}
67061.1Skamil
67071.1SkamilATF_TC_BODY(syscall1, tc)
67081.1Skamil{
67091.1Skamil	const int exitval = 5;
67101.1Skamil	const int sigval = SIGSTOP;
67111.1Skamil	pid_t child, wpid;
67121.1Skamil#if defined(TWAIT_HAVE_STATUS)
67131.1Skamil	int status;
67141.1Skamil#endif
67151.1Skamil	struct ptrace_siginfo info;
67161.1Skamil	memset(&info, 0, sizeof(info));
67171.1Skamil
67181.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
67191.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
67201.1Skamil	if (child == 0) {
67211.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
67221.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
67231.1Skamil
67241.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
67251.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
67261.1Skamil
67271.1Skamil		syscall(SYS_getpid);
67281.1Skamil
67291.13Schristos		DPRINTF("Before exiting of the child process\n");
67301.1Skamil		_exit(exitval);
67311.1Skamil	}
67321.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
67331.1Skamil
67341.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67351.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67361.1Skamil
67371.1Skamil	validate_status_stopped(status, sigval);
67381.1Skamil
67391.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67401.1Skamil	    "without signal to be sent\n");
67411.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
67421.1Skamil
67431.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67441.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67451.1Skamil
67461.1Skamil	validate_status_stopped(status, SIGTRAP);
67471.1Skamil
67481.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
67491.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
67501.1Skamil
67511.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
67521.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
67531.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
67541.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
67551.1Skamil
67561.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67571.1Skamil	    "without signal to be sent\n");
67581.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
67591.1Skamil
67601.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67611.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67621.1Skamil
67631.1Skamil	validate_status_stopped(status, SIGTRAP);
67641.1Skamil
67651.13Schristos	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
67661.13Schristos	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
67671.1Skamil
67681.38Skamil	DPRINTF("Before checking siginfo_t and lwpid\n");
67691.38Skamil	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
67701.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
67711.1Skamil	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
67721.1Skamil
67731.13Schristos	DPRINTF("Before resuming the child process where it left off and "
67741.1Skamil	    "without signal to be sent\n");
67751.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
67761.1Skamil
67771.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67781.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
67791.1Skamil
67801.1Skamil	validate_status_exited(status, exitval);
67811.1Skamil
67821.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
67831.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
67841.1Skamil}
67851.1Skamil
67861.1SkamilATF_TC(syscallemu1);
67871.1SkamilATF_TC_HEAD(syscallemu1, tc)
67881.1Skamil{
67891.1Skamil	atf_tc_set_md_var(tc, "descr",
67901.1Skamil	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
67911.1Skamil}
67921.1Skamil
67931.1SkamilATF_TC_BODY(syscallemu1, tc)
67941.1Skamil{
67951.1Skamil	const int exitval = 5;
67961.1Skamil	const int sigval = SIGSTOP;
67971.1Skamil	pid_t child, wpid;
67981.1Skamil#if defined(TWAIT_HAVE_STATUS)
67991.1Skamil	int status;
68001.1Skamil#endif
68011.1Skamil
68021.6Skamil#if defined(__sparc__) && !defined(__sparc64__)
68031.6Skamil	/* syscallemu does not work on sparc (32-bit) */
68041.6Skamil	atf_tc_expect_fail("PR kern/52166");
68051.6Skamil#endif
68061.6Skamil
68071.13Schristos	DPRINTF("Before forking process PID=%d\n", getpid());
68081.13Schristos	SYSCALL_REQUIRE((child = fork()) != -1);
68091.1Skamil	if (child == 0) {
68101.13Schristos		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
68111.1Skamil		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
68121.1Skamil
68131.13Schristos		DPRINTF("Before raising %s from child\n", strsignal(sigval));
68141.1Skamil		FORKEE_ASSERT(raise(sigval) == 0);
68151.1Skamil
68161.1Skamil		syscall(SYS_exit, 100);
68171.1Skamil
68181.13Schristos		DPRINTF("Before exiting of the child process\n");
68191.1Skamil		_exit(exitval);
68201.1Skamil	}
68211.13Schristos	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
68221.1Skamil
68231.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68241.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68251.1Skamil
68261.1Skamil	validate_status_stopped(status, sigval);
68271.1Skamil
68281.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68291.1Skamil	    "without signal to be sent\n");
68301.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
68311.1Skamil
68321.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68331.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68341.1Skamil
68351.1Skamil	validate_status_stopped(status, SIGTRAP);
68361.1Skamil
68371.13Schristos	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
68381.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
68391.1Skamil
68401.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68411.1Skamil	    "without signal to be sent\n");
68421.13Schristos	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
68431.1Skamil
68441.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68451.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68461.1Skamil
68471.1Skamil	validate_status_stopped(status, SIGTRAP);
68481.1Skamil
68491.13Schristos	DPRINTF("Before resuming the child process where it left off and "
68501.1Skamil	    "without signal to be sent\n");
68511.13Schristos	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
68521.1Skamil
68531.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68541.1Skamil	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
68551.1Skamil
68561.1Skamil	validate_status_exited(status, exitval);
68571.1Skamil
68581.13Schristos	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
68591.1Skamil	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
68601.1Skamil}
68611.1Skamil
68621.26Skamil#if defined(TWAIT_HAVE_PID)
68631.26SkamilATF_TC(race1);
68641.26SkamilATF_TC_HEAD(race1, tc)
68651.26Skamil{
68661.26Skamil	atf_tc_set_md_var(tc, "descr",
68671.26Skamil	    "Assert that await_zombie() in attach1 always finds a single "
68681.26Skamil	    "process and no other error is reported");
68691.26Skamil}
68701.26Skamil
68711.26SkamilATF_TC_BODY(race1, tc)
68721.26Skamil{
68731.26Skamil	time_t start, end;
68741.26Skamil	double diff;
68751.26Skamil	unsigned long N = 0;
68761.26Skamil
68771.26Skamil	/* Reuse this test with attach1 */
68781.26Skamil
68791.26Skamil	start = time(NULL);
68801.26Skamil	while (true) {
68811.26Skamil		DPRINTF("Step: %lu\n", N);
68821.26Skamil		attach1_raw(true);
68831.26Skamil		end = time(NULL);
68841.26Skamil		diff = difftime(end, start);
68851.26Skamil		if (diff >= 5.0)
68861.26Skamil			break;
68871.26Skamil		++N;
68881.26Skamil	}
68891.26Skamil	DPRINTF("Iterations: %lu\n", N);
68901.26Skamil}
68911.26Skamil#endif
68921.26Skamil
68931.1Skamil#include "t_ptrace_amd64_wait.h"
68941.1Skamil#include "t_ptrace_i386_wait.h"
68951.1Skamil#include "t_ptrace_x86_wait.h"
68961.1Skamil
68971.1SkamilATF_TP_ADD_TCS(tp)
68981.1Skamil{
68991.1Skamil	setvbuf(stdout, NULL, _IONBF, 0);
69001.1Skamil	setvbuf(stderr, NULL, _IONBF, 0);
69011.33Skamil
69021.36Skamil	ATF_TP_ADD_TC(tp, traceme_raise1);
69031.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise2);
69041.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise3);
69051.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise4);
69061.33Skamil	ATF_TP_ADD_TC(tp, traceme_raise5);
69071.33Skamil
69081.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
69091.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
69101.34Skamil	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
69111.34Skamil
69121.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler1);
69131.35Skamil//	ATF_TP_ADD_TC(tp, traceme_signal_nohandler2); // not yet
69141.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler3);
69151.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler4);
69161.35Skamil	ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);
69171.1Skamil
69181.37Skamil	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
69191.37Skamil
69201.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
69211.40Skamil//	ATF_TP_ADD_TC(tp, traceme_vfork_raise2); // not yet
69221.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
69231.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
69241.40Skamil	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
69251.40Skamil
69261.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
69271.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
69281.1Skamil	ATF_TP_ADD_TC(tp, attach3);
69291.1Skamil	ATF_TP_ADD_TC(tp, attach4);
69301.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
69311.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
69321.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
69331.1Skamil
69341.1Skamil	ATF_TP_ADD_TC(tp, eventmask1);
69351.1Skamil	ATF_TP_ADD_TC(tp, eventmask2);
69361.1Skamil	ATF_TP_ADD_TC(tp, eventmask3);
69371.1Skamil	ATF_TP_ADD_TC(tp, eventmask4);
69381.1Skamil	ATF_TP_ADD_TC(tp, eventmask5);
69391.1Skamil	ATF_TP_ADD_TC(tp, eventmask6);
69401.1Skamil
69411.31Skamil	ATF_TP_ADD_TC(tp, fork1);
69421.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
69431.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
69441.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
69451.31Skamil	ATF_TP_ADD_TC(tp, fork5);
69461.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
69471.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
69481.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
69491.31Skamil
69501.31Skamil	ATF_TP_ADD_TC(tp, vfork1);
69511.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
69521.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
69531.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
69541.31Skamil	ATF_TP_ADD_TC(tp, vfork5);
69551.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
69561.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
69571.31Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
69581.1Skamil
69591.1Skamil	ATF_TP_ADD_TC(tp, io_read_d1);
69601.1Skamil	ATF_TP_ADD_TC(tp, io_read_d2);
69611.1Skamil	ATF_TP_ADD_TC(tp, io_read_d3);
69621.1Skamil	ATF_TP_ADD_TC(tp, io_read_d4);
69631.1Skamil
69641.1Skamil	ATF_TP_ADD_TC(tp, io_write_d1);
69651.1Skamil	ATF_TP_ADD_TC(tp, io_write_d2);
69661.1Skamil	ATF_TP_ADD_TC(tp, io_write_d3);
69671.1Skamil	ATF_TP_ADD_TC(tp, io_write_d4);
69681.1Skamil
69691.1Skamil	ATF_TP_ADD_TC(tp, read_d1);
69701.1Skamil	ATF_TP_ADD_TC(tp, read_d2);
69711.1Skamil	ATF_TP_ADD_TC(tp, read_d3);
69721.1Skamil	ATF_TP_ADD_TC(tp, read_d4);
69731.1Skamil
69741.1Skamil	ATF_TP_ADD_TC(tp, write_d1);
69751.1Skamil	ATF_TP_ADD_TC(tp, write_d2);
69761.1Skamil	ATF_TP_ADD_TC(tp, write_d3);
69771.1Skamil	ATF_TP_ADD_TC(tp, write_d4);
69781.1Skamil
69791.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
69801.1Skamil	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
69811.1Skamil
69821.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
69831.1Skamil	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
69841.1Skamil
69851.1Skamil	ATF_TP_ADD_TC(tp, io_read_i1);
69861.1Skamil	ATF_TP_ADD_TC(tp, io_read_i2);
69871.1Skamil	ATF_TP_ADD_TC(tp, io_read_i3);
69881.1Skamil	ATF_TP_ADD_TC(tp, io_read_i4);
69891.1Skamil
69901.1Skamil	ATF_TP_ADD_TC(tp, read_i1);
69911.1Skamil	ATF_TP_ADD_TC(tp, read_i2);
69921.1Skamil	ATF_TP_ADD_TC(tp, read_i3);
69931.1Skamil	ATF_TP_ADD_TC(tp, read_i4);
69941.1Skamil
69951.1Skamil	ATF_TP_ADD_TC(tp, io_read_auxv1);
69961.1Skamil
69971.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
69981.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
69991.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
70001.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
70011.1Skamil	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
70021.1Skamil
70031.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
70041.1Skamil	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
70051.1Skamil
70061.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step1);
70071.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step2);
70081.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step3);
70091.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, step4);
70101.1Skamil
70111.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
70121.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
70131.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
70141.2Skamil	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
70151.2Skamil
70161.1Skamil	ATF_TP_ADD_TC(tp, kill1);
70171.1Skamil	ATF_TP_ADD_TC(tp, kill2);
70181.1Skamil
70191.1Skamil	ATF_TP_ADD_TC(tp, lwpinfo1);
70201.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
70211.1Skamil
70221.1Skamil	ATF_TP_ADD_TC(tp, siginfo1);
70231.1Skamil	ATF_TP_ADD_TC(tp, siginfo2);
70241.1Skamil	ATF_TP_ADD_TC(tp, siginfo3);
70251.1Skamil	ATF_TP_ADD_TC(tp, siginfo4);
70261.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
70271.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
70281.1Skamil
70291.1Skamil	ATF_TP_ADD_TC(tp, lwp_create1);
70301.1Skamil
70311.1Skamil	ATF_TP_ADD_TC(tp, lwp_exit1);
70321.1Skamil
70331.1Skamil	ATF_TP_ADD_TC(tp, signal1);
70341.1Skamil	ATF_TP_ADD_TC(tp, signal2);
70351.1Skamil	ATF_TP_ADD_TC(tp, signal3);
70361.1Skamil	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
70371.1Skamil	ATF_TP_ADD_TC(tp, signal5);
70381.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
70391.1Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
70401.1Skamil	ATF_TP_ADD_TC(tp, signal8);
70411.1Skamil	ATF_TP_ADD_TC(tp, signal9);
70421.1Skamil	ATF_TP_ADD_TC(tp, signal10);
70431.1Skamil
70441.1Skamil	ATF_TP_ADD_TC(tp, suspend1);
70451.1Skamil	ATF_TP_ADD_TC(tp, suspend2);
70461.1Skamil
70471.1Skamil	ATF_TP_ADD_TC(tp, resume1);
70481.1Skamil
70491.1Skamil	ATF_TP_ADD_TC(tp, syscall1);
70501.1Skamil
70511.1Skamil	ATF_TP_ADD_TC(tp, syscallemu1);
70521.1Skamil
70531.26Skamil	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
70541.26Skamil
70551.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
70561.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
70571.1Skamil	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
70581.1Skamil
70591.1Skamil	return atf_no_error();
70601.1Skamil}
7061