t_ptrace_wait.c revision 1.48
1/*	$NetBSD: t_ptrace_wait.c,v 1.48 2018/05/20 03:51:31 kamil Exp $	*/
2
3/*-
4 * Copyright (c) 2016 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__RCSID("$NetBSD: t_ptrace_wait.c,v 1.48 2018/05/20 03:51:31 kamil Exp $");
31
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/mman.h>
35#include <sys/ptrace.h>
36#include <sys/resource.h>
37#include <sys/stat.h>
38#include <sys/syscall.h>
39#include <sys/sysctl.h>
40#include <sys/wait.h>
41#include <machine/reg.h>
42#include <elf.h>
43#include <err.h>
44#include <errno.h>
45#include <lwp.h>
46#include <sched.h>
47#include <signal.h>
48#include <stdint.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <strings.h>
52#include <time.h>
53#include <unistd.h>
54
55#include <atf-c.h>
56
57#include "h_macros.h"
58
59#include "t_ptrace_wait.h"
60#include "msg.h"
61
62#define PARENT_TO_CHILD(info, fds, msg) \
63    SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
64
65#define CHILD_FROM_PARENT(info, fds, msg) \
66    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
67
68#define CHILD_TO_PARENT(info, fds, msg) \
69    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
70
71#define PARENT_FROM_CHILD(info, fds, msg) \
72    SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
73
74#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
75    strerror(errno))
76#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
77    "%d(%s) != %d", res, strerror(res), exp)
78
79static int debug = 0;
80
81#define DPRINTF(a, ...)	do  \
82	if (debug) printf(a,  ##__VA_ARGS__); \
83    while (/*CONSTCOND*/0)
84
85/// ----------------------------------------------------------------------------
86
87static void
88traceme_raise(int sigval)
89{
90	const int exitval = 5;
91	pid_t child, wpid;
92#if defined(TWAIT_HAVE_STATUS)
93	int status;
94#endif
95
96	struct ptrace_siginfo info;
97	memset(&info, 0, sizeof(info));
98
99	DPRINTF("Before forking process PID=%d\n", getpid());
100	SYSCALL_REQUIRE((child = fork()) != -1);
101	if (child == 0) {
102		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
103		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
104
105		DPRINTF("Before raising %s from child\n", strsignal(sigval));
106		FORKEE_ASSERT(raise(sigval) == 0);
107
108		switch (sigval) {
109		case SIGKILL:
110			/* NOTREACHED */
111			FORKEE_ASSERTX(0 && "This shall not be reached");
112		default:
113			DPRINTF("Before exiting of the child process\n");
114			_exit(exitval);
115		}
116	}
117	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
118
119	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
120	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
121
122	switch (sigval) {
123	case SIGKILL:
124		validate_status_signaled(status, sigval, 0);
125		break;
126	default:
127		validate_status_stopped(status, sigval);
128
129		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
130		        "child\n");
131		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
132		                       sizeof(info)) != -1);
133
134		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
135		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
136		        "si_errno=%#x\n",
137		        info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
138		        info.psi_siginfo.si_errno);
139
140		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
141		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
142
143		DPRINTF("Before resuming the child process where it left off "
144		    "and without signal to be sent\n");
145		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
146
147		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
148		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
149		                      child);
150		break;
151	}
152
153	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
154	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
155}
156
157#define TRACEME_RAISE(test, sig)						\
158ATF_TC(test);									\
159ATF_TC_HEAD(test, tc)								\
160{										\
161	atf_tc_set_md_var(tc, "descr",						\
162	    "Verify " #sig " followed by _exit(2) in a child");			\
163}										\
164										\
165ATF_TC_BODY(test, tc)								\
166{										\
167										\
168	traceme_raise(sig);							\
169}
170
171TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
172TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
173TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
174TRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
175TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
176
177/// ----------------------------------------------------------------------------
178
179static void
180traceme_sighandler_catch(int sigsent, void (*sah)(int arg), int *traceme_caught)
181{
182	const int exitval = 5;
183	const int sigval = SIGSTOP;
184	pid_t child, wpid;
185	struct sigaction sa;
186#if defined(TWAIT_HAVE_STATUS)
187	int status;
188#endif
189
190	struct ptrace_siginfo info;
191	memset(&info, 0, sizeof(info));
192
193	DPRINTF("Before forking process PID=%d\n", getpid());
194	SYSCALL_REQUIRE((child = fork()) != -1);
195	if (child == 0) {
196		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
197		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
198
199		sa.sa_handler = sah;
200		sa.sa_flags = SA_SIGINFO;
201		sigemptyset(&sa.sa_mask);
202
203		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
204
205		DPRINTF("Before raising %s from child\n", strsignal(sigval));
206		FORKEE_ASSERT(raise(sigval) == 0);
207
208		FORKEE_ASSERT_EQ(*traceme_caught, 1);
209
210		DPRINTF("Before exiting of the child process\n");
211		_exit(exitval);
212	}
213	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
214
215	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
216	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
217
218	validate_status_stopped(status, sigval);
219
220	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
221	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
222	                != -1);
223
224	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
225	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
226	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
227	    info.psi_siginfo.si_errno);
228
229	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
230	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
231
232	DPRINTF("Before resuming the child process where it left off and with "
233	    "signal %s to be sent\n", strsignal(sigsent));
234	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
235
236	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
237	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
238
239	validate_status_exited(status, exitval);
240
241	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
242	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
243}
244
245#define TRACEME_SIGHANDLER_CATCH(test, sig)					\
246ATF_TC(test);									\
247ATF_TC_HEAD(test, tc)								\
248{										\
249	atf_tc_set_md_var(tc, "descr",						\
250	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
251	    "handled correctly and caught by a signal handler");		\
252}										\
253										\
254static int test##_caught = 0;							\
255										\
256static void									\
257test##_sighandler(int arg)							\
258{										\
259	FORKEE_ASSERT_EQ(arg, sig);						\
260										\
261	++ test##_caught;							\
262}										\
263										\
264ATF_TC_BODY(test, tc)								\
265{										\
266										\
267	traceme_sighandler_catch(sig, test##_sighandler, & test##_caught);	\
268}
269
270// A signal handler for SIGKILL and SIGSTOP cannot be registered.
271TRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch1, SIGABRT) /* abort trap */
272TRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch2, SIGHUP)  /* hangup */
273TRACEME_SIGHANDLER_CATCH(traceme_sighandler_catch3, SIGCONT) /* continued? */
274
275/// ----------------------------------------------------------------------------
276
277static void
278traceme_signal_nohandler(int sigsent)
279{
280	const int sigval = SIGSTOP;
281	int exitval = 0;
282	pid_t child, wpid;
283#if defined(TWAIT_HAVE_STATUS)
284	int status;
285	int expect_core = (sigsent == SIGABRT) ? 1 : 0;
286#endif
287
288	struct ptrace_siginfo info;
289	memset(&info, 0, sizeof(info));
290
291	DPRINTF("Before forking process PID=%d\n", getpid());
292	SYSCALL_REQUIRE((child = fork()) != -1);
293	if (child == 0) {
294		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
295		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
296
297		DPRINTF("Before raising %s from child\n", strsignal(sigval));
298		FORKEE_ASSERT(raise(sigval) == 0);
299
300		switch (sigsent) {
301		case SIGCONT:
302		case SIGSTOP:
303			_exit(exitval);
304		default:
305			/* NOTREACHED */
306			FORKEE_ASSERTX(0 && "This shall not be reached");
307		}
308	}
309	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
310
311	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
312	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
313
314	validate_status_stopped(status, sigval);
315
316	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
317	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
318	                != -1);
319
320	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
321	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
322	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
323	    info.psi_siginfo.si_errno);
324
325	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
326	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
327
328	DPRINTF("Before resuming the child process where it left off and with "
329	    "signal %s to be sent\n", strsignal(sigsent));
330	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
331
332	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
333	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
334
335	switch (sigsent) {
336	case SIGSTOP:
337		validate_status_stopped(status, sigsent);
338		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
339		        "child\n");
340		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
341		                       sizeof(info)) != -1);
342
343		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
344		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
345		        "si_errno=%#x\n",
346			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
347		        info.psi_siginfo.si_errno);
348
349		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
350		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
351
352		DPRINTF("Before resuming the child process where it left off "
353		        "and with signal %s to be sent\n", strsignal(sigsent));
354		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
355
356		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
357		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
358		                      child);
359		/* FALLTHROUGH */
360	case SIGCONT:
361		validate_status_exited(status, exitval);
362		break;
363	default:
364		validate_status_signaled(status, sigsent, expect_core);
365		break;
366	}
367
368	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
369	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
370}
371
372#define TRACEME_SIGNAL_NOHANDLER(test, sig)					\
373ATF_TC(test);									\
374ATF_TC_HEAD(test, tc)								\
375{										\
376	atf_tc_set_md_var(tc, "descr",						\
377	    "Verify that a signal " #sig " emitted by a tracer to a child is "	\
378	    "handled correctly in a child without a signal handler");		\
379}										\
380										\
381ATF_TC_BODY(test, tc)								\
382{										\
383										\
384	traceme_signal_nohandler(sig);						\
385}
386
387TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */
388TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */
389TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */
390TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP)  /* hangup */
391TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */
392
393/// ----------------------------------------------------------------------------
394
395ATF_TC(traceme_pid1_parent);
396ATF_TC_HEAD(traceme_pid1_parent, tc)
397{
398	atf_tc_set_md_var(tc, "descr",
399	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
400}
401
402ATF_TC_BODY(traceme_pid1_parent, tc)
403{
404	struct msg_fds parent_child;
405	int exitval_child1 = 1, exitval_child2 = 2;
406	pid_t child1, child2, wpid;
407	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
408#if defined(TWAIT_HAVE_STATUS)
409	int status;
410#endif
411
412	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
413
414	DPRINTF("Before forking process PID=%d\n", getpid());
415	SYSCALL_REQUIRE((child1 = fork()) != -1);
416	if (child1 == 0) {
417		DPRINTF("Before forking process PID=%d\n", getpid());
418		SYSCALL_REQUIRE((child2 = fork()) != -1);
419		if (child2 != 0) {
420			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
421			        getpid(), child2);
422			_exit(exitval_child1);
423		}
424		CHILD_FROM_PARENT("exit child1", parent_child, msg);
425
426		DPRINTF("Assert that our parent is PID1 (initproc)\n");
427		FORKEE_ASSERT_EQ(getppid(), 1);
428
429		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
430		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
431		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
432
433		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
434
435		_exit(exitval_child2);
436	}
437	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
438
439	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
440	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child1, &status, WEXITED),
441	                      child1);
442
443	validate_status_exited(status, exitval_child1);
444
445	DPRINTF("Notify that child1 is dead\n");
446	PARENT_TO_CHILD("exit child1", parent_child, msg);
447
448	DPRINTF("Wait for exiting of child2\n");
449	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
450}
451
452/// ----------------------------------------------------------------------------
453
454static void
455traceme_vfork_raise(int sigval)
456{
457	const int exitval = 5, exitval_watcher = 10;
458	pid_t child, parent, watcher, wpid;
459	int rv;
460#if defined(TWAIT_HAVE_STATUS)
461	int status;
462	int expect_core = (sigval == SIGABRT) ? 1 : 0;
463#endif
464
465	/*
466	 * Spawn a dedicated thread to watch for a stopped child and emit
467	 * the SIGKILL signal to it.
468	 *
469	 * vfork(2) might clobber watcher, this means that it's safer and
470	 * simpler to reparent this process to initproc and forget about it.
471	 */
472	if (sigval == SIGSTOP) {
473		parent = getpid();
474
475		watcher = fork();
476		ATF_REQUIRE(watcher != 1);
477		if (watcher == 0) {
478			/* Double fork(2) trick to reparent to initproc */
479			watcher = fork();
480			FORKEE_ASSERT_NEQ(watcher, -1);
481			if (watcher != 0)
482				_exit(exitval_watcher);
483
484			child = await_stopped_child(parent);
485
486			errno = 0;
487			rv = kill(child, SIGKILL);
488			FORKEE_ASSERT_EQ(rv, 0);
489			FORKEE_ASSERT_EQ(errno, 0);
490
491			/* This exit value will be collected by initproc */
492			_exit(0);
493		}
494		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
495		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
496		                      watcher);
497
498		validate_status_exited(status, exitval_watcher);
499
500		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
501		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(watcher,
502		                                                   &status, 0));
503	}
504
505	DPRINTF("Before forking process PID=%d\n", getpid());
506	SYSCALL_REQUIRE((child = vfork()) != -1);
507	if (child == 0) {
508		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
509		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
510
511		DPRINTF("Before raising %s from child\n", strsignal(sigval));
512		FORKEE_ASSERT(raise(sigval) == 0);
513
514		switch (sigval) {
515		case SIGSTOP:
516		case SIGKILL:
517		case SIGABRT:
518		case SIGHUP:
519			/* NOTREACHED */
520			FORKEE_ASSERTX(0 && "This shall not be reached");
521		default:
522			DPRINTF("Before exiting of the child process\n");
523			_exit(exitval);
524		}
525	}
526	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
527
528	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
529	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
530
531	switch (sigval) {
532	case SIGKILL:
533	case SIGABRT:
534	case SIGHUP:
535		validate_status_signaled(status, sigval, expect_core);
536		break;
537	case SIGSTOP:
538		validate_status_signaled(status, SIGKILL, 0);
539		break;
540	case SIGCONT:
541	case SIGTSTP:
542	case SIGTTIN:
543	case SIGTTOU:
544		validate_status_exited(status, exitval);
545		break;
546	default:
547		/* NOTREACHED */
548		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
549		break;
550	}
551
552	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
553	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
554}
555
556#define TRACEME_VFORK_RAISE(test, sig)						\
557ATF_TC(test);									\
558ATF_TC_HEAD(test, tc)								\
559{										\
560	atf_tc_set_md_var(tc, "descr",						\
561	    "Verify PT_TRACE_ME followed by raise of " #sig " in a vfork(2)ed "	\
562	    "child");								\
563}										\
564										\
565ATF_TC_BODY(test, tc)								\
566{										\
567										\
568	traceme_vfork_raise(sig);						\
569}
570
571TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
572TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
573TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
574TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
575TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
576TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
577TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
578TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
579
580/// ----------------------------------------------------------------------------
581
582ATF_TC(traceme_vfork_breakpoint);
583ATF_TC_HEAD(traceme_vfork_breakpoint, tc)
584{
585	atf_tc_set_md_var(tc, "descr",
586	    "Verify PT_TRACE_ME followed by a software breakpoint in a "
587	    "vfork(2)ed child");
588}
589
590ATF_TC_BODY(traceme_vfork_breakpoint, tc)
591{
592	pid_t child, wpid;
593#if defined(TWAIT_HAVE_STATUS)
594	int status;
595#endif
596
597	DPRINTF("Before forking process PID=%d\n", getpid());
598	SYSCALL_REQUIRE((child = vfork()) != -1);
599	if (child == 0) {
600		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
601		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
602
603		DPRINTF("Before executing a software breakpoint\n");
604#ifdef PTRACE_BREAKPOINT_ASM
605		PTRACE_BREAKPOINT_ASM;
606#else
607		/* port me */
608#endif
609
610		/* NOTREACHED */
611		FORKEE_ASSERTX(0 && "This shall not be reached");
612	}
613	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
614
615	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
616	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
617
618	validate_status_signaled(status, SIGTRAP, 1);
619
620	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
621	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
622}
623
624/// ----------------------------------------------------------------------------
625
626ATF_TC(traceme_vfork_exec);
627ATF_TC_HEAD(traceme_vfork_exec, tc)
628{
629	atf_tc_set_md_var(tc, "descr",
630	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child");
631}
632
633ATF_TC_BODY(traceme_vfork_exec, tc)
634{
635	const int sigval = SIGTRAP;
636	pid_t child, wpid;
637#if defined(TWAIT_HAVE_STATUS)
638	int status;
639#endif
640
641	struct ptrace_siginfo info;
642	memset(&info, 0, sizeof(info));
643
644	DPRINTF("Before forking process PID=%d\n", getpid());
645	SYSCALL_REQUIRE((child = vfork()) != -1);
646	if (child == 0) {
647		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
648		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
649
650		DPRINTF("Before calling execve(2) from child\n");
651		execlp("/bin/echo", "/bin/echo", NULL);
652
653		/* NOTREACHED */
654		FORKEE_ASSERTX(0 && "Not reached");
655	}
656	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
657
658	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
659	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
660
661	validate_status_stopped(status, sigval);
662
663	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
664	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
665
666	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
667	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
668	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
669	    info.psi_siginfo.si_errno);
670
671	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
672	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
673
674	DPRINTF("Before resuming the child process where it left off and "
675	    "without signal to be sent\n");
676	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
677
678	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
679	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
680
681	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
682	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
683}
684
685/// ----------------------------------------------------------------------------
686
687#if defined(TWAIT_HAVE_PID)
688ATF_TC(attach1);
689ATF_TC_HEAD(attach1, tc)
690{
691	atf_tc_set_md_var(tc, "descr",
692	    "Assert that tracer sees process termination before the parent");
693}
694
695static void
696attach1_raw(bool raw)
697{
698	struct msg_fds parent_tracee, parent_tracer;
699	const int exitval_tracee = 5;
700	const int exitval_tracer = 10;
701	pid_t tracee, tracer, wpid;
702	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
703#if defined(TWAIT_HAVE_STATUS)
704	int status;
705#endif
706
707	DPRINTF("Spawn tracee\n");
708	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
709	tracee = atf_utils_fork();
710	if (tracee == 0) {
711		// Wait for parent to let us exit
712		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
713		_exit(exitval_tracee);
714	}
715
716	DPRINTF("Spawn debugger\n");
717	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
718	tracer = atf_utils_fork();
719	if (tracer == 0) {
720		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
721		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
722
723		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
724		FORKEE_REQUIRE_SUCCESS(
725		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
726
727		forkee_status_stopped(status, SIGSTOP);
728
729		/* Resume tracee with PT_CONTINUE */
730		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
731
732		/* Inform parent that tracer has attached to tracee */
733		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
734
735		/* Wait for parent to tell use that tracee should have exited */
736		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
737
738		/* Wait for tracee and assert that it exited */
739		FORKEE_REQUIRE_SUCCESS(
740		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
741
742		forkee_status_exited(status, exitval_tracee);
743		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
744
745		DPRINTF("Before exiting of the tracer process\n");
746		_exit(exitval_tracer);
747	}
748
749	DPRINTF("Wait for the tracer to attach to the tracee\n");
750	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
751
752	DPRINTF("Resume the tracee and let it exit\n");
753	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
754
755	DPRINTF("Detect that tracee is zombie\n");
756	if (raw)
757		await_zombie_raw(tracee, 0);
758	else
759		await_zombie(tracee);
760
761	DPRINTF("Assert that there is no status about tracee %d - "
762	    "Tracer must detect zombie first - calling %s()\n", tracee,
763	    TWAIT_FNAME);
764	TWAIT_REQUIRE_SUCCESS(
765	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
766
767	DPRINTF("Tell the tracer child should have exited\n");
768	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
769	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
770	    TWAIT_FNAME);
771
772	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
773	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
774	    tracer);
775
776	validate_status_exited(status, exitval_tracer);
777
778	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
779	    TWAIT_FNAME);
780	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
781	    tracee);
782
783	validate_status_exited(status, exitval_tracee);
784
785	msg_close(&parent_tracer);
786	msg_close(&parent_tracee);
787}
788
789ATF_TC_BODY(attach1, tc)
790{
791
792	/* Reuse this test with race1 */
793	attach1_raw(false);
794}
795
796#endif
797
798#if defined(TWAIT_HAVE_PID)
799ATF_TC(attach2);
800ATF_TC_HEAD(attach2, tc)
801{
802	atf_tc_set_md_var(tc, "descr",
803	    "Assert that any tracer sees process termination before its "
804	    "parent");
805}
806
807ATF_TC_BODY(attach2, tc)
808{
809	struct msg_fds parent_tracer, parent_tracee;
810	const int exitval_tracee = 5;
811	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
812	pid_t tracee, tracer, wpid;
813	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
814#if defined(TWAIT_HAVE_STATUS)
815	int status;
816#endif
817
818	DPRINTF("Spawn tracee\n");
819	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
820	tracee = atf_utils_fork();
821	if (tracee == 0) {
822		/* Wait for message from the parent */
823		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
824		_exit(exitval_tracee);
825	}
826
827	DPRINTF("Spawn debugger\n");
828	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
829	tracer = atf_utils_fork();
830	if (tracer == 0) {
831		/* Fork again and drop parent to reattach to PID 1 */
832		tracer = atf_utils_fork();
833		if (tracer != 0)
834			_exit(exitval_tracer1);
835
836		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
837		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
838
839		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
840		FORKEE_REQUIRE_SUCCESS(
841		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
842
843		forkee_status_stopped(status, SIGSTOP);
844
845		/* Resume tracee with PT_CONTINUE */
846		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
847
848		/* Inform parent that tracer has attached to tracee */
849		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
850		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
851
852		/* Wait for tracee and assert that it exited */
853		FORKEE_REQUIRE_SUCCESS(
854		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
855
856		forkee_status_exited(status, exitval_tracee);
857
858		DPRINTF("Before exiting of the tracer process\n");
859		_exit(exitval_tracer2);
860	}
861	DPRINTF("Wait for the tracer process (direct child) to exit calling "
862	    "%s()\n", TWAIT_FNAME);
863	TWAIT_REQUIRE_SUCCESS(
864	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
865
866	validate_status_exited(status, exitval_tracer1);
867
868	DPRINTF("Wait for the non-exited tracee process with %s()\n",
869	    TWAIT_FNAME);
870	TWAIT_REQUIRE_SUCCESS(
871	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
872
873	DPRINTF("Wait for the tracer to attach to the tracee\n");
874	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
875	DPRINTF("Resume the tracee and let it exit\n");
876	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
877
878	DPRINTF("Detect that tracee is zombie\n");
879	await_zombie(tracee);
880
881	DPRINTF("Assert that there is no status about tracee - "
882	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
883	TWAIT_REQUIRE_SUCCESS(
884	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
885
886	DPRINTF("Resume the tracer and let it detect exited tracee\n");
887	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
888
889	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
890	    TWAIT_FNAME);
891	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
892	    tracee);
893
894	validate_status_exited(status, exitval_tracee);
895
896	msg_close(&parent_tracer);
897	msg_close(&parent_tracee);
898}
899#endif
900
901ATF_TC(attach3);
902ATF_TC_HEAD(attach3, tc)
903{
904	atf_tc_set_md_var(tc, "descr",
905	    "Assert that tracer parent can PT_ATTACH to its child");
906}
907
908ATF_TC_BODY(attach3, tc)
909{
910	struct msg_fds parent_tracee;
911	const int exitval_tracee = 5;
912	pid_t tracee, wpid;
913	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
914#if defined(TWAIT_HAVE_STATUS)
915	int status;
916#endif
917
918	DPRINTF("Spawn tracee\n");
919	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
920	tracee = atf_utils_fork();
921	if (tracee == 0) {
922		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
923		DPRINTF("Parent should now attach to tracee\n");
924
925		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
926		/* Wait for message from the parent */
927		_exit(exitval_tracee);
928	}
929	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
930
931	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
932	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
933
934	DPRINTF("Wait for the stopped tracee process with %s()\n",
935	    TWAIT_FNAME);
936	TWAIT_REQUIRE_SUCCESS(
937	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
938
939	validate_status_stopped(status, SIGSTOP);
940
941	DPRINTF("Resume tracee with PT_CONTINUE\n");
942	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
943
944	DPRINTF("Let the tracee exit now\n");
945	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
946
947	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
948	TWAIT_REQUIRE_SUCCESS(
949	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
950
951	validate_status_exited(status, exitval_tracee);
952
953	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
954	TWAIT_REQUIRE_FAILURE(ECHILD,
955	    wpid = TWAIT_GENERIC(tracee, &status, 0));
956
957	msg_close(&parent_tracee);
958}
959
960ATF_TC(attach4);
961ATF_TC_HEAD(attach4, tc)
962{
963	atf_tc_set_md_var(tc, "descr",
964	    "Assert that tracer child can PT_ATTACH to its parent");
965}
966
967ATF_TC_BODY(attach4, tc)
968{
969	struct msg_fds parent_tracee;
970	const int exitval_tracer = 5;
971	pid_t tracer, wpid;
972	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
973#if defined(TWAIT_HAVE_STATUS)
974	int status;
975#endif
976
977	DPRINTF("Spawn tracer\n");
978	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
979	tracer = atf_utils_fork();
980	if (tracer == 0) {
981
982		/* Wait for message from the parent */
983		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
984
985		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
986		    getppid());
987		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
988
989		DPRINTF("Wait for the stopped parent process with %s()\n",
990		    TWAIT_FNAME);
991		FORKEE_REQUIRE_SUCCESS(
992		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
993
994		forkee_status_stopped(status, SIGSTOP);
995
996		DPRINTF("Resume parent with PT_DETACH\n");
997		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
998		    != -1);
999
1000		/* Tell parent we are ready */
1001		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
1002
1003		_exit(exitval_tracer);
1004	}
1005
1006	DPRINTF("Wait for the tracer to become ready\n");
1007	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
1008	DPRINTF("Allow the tracer to exit now\n");
1009	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
1010
1011	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
1012	TWAIT_REQUIRE_SUCCESS(
1013	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
1014
1015	validate_status_exited(status, exitval_tracer);
1016
1017	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
1018	TWAIT_REQUIRE_FAILURE(ECHILD,
1019	    wpid = TWAIT_GENERIC(tracer, &status, 0));
1020
1021	msg_close(&parent_tracee);
1022}
1023
1024#if defined(TWAIT_HAVE_PID)
1025ATF_TC(attach5);
1026ATF_TC_HEAD(attach5, tc)
1027{
1028	atf_tc_set_md_var(tc, "descr",
1029	    "Assert that tracer sees its parent when attached to tracer "
1030	    "(check getppid(2))");
1031}
1032
1033ATF_TC_BODY(attach5, tc)
1034{
1035	struct msg_fds parent_tracer, parent_tracee;
1036	const int exitval_tracee = 5;
1037	const int exitval_tracer = 10;
1038	pid_t parent, tracee, tracer, wpid;
1039	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1040#if defined(TWAIT_HAVE_STATUS)
1041	int status;
1042#endif
1043
1044	DPRINTF("Spawn tracee\n");
1045	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1046	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1047	tracee = atf_utils_fork();
1048	if (tracee == 0) {
1049		parent = getppid();
1050
1051		/* Emit message to the parent */
1052		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
1053		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
1054
1055		FORKEE_ASSERT_EQ(parent, getppid());
1056
1057		_exit(exitval_tracee);
1058	}
1059	DPRINTF("Wait for child to record its parent identifier (pid)\n");
1060	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
1061
1062	DPRINTF("Spawn debugger\n");
1063	tracer = atf_utils_fork();
1064	if (tracer == 0) {
1065		/* No IPC to communicate with the child */
1066		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1067		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1068
1069		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1070		FORKEE_REQUIRE_SUCCESS(
1071		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1072
1073		forkee_status_stopped(status, SIGSTOP);
1074
1075		/* Resume tracee with PT_CONTINUE */
1076		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1077
1078		/* Inform parent that tracer has attached to tracee */
1079		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1080
1081		/* Wait for parent to tell use that tracee should have exited */
1082		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
1083
1084		/* Wait for tracee and assert that it exited */
1085		FORKEE_REQUIRE_SUCCESS(
1086		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1087
1088		forkee_status_exited(status, exitval_tracee);
1089
1090		DPRINTF("Before exiting of the tracer process\n");
1091		_exit(exitval_tracer);
1092	}
1093
1094	DPRINTF("Wait for the tracer to attach to the tracee\n");
1095	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
1096
1097	DPRINTF("Resume the tracee and let it exit\n");
1098	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
1099
1100	DPRINTF("Detect that tracee is zombie\n");
1101	await_zombie(tracee);
1102
1103	DPRINTF("Assert that there is no status about tracee - "
1104	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
1105	TWAIT_REQUIRE_SUCCESS(
1106	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
1107
1108	DPRINTF("Tell the tracer child should have exited\n");
1109	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
1110
1111	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
1112	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
1113	    tracer);
1114
1115	validate_status_exited(status, exitval_tracer);
1116
1117	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1118	    TWAIT_FNAME);
1119	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
1120	    tracee);
1121
1122	validate_status_exited(status, exitval_tracee);
1123
1124	msg_close(&parent_tracer);
1125	msg_close(&parent_tracee);
1126}
1127#endif
1128
1129#if defined(TWAIT_HAVE_PID)
1130ATF_TC(attach6);
1131ATF_TC_HEAD(attach6, tc)
1132{
1133	atf_tc_set_md_var(tc, "descr",
1134	    "Assert that tracer sees its parent when attached to tracer "
1135	    "(check sysctl(7) and struct kinfo_proc2)");
1136}
1137
1138ATF_TC_BODY(attach6, tc)
1139{
1140	struct msg_fds parent_tracee, parent_tracer;
1141	const int exitval_tracee = 5;
1142	const int exitval_tracer = 10;
1143	pid_t parent, tracee, tracer, wpid;
1144	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1145#if defined(TWAIT_HAVE_STATUS)
1146	int status;
1147#endif
1148	int name[CTL_MAXNAME];
1149	struct kinfo_proc2 kp;
1150	size_t len = sizeof(kp);
1151	unsigned int namelen;
1152
1153	DPRINTF("Spawn tracee\n");
1154	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1155	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1156	tracee = atf_utils_fork();
1157	if (tracee == 0) {
1158		parent = getppid();
1159
1160		/* Emit message to the parent */
1161		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
1162		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
1163
1164		namelen = 0;
1165		name[namelen++] = CTL_KERN;
1166		name[namelen++] = KERN_PROC2;
1167		name[namelen++] = KERN_PROC_PID;
1168		name[namelen++] = getpid();
1169		name[namelen++] = len;
1170		name[namelen++] = 1;
1171
1172		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
1173		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
1174
1175		_exit(exitval_tracee);
1176	}
1177
1178	DPRINTF("Wait for child to record its parent identifier (pid)\n");
1179	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
1180
1181	DPRINTF("Spawn debugger\n");
1182	tracer = atf_utils_fork();
1183	if (tracer == 0) {
1184		/* No IPC to communicate with the child */
1185		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1186		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1187
1188		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1189		FORKEE_REQUIRE_SUCCESS(
1190		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1191
1192		forkee_status_stopped(status, SIGSTOP);
1193
1194		/* Resume tracee with PT_CONTINUE */
1195		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1196
1197		/* Inform parent that tracer has attached to tracee */
1198		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
1199
1200		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
1201
1202		/* Wait for tracee and assert that it exited */
1203		FORKEE_REQUIRE_SUCCESS(
1204		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1205
1206		forkee_status_exited(status, exitval_tracee);
1207
1208		DPRINTF("Before exiting of the tracer process\n");
1209		_exit(exitval_tracer);
1210	}
1211
1212	DPRINTF("Wait for the tracer to attach to the tracee\n");
1213	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
1214
1215	DPRINTF("Resume the tracee and let it exit\n");
1216	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
1217
1218	DPRINTF("Detect that tracee is zombie\n");
1219	await_zombie(tracee);
1220
1221	DPRINTF("Assert that there is no status about tracee - "
1222	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
1223	TWAIT_REQUIRE_SUCCESS(
1224	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
1225
1226	DPRINTF("Resume the tracer and let it detect exited tracee\n");
1227	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
1228
1229	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
1230	    TWAIT_FNAME);
1231	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
1232	    tracer);
1233
1234	validate_status_exited(status, exitval_tracer);
1235
1236	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1237	    TWAIT_FNAME);
1238	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
1239	    tracee);
1240
1241	validate_status_exited(status, exitval_tracee);
1242
1243	msg_close(&parent_tracee);
1244	msg_close(&parent_tracer);
1245}
1246#endif
1247
1248#if defined(TWAIT_HAVE_PID)
1249ATF_TC(attach7);
1250ATF_TC_HEAD(attach7, tc)
1251{
1252	atf_tc_set_md_var(tc, "descr",
1253	    "Assert that tracer sees its parent when attached to tracer "
1254	    "(check /proc/curproc/status 3rd column)");
1255}
1256
1257ATF_TC_BODY(attach7, tc)
1258{
1259	struct msg_fds parent_tracee, parent_tracer;
1260	int rv;
1261	const int exitval_tracee = 5;
1262	const int exitval_tracer = 10;
1263	pid_t parent, tracee, tracer, wpid;
1264	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1265#if defined(TWAIT_HAVE_STATUS)
1266	int status;
1267#endif
1268	FILE *fp;
1269	struct stat st;
1270	const char *fname = "/proc/curproc/status";
1271	char s_executable[MAXPATHLEN];
1272	int s_pid, s_ppid;
1273	/*
1274	 * Format:
1275	 *  EXECUTABLE PID PPID ...
1276	 */
1277
1278	SYSCALL_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
1279	if (rv != 0) {
1280		atf_tc_skip("/proc/curproc/status not found");
1281	}
1282
1283	DPRINTF("Spawn tracee\n");
1284	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1285	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1286	tracee = atf_utils_fork();
1287	if (tracee == 0) {
1288		parent = getppid();
1289
1290		// Wait for parent to let us exit
1291		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
1292		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
1293
1294		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
1295		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
1296		FORKEE_ASSERT(fclose(fp) == 0);
1297		FORKEE_ASSERT_EQ(parent, s_ppid);
1298
1299		_exit(exitval_tracee);
1300	}
1301
1302	DPRINTF("Wait for child to record its parent identifier (pid)\n");
1303	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
1304
1305	DPRINTF("Spawn debugger\n");
1306	tracer = atf_utils_fork();
1307	if (tracer == 0) {
1308		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1309		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1310
1311		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1312		FORKEE_REQUIRE_SUCCESS(
1313		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1314
1315		forkee_status_stopped(status, SIGSTOP);
1316
1317		/* Resume tracee with PT_CONTINUE */
1318		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1319
1320		/* Inform parent that tracer has attached to tracee */
1321		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1322
1323		/* Wait for parent to tell use that tracee should have exited */
1324		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
1325
1326		/* Wait for tracee and assert that it exited */
1327		FORKEE_REQUIRE_SUCCESS(
1328		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1329
1330		forkee_status_exited(status, exitval_tracee);
1331
1332		DPRINTF("Before exiting of the tracer process\n");
1333		_exit(exitval_tracer);
1334	}
1335	DPRINTF("Wait for the tracer to attach to the tracee\n");
1336	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
1337	DPRINTF("Resume the tracee and let it exit\n");
1338	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
1339
1340	DPRINTF("Detect that tracee is zombie\n");
1341	await_zombie(tracee);
1342
1343	DPRINTF("Assert that there is no status about tracee - "
1344	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
1345	TWAIT_REQUIRE_SUCCESS(
1346	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
1347
1348	DPRINTF("Resume the tracer and let it detect exited tracee\n");
1349	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
1350
1351	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
1352	    TWAIT_FNAME);
1353	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
1354	    tracer);
1355
1356	validate_status_exited(status, exitval_tracer);
1357
1358	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1359	    TWAIT_FNAME);
1360	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
1361	    tracee);
1362
1363	validate_status_exited(status, exitval_tracee);
1364
1365	msg_close(&parent_tracee);
1366	msg_close(&parent_tracer);
1367}
1368#endif
1369
1370ATF_TC(eventmask1);
1371ATF_TC_HEAD(eventmask1, tc)
1372{
1373	atf_tc_set_md_var(tc, "descr",
1374	    "Verify that empty EVENT_MASK is preserved");
1375}
1376
1377ATF_TC_BODY(eventmask1, tc)
1378{
1379	const int exitval = 5;
1380	const int sigval = SIGSTOP;
1381	pid_t child, wpid;
1382#if defined(TWAIT_HAVE_STATUS)
1383	int status;
1384#endif
1385	ptrace_event_t set_event, get_event;
1386	const int len = sizeof(ptrace_event_t);
1387
1388	DPRINTF("Before forking process PID=%d\n", getpid());
1389	SYSCALL_REQUIRE((child = fork()) != -1);
1390	if (child == 0) {
1391		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1392		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1393
1394		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1395		FORKEE_ASSERT(raise(sigval) == 0);
1396
1397		DPRINTF("Before exiting of the child process\n");
1398		_exit(exitval);
1399	}
1400	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1401
1402	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1403	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1404
1405	validate_status_stopped(status, sigval);
1406
1407	set_event.pe_set_event = 0;
1408	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1409	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1410	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1411
1412	DPRINTF("Before resuming the child process where it left off and "
1413	    "without signal to be sent\n");
1414	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1415
1416	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1417	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1418
1419	validate_status_exited(status, exitval);
1420
1421	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1422	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1423}
1424
1425ATF_TC(eventmask2);
1426ATF_TC_HEAD(eventmask2, tc)
1427{
1428	atf_tc_set_md_var(tc, "descr",
1429	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
1430}
1431
1432ATF_TC_BODY(eventmask2, tc)
1433{
1434	const int exitval = 5;
1435	const int sigval = SIGSTOP;
1436	pid_t child, wpid;
1437#if defined(TWAIT_HAVE_STATUS)
1438	int status;
1439#endif
1440	ptrace_event_t set_event, get_event;
1441	const int len = sizeof(ptrace_event_t);
1442
1443	DPRINTF("Before forking process PID=%d\n", getpid());
1444	SYSCALL_REQUIRE((child = fork()) != -1);
1445	if (child == 0) {
1446		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1447		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1448
1449		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1450		FORKEE_ASSERT(raise(sigval) == 0);
1451
1452		DPRINTF("Before exiting of the child process\n");
1453		_exit(exitval);
1454	}
1455	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1456
1457	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1458	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1459
1460	validate_status_stopped(status, sigval);
1461
1462	set_event.pe_set_event = PTRACE_FORK;
1463	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1464	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1465	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1466
1467	DPRINTF("Before resuming the child process where it left off and "
1468	    "without signal to be sent\n");
1469	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1470
1471	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1472	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1473
1474	validate_status_exited(status, exitval);
1475
1476	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1477	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1478}
1479
1480ATF_TC(eventmask3);
1481ATF_TC_HEAD(eventmask3, tc)
1482{
1483	atf_tc_set_md_var(tc, "descr",
1484	    "Verify that PTRACE_VFORK in EVENT_MASK is preserved");
1485}
1486
1487ATF_TC_BODY(eventmask3, tc)
1488{
1489	const int exitval = 5;
1490	const int sigval = SIGSTOP;
1491	pid_t child, wpid;
1492#if defined(TWAIT_HAVE_STATUS)
1493	int status;
1494#endif
1495	ptrace_event_t set_event, get_event;
1496	const int len = sizeof(ptrace_event_t);
1497
1498	DPRINTF("Before forking process PID=%d\n", getpid());
1499	SYSCALL_REQUIRE((child = fork()) != -1);
1500	if (child == 0) {
1501		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1502		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1503
1504		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1505		FORKEE_ASSERT(raise(sigval) == 0);
1506
1507		DPRINTF("Before exiting of the child process\n");
1508		_exit(exitval);
1509	}
1510	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1511
1512	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1513	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1514
1515	validate_status_stopped(status, sigval);
1516
1517	set_event.pe_set_event = PTRACE_VFORK;
1518	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1519	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1520	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1521
1522	DPRINTF("Before resuming the child process where it left off and "
1523	    "without signal to be sent\n");
1524	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1525
1526	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1527	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1528
1529	validate_status_exited(status, exitval);
1530
1531	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1532	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1533}
1534
1535ATF_TC(eventmask4);
1536ATF_TC_HEAD(eventmask4, tc)
1537{
1538	atf_tc_set_md_var(tc, "descr",
1539	    "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved");
1540}
1541
1542ATF_TC_BODY(eventmask4, tc)
1543{
1544	const int exitval = 5;
1545	const int sigval = SIGSTOP;
1546	pid_t child, wpid;
1547#if defined(TWAIT_HAVE_STATUS)
1548	int status;
1549#endif
1550	ptrace_event_t set_event, get_event;
1551	const int len = sizeof(ptrace_event_t);
1552
1553	DPRINTF("Before forking process PID=%d\n", getpid());
1554	SYSCALL_REQUIRE((child = fork()) != -1);
1555	if (child == 0) {
1556		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1557		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1558
1559		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1560		FORKEE_ASSERT(raise(sigval) == 0);
1561
1562		DPRINTF("Before exiting of the child process\n");
1563		_exit(exitval);
1564	}
1565	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1566
1567	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1568	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1569
1570	validate_status_stopped(status, sigval);
1571
1572	set_event.pe_set_event = PTRACE_VFORK_DONE;
1573	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1574	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1575	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1576
1577	DPRINTF("Before resuming the child process where it left off and "
1578	    "without signal to be sent\n");
1579	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1580
1581	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1582	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1583
1584	validate_status_exited(status, exitval);
1585
1586	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1587	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1588}
1589
1590ATF_TC(eventmask5);
1591ATF_TC_HEAD(eventmask5, tc)
1592{
1593	atf_tc_set_md_var(tc, "descr",
1594	    "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved");
1595}
1596
1597ATF_TC_BODY(eventmask5, tc)
1598{
1599	const int exitval = 5;
1600	const int sigval = SIGSTOP;
1601	pid_t child, wpid;
1602#if defined(TWAIT_HAVE_STATUS)
1603	int status;
1604#endif
1605	ptrace_event_t set_event, get_event;
1606	const int len = sizeof(ptrace_event_t);
1607
1608	DPRINTF("Before forking process PID=%d\n", getpid());
1609	SYSCALL_REQUIRE((child = fork()) != -1);
1610	if (child == 0) {
1611		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1612		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1613
1614		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1615		FORKEE_ASSERT(raise(sigval) == 0);
1616
1617		DPRINTF("Before exiting of the child process\n");
1618		_exit(exitval);
1619	}
1620	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1621
1622	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1623	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1624
1625	validate_status_stopped(status, sigval);
1626
1627	set_event.pe_set_event = PTRACE_LWP_CREATE;
1628	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1629	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1630	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1631
1632	DPRINTF("Before resuming the child process where it left off and "
1633	    "without signal to be sent\n");
1634	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1635
1636	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1637	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1638
1639	validate_status_exited(status, exitval);
1640
1641	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1642	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1643}
1644
1645ATF_TC(eventmask6);
1646ATF_TC_HEAD(eventmask6, tc)
1647{
1648	atf_tc_set_md_var(tc, "descr",
1649	    "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved");
1650}
1651
1652ATF_TC_BODY(eventmask6, tc)
1653{
1654	const int exitval = 5;
1655	const int sigval = SIGSTOP;
1656	pid_t child, wpid;
1657#if defined(TWAIT_HAVE_STATUS)
1658	int status;
1659#endif
1660	ptrace_event_t set_event, get_event;
1661	const int len = sizeof(ptrace_event_t);
1662
1663	DPRINTF("Before forking process PID=%d\n", getpid());
1664	SYSCALL_REQUIRE((child = fork()) != -1);
1665	if (child == 0) {
1666		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1667		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1668
1669		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1670		FORKEE_ASSERT(raise(sigval) == 0);
1671
1672		DPRINTF("Before exiting of the child process\n");
1673		_exit(exitval);
1674	}
1675	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1676
1677	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1678	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1679
1680	validate_status_stopped(status, sigval);
1681
1682	set_event.pe_set_event = PTRACE_LWP_EXIT;
1683	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1684	SYSCALL_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1685	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1686
1687	DPRINTF("Before resuming the child process where it left off and "
1688	    "without signal to be sent\n");
1689	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1690
1691	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1692	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1693
1694	validate_status_exited(status, exitval);
1695
1696	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1697	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1698}
1699
1700static void
1701fork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork,
1702          bool trackvforkdone, bool detachchild, bool detachparent)
1703{
1704	const int exitval = 5;
1705	const int exitval2 = 15;
1706	const int sigval = SIGSTOP;
1707	pid_t child, child2 = 0, wpid;
1708#if defined(TWAIT_HAVE_STATUS)
1709	int status;
1710#endif
1711	ptrace_state_t state;
1712	const int slen = sizeof(state);
1713	ptrace_event_t event;
1714	const int elen = sizeof(event);
1715
1716	DPRINTF("Before forking process PID=%d\n", getpid());
1717	SYSCALL_REQUIRE((child = fork()) != -1);
1718	if (child == 0) {
1719		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1720		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1721
1722		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1723		FORKEE_ASSERT(raise(sigval) == 0);
1724
1725		FORKEE_ASSERT((child2 = (fn)()) != -1);
1726
1727		if (child2 == 0)
1728			_exit(exitval2);
1729
1730		FORKEE_REQUIRE_SUCCESS
1731		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1732
1733		forkee_status_exited(status, exitval2);
1734
1735		DPRINTF("Before exiting of the child process\n");
1736		_exit(exitval);
1737	}
1738	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1739
1740	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1741	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1742
1743	validate_status_stopped(status, sigval);
1744
1745	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
1746	        trackfork ? "|PTRACE_FORK" : "",
1747	        trackvfork ? "|PTRACE_VFORK" : "",
1748	        trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
1749	event.pe_set_event = 0;
1750	if (trackfork)
1751		event.pe_set_event |= PTRACE_FORK;
1752	if (trackvfork)
1753		event.pe_set_event |= PTRACE_VFORK;
1754	if (trackvforkdone)
1755		event.pe_set_event |= PTRACE_VFORK_DONE;
1756	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1757
1758	DPRINTF("Before resuming the child process where it left off and "
1759	    "without signal to be sent\n");
1760	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1761
1762#if defined(TWAIT_HAVE_PID)
1763	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
1764		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
1765		        child);
1766		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1767		                      child);
1768
1769		validate_status_stopped(status, SIGTRAP);
1770
1771		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
1772		                       slen) != -1);
1773		if (trackfork && fn == fork) {
1774			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
1775			       PTRACE_FORK);
1776		}
1777		if (trackvfork && fn == vfork) {
1778			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
1779			       PTRACE_VFORK);
1780		}
1781
1782		child2 = state.pe_other_pid;
1783		DPRINTF("Reported ptrace event with forkee %d\n", child2);
1784
1785		DPRINTF("Before calling %s() for the forkee %d of the child "
1786		        "%d\n", TWAIT_FNAME, child2, child);
1787		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1788		    child2);
1789
1790		validate_status_stopped(status, SIGTRAP);
1791
1792		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state,
1793		                       slen) != -1);
1794		if (trackfork && fn == fork) {
1795			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
1796			       PTRACE_FORK);
1797		}
1798		if (trackvfork && fn == vfork) {
1799			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
1800			       PTRACE_VFORK);
1801		}
1802
1803		ATF_REQUIRE_EQ(state.pe_other_pid, child);
1804
1805		DPRINTF("Before resuming the forkee process where it left off "
1806		    "and without signal to be sent\n");
1807		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0)
1808		                != -1);
1809
1810		DPRINTF("Before resuming the child process where it left off "
1811		        "and without signal to be sent\n");
1812		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1813	}
1814#endif
1815
1816	if (trackvforkdone && fn == vfork) {
1817		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
1818		        child);
1819		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1820		                      child);
1821
1822		validate_status_stopped(status, SIGTRAP);
1823
1824		SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state,
1825		                       slen) != -1);
1826		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
1827
1828		child2 = state.pe_other_pid;
1829		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
1830		        child2);
1831
1832		DPRINTF("Before resuming the child process where it left off "
1833		        "and without signal to be sent\n");
1834		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1835	}
1836
1837#if defined(TWAIT_HAVE_PID)
1838	if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) {
1839		DPRINTF("Before calling %s() for the forkee - expected exited"
1840		        "\n", TWAIT_FNAME);
1841		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1842		    child2);
1843
1844		validate_status_exited(status, exitval2);
1845
1846		DPRINTF("Before calling %s() for the forkee - expected no "
1847		        "process\n", TWAIT_FNAME);
1848		TWAIT_REQUIRE_FAILURE(ECHILD,
1849		    wpid = TWAIT_GENERIC(child2, &status, 0));
1850	}
1851#endif
1852
1853	DPRINTF("Before calling %s() for the child - expected stopped "
1854	    "SIGCHLD\n", TWAIT_FNAME);
1855	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1856
1857	validate_status_stopped(status, SIGCHLD);
1858
1859	DPRINTF("Before resuming the child process where it left off and "
1860	    "without signal to be sent\n");
1861	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1862
1863	DPRINTF("Before calling %s() for the child - expected exited\n",
1864	    TWAIT_FNAME);
1865	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1866
1867	validate_status_exited(status, exitval);
1868
1869	DPRINTF("Before calling %s() for the child - expected no process\n",
1870	    TWAIT_FNAME);
1871	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1872}
1873
1874#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent)	\
1875ATF_TC(name);									\
1876ATF_TC_HEAD(name, tc)								\
1877{										\
1878	atf_tc_set_md_var(tc, "descr", descr);					\
1879}										\
1880										\
1881ATF_TC_BODY(name, tc)								\
1882{										\
1883										\
1884	fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent);		\
1885}
1886
1887#define F false
1888#define T true
1889
1890#define F_IF__0(x)
1891#define F_IF__1(x) x
1892#define F_IF__(x,y) F_IF__ ## x (y)
1893#define F_IF_(x,y) F_IF__(x,y)
1894#define F_IF(x,y) F_IF_(x,y)
1895
1896#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit)	\
1897        "Verify " #function "(2) called with 0"					\
1898        F_IF(forkbit,"|PTRACE_FORK")						\
1899        F_IF(vforkbit,"|PTRACE_VFORK")						\
1900        F_IF(vforkdonebit,"|PTRACE_VFORK_DONE")					\
1901        " in EVENT_MASK."							\
1902        F_IF(dchildbit," Detach child in this test.")				\
1903        F_IF(dparentbit," Detach parent in this test.")
1904
1905FORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
1906#if defined(TWAIT_HAVE_PID)
1907FORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F)
1908FORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F)
1909FORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F)
1910#endif
1911FORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F)
1912#if defined(TWAIT_HAVE_PID)
1913FORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F)
1914FORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F)
1915FORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F)
1916#endif
1917
1918FORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F)
1919#if defined(TWAIT_HAVE_PID)
1920FORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F)
1921FORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F)
1922FORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F)
1923#endif
1924FORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F)
1925#if defined(TWAIT_HAVE_PID)
1926FORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F)
1927FORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F)
1928FORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F)
1929#endif
1930
1931
1932
1933
1934ATF_TC(io_read_d1);
1935ATF_TC_HEAD(io_read_d1, tc)
1936{
1937	atf_tc_set_md_var(tc, "descr",
1938	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
1939}
1940
1941ATF_TC_BODY(io_read_d1, tc)
1942{
1943	const int exitval = 5;
1944	const int sigval = SIGSTOP;
1945	pid_t child, wpid;
1946	uint8_t lookup_me = 0;
1947	const uint8_t magic = 0xab;
1948	struct ptrace_io_desc io = {
1949		.piod_op = PIOD_READ_D,
1950		.piod_offs = &lookup_me,
1951		.piod_addr = &lookup_me,
1952		.piod_len = sizeof(lookup_me)
1953	};
1954#if defined(TWAIT_HAVE_STATUS)
1955	int status;
1956#endif
1957
1958	DPRINTF("Before forking process PID=%d\n", getpid());
1959	SYSCALL_REQUIRE((child = fork()) != -1);
1960	if (child == 0) {
1961		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1962		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1963
1964		lookup_me = magic;
1965
1966		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1967		FORKEE_ASSERT(raise(sigval) == 0);
1968
1969		DPRINTF("Before exiting of the child process\n");
1970		_exit(exitval);
1971	}
1972	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1973
1974	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1975	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1976
1977	validate_status_stopped(status, sigval);
1978
1979	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
1980	    child, getpid());
1981	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1982
1983	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
1984	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
1985
1986	DPRINTF("Before resuming the child process where it left off and "
1987	    "without signal to be sent\n");
1988	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1989
1990	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1991	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1992
1993	validate_status_exited(status, exitval);
1994
1995	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1996	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1997}
1998
1999ATF_TC(io_read_d2);
2000ATF_TC_HEAD(io_read_d2, tc)
2001{
2002	atf_tc_set_md_var(tc, "descr",
2003	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
2004}
2005
2006ATF_TC_BODY(io_read_d2, tc)
2007{
2008	const int exitval = 5;
2009	const int sigval = SIGSTOP;
2010	pid_t child, wpid;
2011	uint16_t lookup_me = 0;
2012	const uint16_t magic = 0x1234;
2013	struct ptrace_io_desc io = {
2014		.piod_op = PIOD_READ_D,
2015		.piod_offs = &lookup_me,
2016		.piod_addr = &lookup_me,
2017		.piod_len = sizeof(lookup_me)
2018	};
2019#if defined(TWAIT_HAVE_STATUS)
2020	int status;
2021#endif
2022
2023	DPRINTF("Before forking process PID=%d\n", getpid());
2024	SYSCALL_REQUIRE((child = fork()) != -1);
2025	if (child == 0) {
2026		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2027		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2028
2029		lookup_me = magic;
2030
2031		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2032		FORKEE_ASSERT(raise(sigval) == 0);
2033
2034		DPRINTF("Before exiting of the child process\n");
2035		_exit(exitval);
2036	}
2037	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2038
2039	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2040	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2041
2042	validate_status_stopped(status, sigval);
2043
2044	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2045	    child, getpid());
2046	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2047
2048	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2049	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
2050
2051	DPRINTF("Before resuming the child process where it left off and "
2052	    "without signal to be sent\n");
2053	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2054
2055	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2056	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2057
2058	validate_status_exited(status, exitval);
2059
2060	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2061	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2062}
2063
2064ATF_TC(io_read_d3);
2065ATF_TC_HEAD(io_read_d3, tc)
2066{
2067	atf_tc_set_md_var(tc, "descr",
2068	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
2069}
2070
2071ATF_TC_BODY(io_read_d3, tc)
2072{
2073	const int exitval = 5;
2074	const int sigval = SIGSTOP;
2075	pid_t child, wpid;
2076	uint32_t lookup_me = 0;
2077	const uint32_t magic = 0x1234abcd;
2078	struct ptrace_io_desc io = {
2079		.piod_op = PIOD_READ_D,
2080		.piod_offs = &lookup_me,
2081		.piod_addr = &lookup_me,
2082		.piod_len = sizeof(lookup_me)
2083	};
2084#if defined(TWAIT_HAVE_STATUS)
2085	int status;
2086#endif
2087
2088	DPRINTF("Before forking process PID=%d\n", getpid());
2089	SYSCALL_REQUIRE((child = fork()) != -1);
2090	if (child == 0) {
2091		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2092		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2093
2094		lookup_me = magic;
2095
2096		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2097		FORKEE_ASSERT(raise(sigval) == 0);
2098
2099		DPRINTF("Before exiting of the child process\n");
2100		_exit(exitval);
2101	}
2102	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2103
2104	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2105	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2106
2107	validate_status_stopped(status, sigval);
2108
2109	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2110	    child, getpid());
2111	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2112
2113	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2114	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
2115
2116	DPRINTF("Before resuming the child process where it left off and "
2117	    "without signal to be sent\n");
2118	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2119
2120	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2121	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2122
2123	validate_status_exited(status, exitval);
2124
2125	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2126	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2127}
2128
2129ATF_TC(io_read_d4);
2130ATF_TC_HEAD(io_read_d4, tc)
2131{
2132	atf_tc_set_md_var(tc, "descr",
2133	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
2134}
2135
2136ATF_TC_BODY(io_read_d4, tc)
2137{
2138	const int exitval = 5;
2139	const int sigval = SIGSTOP;
2140	pid_t child, wpid;
2141	uint64_t lookup_me = 0;
2142	const uint64_t magic = 0x1234abcd9876dcfa;
2143	struct ptrace_io_desc io = {
2144		.piod_op = PIOD_READ_D,
2145		.piod_offs = &lookup_me,
2146		.piod_addr = &lookup_me,
2147		.piod_len = sizeof(lookup_me)
2148	};
2149#if defined(TWAIT_HAVE_STATUS)
2150	int status;
2151#endif
2152
2153	DPRINTF("Before forking process PID=%d\n", getpid());
2154	SYSCALL_REQUIRE((child = fork()) != -1);
2155	if (child == 0) {
2156		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2157		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2158
2159		lookup_me = magic;
2160
2161		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2162		FORKEE_ASSERT(raise(sigval) == 0);
2163
2164		DPRINTF("Before exiting of the child process\n");
2165		_exit(exitval);
2166	}
2167	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2168
2169	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2170	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2171
2172	validate_status_stopped(status, sigval);
2173
2174	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2175	    child, getpid());
2176	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2177
2178	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2179	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
2180
2181	DPRINTF("Before resuming the child process where it left off and "
2182	    "without signal to be sent\n");
2183	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2184
2185	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2186	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2187
2188	validate_status_exited(status, exitval);
2189
2190	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2191	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2192}
2193
2194ATF_TC(io_write_d1);
2195ATF_TC_HEAD(io_write_d1, tc)
2196{
2197	atf_tc_set_md_var(tc, "descr",
2198	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
2199}
2200
2201ATF_TC_BODY(io_write_d1, tc)
2202{
2203	const int exitval = 5;
2204	const int sigval = SIGSTOP;
2205	pid_t child, wpid;
2206	uint8_t lookup_me = 0;
2207	const uint8_t magic = 0xab;
2208	struct ptrace_io_desc io = {
2209		.piod_op = PIOD_WRITE_D,
2210		.piod_offs = &lookup_me,
2211		.piod_addr = &lookup_me,
2212		.piod_len = sizeof(lookup_me)
2213	};
2214#if defined(TWAIT_HAVE_STATUS)
2215	int status;
2216#endif
2217
2218	DPRINTF("Before forking process PID=%d\n", getpid());
2219	SYSCALL_REQUIRE((child = fork()) != -1);
2220	if (child == 0) {
2221		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2222		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2223
2224		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2225		FORKEE_ASSERT(raise(sigval) == 0);
2226
2227		FORKEE_ASSERT_EQ(lookup_me, magic);
2228
2229		DPRINTF("Before exiting of the child process\n");
2230		_exit(exitval);
2231	}
2232	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2233
2234	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2235	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2236
2237	validate_status_stopped(status, sigval);
2238
2239	lookup_me = magic;
2240
2241	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2242	    child, getpid());
2243	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2244
2245	DPRINTF("Before resuming the child process where it left off and "
2246	    "without signal to be sent\n");
2247	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2248
2249	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2250	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2251
2252	validate_status_exited(status, exitval);
2253
2254	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2255	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2256}
2257
2258ATF_TC(io_write_d2);
2259ATF_TC_HEAD(io_write_d2, tc)
2260{
2261	atf_tc_set_md_var(tc, "descr",
2262	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
2263}
2264
2265ATF_TC_BODY(io_write_d2, tc)
2266{
2267	const int exitval = 5;
2268	const int sigval = SIGSTOP;
2269	pid_t child, wpid;
2270	uint16_t lookup_me = 0;
2271	const uint16_t magic = 0xab12;
2272	struct ptrace_io_desc io = {
2273		.piod_op = PIOD_WRITE_D,
2274		.piod_offs = &lookup_me,
2275		.piod_addr = &lookup_me,
2276		.piod_len = sizeof(lookup_me)
2277	};
2278#if defined(TWAIT_HAVE_STATUS)
2279	int status;
2280#endif
2281
2282	DPRINTF("Before forking process PID=%d\n", getpid());
2283	SYSCALL_REQUIRE((child = fork()) != -1);
2284	if (child == 0) {
2285		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2286		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2287
2288		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2289		FORKEE_ASSERT(raise(sigval) == 0);
2290
2291		FORKEE_ASSERT_EQ(lookup_me, magic);
2292
2293		DPRINTF("Before exiting of the child process\n");
2294		_exit(exitval);
2295	}
2296	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2297
2298	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2299	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2300
2301	validate_status_stopped(status, sigval);
2302
2303	lookup_me = magic;
2304
2305	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2306	    child, getpid());
2307	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2308
2309	DPRINTF("Before resuming the child process where it left off and "
2310	    "without signal to be sent\n");
2311	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2312
2313	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2314	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2315
2316	validate_status_exited(status, exitval);
2317
2318	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2319	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2320}
2321
2322ATF_TC(io_write_d3);
2323ATF_TC_HEAD(io_write_d3, tc)
2324{
2325	atf_tc_set_md_var(tc, "descr",
2326	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
2327}
2328
2329ATF_TC_BODY(io_write_d3, tc)
2330{
2331	const int exitval = 5;
2332	const int sigval = SIGSTOP;
2333	pid_t child, wpid;
2334	uint32_t lookup_me = 0;
2335	const uint32_t magic = 0xab127643;
2336	struct ptrace_io_desc io = {
2337		.piod_op = PIOD_WRITE_D,
2338		.piod_offs = &lookup_me,
2339		.piod_addr = &lookup_me,
2340		.piod_len = sizeof(lookup_me)
2341	};
2342#if defined(TWAIT_HAVE_STATUS)
2343	int status;
2344#endif
2345
2346	DPRINTF("Before forking process PID=%d\n", getpid());
2347	SYSCALL_REQUIRE((child = fork()) != -1);
2348	if (child == 0) {
2349		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2350		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2351
2352		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2353		FORKEE_ASSERT(raise(sigval) == 0);
2354
2355		FORKEE_ASSERT_EQ(lookup_me, magic);
2356
2357		DPRINTF("Before exiting of the child process\n");
2358		_exit(exitval);
2359	}
2360	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2361
2362	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2363	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2364
2365	validate_status_stopped(status, sigval);
2366
2367	lookup_me = magic;
2368
2369	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2370	    child, getpid());
2371	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2372
2373	DPRINTF("Before resuming the child process where it left off and "
2374	    "without signal to be sent\n");
2375	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2376
2377	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2378	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2379
2380	validate_status_exited(status, exitval);
2381
2382	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2383	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2384}
2385
2386ATF_TC(io_write_d4);
2387ATF_TC_HEAD(io_write_d4, tc)
2388{
2389	atf_tc_set_md_var(tc, "descr",
2390	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
2391}
2392
2393ATF_TC_BODY(io_write_d4, tc)
2394{
2395	const int exitval = 5;
2396	const int sigval = SIGSTOP;
2397	pid_t child, wpid;
2398	uint64_t lookup_me = 0;
2399	const uint64_t magic = 0xab12764376490123;
2400	struct ptrace_io_desc io = {
2401		.piod_op = PIOD_WRITE_D,
2402		.piod_offs = &lookup_me,
2403		.piod_addr = &lookup_me,
2404		.piod_len = sizeof(lookup_me)
2405	};
2406#if defined(TWAIT_HAVE_STATUS)
2407	int status;
2408#endif
2409
2410	DPRINTF("Before forking process PID=%d\n", getpid());
2411	SYSCALL_REQUIRE((child = fork()) != -1);
2412	if (child == 0) {
2413		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2414		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2415
2416		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2417		FORKEE_ASSERT(raise(sigval) == 0);
2418
2419		FORKEE_ASSERT_EQ(lookup_me, magic);
2420
2421		DPRINTF("Before exiting of the child process\n");
2422		_exit(exitval);
2423	}
2424	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2425
2426	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2427	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2428
2429	validate_status_stopped(status, sigval);
2430
2431	lookup_me = magic;
2432
2433	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2434	    child, getpid());
2435	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2436
2437	DPRINTF("Before resuming the child process where it left off and "
2438	    "without signal to be sent\n");
2439	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2440
2441	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2442	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2443
2444	validate_status_exited(status, exitval);
2445
2446	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2447	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2448}
2449
2450ATF_TC(io_read_auxv1);
2451ATF_TC_HEAD(io_read_auxv1, tc)
2452{
2453	atf_tc_set_md_var(tc, "descr",
2454	    "Verify PT_READ_AUXV called for tracee");
2455}
2456
2457ATF_TC_BODY(io_read_auxv1, tc)
2458{
2459	const int exitval = 5;
2460	const int sigval = SIGSTOP;
2461	pid_t child, wpid;
2462#if defined(TWAIT_HAVE_STATUS)
2463	int status;
2464#endif
2465	AuxInfo ai[100], *aip;
2466	struct ptrace_io_desc io = {
2467		.piod_op = PIOD_READ_AUXV,
2468		.piod_offs = 0,
2469		.piod_addr = ai,
2470		.piod_len = sizeof(ai)
2471	};
2472
2473	DPRINTF("Before forking process PID=%d\n", getpid());
2474	SYSCALL_REQUIRE((child = fork()) != -1);
2475	if (child == 0) {
2476		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2477		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2478
2479		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2480		FORKEE_ASSERT(raise(sigval) == 0);
2481
2482		DPRINTF("Before exiting of the child process\n");
2483		_exit(exitval);
2484	}
2485	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2486
2487	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2488	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2489
2490	validate_status_stopped(status, sigval);
2491
2492	DPRINTF("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n",
2493	    child, getpid());
2494	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2495
2496	DPRINTF("Asserting that AUXV length (%zu) is > 0\n", io.piod_len);
2497	ATF_REQUIRE(io.piod_len > 0);
2498
2499	for (aip = ai; aip->a_type != AT_NULL; aip++)
2500		DPRINTF("a_type=%#llx a_v=%#llx\n",
2501		    (long long int)aip->a_type, (long long int)aip->a_v);
2502
2503	DPRINTF("Before resuming the child process where it left off and "
2504	    "without signal to be sent\n");
2505	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2506
2507	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2508	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2509
2510	validate_status_exited(status, exitval);
2511
2512	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2513	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2514}
2515
2516ATF_TC(read_d1);
2517ATF_TC_HEAD(read_d1, tc)
2518{
2519	atf_tc_set_md_var(tc, "descr",
2520	    "Verify PT_READ_D called once");
2521}
2522
2523ATF_TC_BODY(read_d1, tc)
2524{
2525	const int exitval = 5;
2526	const int sigval = SIGSTOP;
2527	pid_t child, wpid;
2528	int lookup_me = 0;
2529	const int magic = (int)random();
2530#if defined(TWAIT_HAVE_STATUS)
2531	int status;
2532#endif
2533
2534	DPRINTF("Before forking process PID=%d\n", getpid());
2535	SYSCALL_REQUIRE((child = fork()) != -1);
2536	if (child == 0) {
2537		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2538		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2539
2540		lookup_me = magic;
2541
2542		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2543		FORKEE_ASSERT(raise(sigval) == 0);
2544
2545		DPRINTF("Before exiting of the child process\n");
2546		_exit(exitval);
2547	}
2548	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2549
2550	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2551	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2552
2553	validate_status_stopped(status, sigval);
2554
2555	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2556	    child, getpid());
2557	errno = 0;
2558	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
2559	SYSCALL_REQUIRE_ERRNO(errno, 0);
2560
2561	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2562	    "got value %#x != expected %#x", lookup_me, magic);
2563
2564	DPRINTF("Before resuming the child process where it left off and "
2565	    "without signal to be sent\n");
2566	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2567
2568	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2569	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2570
2571	validate_status_exited(status, exitval);
2572
2573	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2574	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2575}
2576
2577ATF_TC(read_d2);
2578ATF_TC_HEAD(read_d2, tc)
2579{
2580	atf_tc_set_md_var(tc, "descr",
2581	    "Verify PT_READ_D called twice");
2582}
2583
2584ATF_TC_BODY(read_d2, tc)
2585{
2586	const int exitval = 5;
2587	const int sigval = SIGSTOP;
2588	pid_t child, wpid;
2589	int lookup_me1 = 0;
2590	int lookup_me2 = 0;
2591	const int magic1 = (int)random();
2592	const int magic2 = (int)random();
2593#if defined(TWAIT_HAVE_STATUS)
2594	int status;
2595#endif
2596
2597	DPRINTF("Before forking process PID=%d\n", getpid());
2598	SYSCALL_REQUIRE((child = fork()) != -1);
2599	if (child == 0) {
2600		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2601		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2602
2603		lookup_me1 = magic1;
2604		lookup_me2 = magic2;
2605
2606		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2607		FORKEE_ASSERT(raise(sigval) == 0);
2608
2609		DPRINTF("Before exiting of the child process\n");
2610		_exit(exitval);
2611	}
2612	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2613
2614	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2615	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2616
2617	validate_status_stopped(status, sigval);
2618
2619	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2620	    child, getpid());
2621	errno = 0;
2622	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2623	SYSCALL_REQUIRE_ERRNO(errno, 0);
2624
2625	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2626	    "got value %#x != expected %#x", lookup_me1, magic1);
2627
2628	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2629	    child, getpid());
2630	errno = 0;
2631	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2632	SYSCALL_REQUIRE_ERRNO(errno, 0);
2633
2634	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2635	    "got value %#x != expected %#x", lookup_me2, magic2);
2636
2637	DPRINTF("Before resuming the child process where it left off and "
2638	    "without signal to be sent\n");
2639	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2640
2641	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2642	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2643
2644	validate_status_exited(status, exitval);
2645
2646	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2647	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2648}
2649
2650ATF_TC(read_d3);
2651ATF_TC_HEAD(read_d3, tc)
2652{
2653	atf_tc_set_md_var(tc, "descr",
2654	    "Verify PT_READ_D called three times");
2655}
2656
2657ATF_TC_BODY(read_d3, tc)
2658{
2659	const int exitval = 5;
2660	const int sigval = SIGSTOP;
2661	pid_t child, wpid;
2662	int lookup_me1 = 0;
2663	int lookup_me2 = 0;
2664	int lookup_me3 = 0;
2665	const int magic1 = (int)random();
2666	const int magic2 = (int)random();
2667	const int magic3 = (int)random();
2668#if defined(TWAIT_HAVE_STATUS)
2669	int status;
2670#endif
2671
2672	DPRINTF("Before forking process PID=%d\n", getpid());
2673	SYSCALL_REQUIRE((child = fork()) != -1);
2674	if (child == 0) {
2675		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2676		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2677
2678		lookup_me1 = magic1;
2679		lookup_me2 = magic2;
2680		lookup_me3 = magic3;
2681
2682		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2683		FORKEE_ASSERT(raise(sigval) == 0);
2684
2685		DPRINTF("Before exiting of the child process\n");
2686		_exit(exitval);
2687	}
2688	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2689
2690	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2691	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2692
2693	validate_status_stopped(status, sigval);
2694
2695	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2696	    child, getpid());
2697	errno = 0;
2698	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2699	SYSCALL_REQUIRE_ERRNO(errno, 0);
2700
2701	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2702	    "got value %#x != expected %#x", lookup_me1, magic1);
2703
2704	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2705	    child, getpid());
2706	errno = 0;
2707	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2708	SYSCALL_REQUIRE_ERRNO(errno, 0);
2709
2710	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2711	    "got value %#x != expected %#x", lookup_me2, magic2);
2712
2713	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
2714	    child, getpid());
2715	errno = 0;
2716	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
2717	SYSCALL_REQUIRE_ERRNO(errno, 0);
2718
2719	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
2720	    "got value %#x != expected %#x", lookup_me3, magic3);
2721
2722	DPRINTF("Before resuming the child process where it left off and "
2723	    "without signal to be sent\n");
2724	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2725
2726	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2727	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2728
2729	validate_status_exited(status, exitval);
2730
2731	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2732	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2733}
2734
2735ATF_TC(read_d4);
2736ATF_TC_HEAD(read_d4, tc)
2737{
2738	atf_tc_set_md_var(tc, "descr",
2739	    "Verify PT_READ_D called four times");
2740}
2741
2742ATF_TC_BODY(read_d4, tc)
2743{
2744	const int exitval = 5;
2745	const int sigval = SIGSTOP;
2746	pid_t child, wpid;
2747	int lookup_me1 = 0;
2748	int lookup_me2 = 0;
2749	int lookup_me3 = 0;
2750	int lookup_me4 = 0;
2751	const int magic1 = (int)random();
2752	const int magic2 = (int)random();
2753	const int magic3 = (int)random();
2754	const int magic4 = (int)random();
2755#if defined(TWAIT_HAVE_STATUS)
2756	int status;
2757#endif
2758
2759	DPRINTF("Before forking process PID=%d\n", getpid());
2760	SYSCALL_REQUIRE((child = fork()) != -1);
2761	if (child == 0) {
2762		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2763		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2764
2765		lookup_me1 = magic1;
2766		lookup_me2 = magic2;
2767		lookup_me3 = magic3;
2768		lookup_me4 = magic4;
2769
2770		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2771		FORKEE_ASSERT(raise(sigval) == 0);
2772
2773		DPRINTF("Before exiting of the child process\n");
2774		_exit(exitval);
2775	}
2776	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2777
2778	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2779	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2780
2781	validate_status_stopped(status, sigval);
2782
2783	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2784	    child, getpid());
2785	errno = 0;
2786	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2787	SYSCALL_REQUIRE_ERRNO(errno, 0);
2788
2789	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2790	    "got value %#x != expected %#x", lookup_me1, magic1);
2791
2792	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2793	    child, getpid());
2794	errno = 0;
2795	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2796	SYSCALL_REQUIRE_ERRNO(errno, 0);
2797
2798	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2799	    "got value %#x != expected %#x", lookup_me2, magic2);
2800
2801	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
2802	    child, getpid());
2803	errno = 0;
2804	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
2805	SYSCALL_REQUIRE_ERRNO(errno, 0);
2806
2807	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
2808	    "got value %#x != expected %#x", lookup_me3, magic3);
2809
2810	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
2811	    child, getpid());
2812	errno = 0;
2813	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
2814	SYSCALL_REQUIRE_ERRNO(errno, 0);
2815
2816	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
2817	    "got value %#x != expected %#x", lookup_me4, magic4);
2818
2819	DPRINTF("Before resuming the child process where it left off and "
2820	    "without signal to be sent\n");
2821	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2822
2823	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2824	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2825
2826	validate_status_exited(status, exitval);
2827
2828	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2829	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2830}
2831
2832ATF_TC(write_d1);
2833ATF_TC_HEAD(write_d1, tc)
2834{
2835	atf_tc_set_md_var(tc, "descr",
2836	    "Verify PT_WRITE_D called once");
2837}
2838
2839ATF_TC_BODY(write_d1, tc)
2840{
2841	const int exitval = 5;
2842	const int sigval = SIGSTOP;
2843	pid_t child, wpid;
2844	int lookup_me = 0;
2845	const int magic = (int)random();
2846#if defined(TWAIT_HAVE_STATUS)
2847	int status;
2848#endif
2849
2850	DPRINTF("Before forking process PID=%d\n", getpid());
2851	SYSCALL_REQUIRE((child = fork()) != -1);
2852	if (child == 0) {
2853		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2854		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2855
2856		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2857		FORKEE_ASSERT(raise(sigval) == 0);
2858
2859		FORKEE_ASSERT_EQ(lookup_me, magic);
2860
2861		DPRINTF("Before exiting of the child process\n");
2862		_exit(exitval);
2863	}
2864	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2865
2866	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2867	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2868
2869	validate_status_stopped(status, sigval);
2870
2871	DPRINTF("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2872	    child, getpid());
2873	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
2874
2875	DPRINTF("Before resuming the child process where it left off and "
2876	    "without signal to be sent\n");
2877	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2878
2879	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2880	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2881
2882	validate_status_exited(status, exitval);
2883
2884	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2885	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2886}
2887
2888ATF_TC(write_d2);
2889ATF_TC_HEAD(write_d2, tc)
2890{
2891	atf_tc_set_md_var(tc, "descr",
2892	    "Verify PT_WRITE_D called twice");
2893}
2894
2895ATF_TC_BODY(write_d2, tc)
2896{
2897	const int exitval = 5;
2898	const int sigval = SIGSTOP;
2899	pid_t child, wpid;
2900	int lookup_me1 = 0;
2901	int lookup_me2 = 0;
2902	const int magic1 = (int)random();
2903	const int magic2 = (int)random();
2904#if defined(TWAIT_HAVE_STATUS)
2905	int status;
2906#endif
2907
2908	DPRINTF("Before forking process PID=%d\n", getpid());
2909	SYSCALL_REQUIRE((child = fork()) != -1);
2910	if (child == 0) {
2911		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2912		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2913
2914		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2915		FORKEE_ASSERT(raise(sigval) == 0);
2916
2917		FORKEE_ASSERT_EQ(lookup_me1, magic1);
2918		FORKEE_ASSERT_EQ(lookup_me2, magic2);
2919
2920		DPRINTF("Before exiting of the child process\n");
2921		_exit(exitval);
2922	}
2923	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2924
2925	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2926	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2927
2928	validate_status_stopped(status, sigval);
2929
2930	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
2931	    child, getpid());
2932	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
2933
2934	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
2935	    child, getpid());
2936	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
2937
2938	DPRINTF("Before resuming the child process where it left off and "
2939	    "without signal to be sent\n");
2940	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2941
2942	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2943	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2944
2945	validate_status_exited(status, exitval);
2946
2947	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2948	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2949}
2950
2951ATF_TC(write_d3);
2952ATF_TC_HEAD(write_d3, tc)
2953{
2954	atf_tc_set_md_var(tc, "descr",
2955	    "Verify PT_WRITE_D called three times");
2956}
2957
2958ATF_TC_BODY(write_d3, tc)
2959{
2960	const int exitval = 5;
2961	const int sigval = SIGSTOP;
2962	pid_t child, wpid;
2963	int lookup_me1 = 0;
2964	int lookup_me2 = 0;
2965	int lookup_me3 = 0;
2966	const int magic1 = (int)random();
2967	const int magic2 = (int)random();
2968	const int magic3 = (int)random();
2969#if defined(TWAIT_HAVE_STATUS)
2970	int status;
2971#endif
2972
2973	DPRINTF("Before forking process PID=%d\n", getpid());
2974	SYSCALL_REQUIRE((child = fork()) != -1);
2975	if (child == 0) {
2976		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2977		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2978
2979		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2980		FORKEE_ASSERT(raise(sigval) == 0);
2981
2982		FORKEE_ASSERT_EQ(lookup_me1, magic1);
2983		FORKEE_ASSERT_EQ(lookup_me2, magic2);
2984		FORKEE_ASSERT_EQ(lookup_me3, magic3);
2985
2986		DPRINTF("Before exiting of the child process\n");
2987		_exit(exitval);
2988	}
2989	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2990
2991	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2992	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2993
2994	validate_status_stopped(status, sigval);
2995
2996	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
2997	    child, getpid());
2998	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
2999
3000	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
3001	    child, getpid());
3002	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
3003
3004	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
3005	    child, getpid());
3006	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
3007
3008	DPRINTF("Before resuming the child process where it left off and "
3009	    "without signal to be sent\n");
3010	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3011
3012	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3013	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3014
3015	validate_status_exited(status, exitval);
3016
3017	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3018	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3019}
3020
3021ATF_TC(write_d4);
3022ATF_TC_HEAD(write_d4, tc)
3023{
3024	atf_tc_set_md_var(tc, "descr",
3025	    "Verify PT_WRITE_D called four times");
3026}
3027
3028ATF_TC_BODY(write_d4, tc)
3029{
3030	const int exitval = 5;
3031	const int sigval = SIGSTOP;
3032	pid_t child, wpid;
3033	int lookup_me1 = 0;
3034	int lookup_me2 = 0;
3035	int lookup_me3 = 0;
3036	int lookup_me4 = 0;
3037	const int magic1 = (int)random();
3038	const int magic2 = (int)random();
3039	const int magic3 = (int)random();
3040	const int magic4 = (int)random();
3041#if defined(TWAIT_HAVE_STATUS)
3042	int status;
3043#endif
3044
3045	DPRINTF("Before forking process PID=%d\n", getpid());
3046	SYSCALL_REQUIRE((child = fork()) != -1);
3047	if (child == 0) {
3048		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3049		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3050
3051		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3052		FORKEE_ASSERT(raise(sigval) == 0);
3053
3054		FORKEE_ASSERT_EQ(lookup_me1, magic1);
3055		FORKEE_ASSERT_EQ(lookup_me2, magic2);
3056		FORKEE_ASSERT_EQ(lookup_me3, magic3);
3057		FORKEE_ASSERT_EQ(lookup_me4, magic4);
3058
3059		DPRINTF("Before exiting of the child process\n");
3060		_exit(exitval);
3061	}
3062	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3063
3064	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3065	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3066
3067	validate_status_stopped(status, sigval);
3068
3069	DPRINTF("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
3070	    child, getpid());
3071	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
3072
3073	DPRINTF("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
3074	    child, getpid());
3075	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
3076
3077	DPRINTF("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
3078	    child, getpid());
3079	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
3080
3081	DPRINTF("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
3082	    child, getpid());
3083	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
3084
3085	DPRINTF("Before resuming the child process where it left off and "
3086	    "without signal to be sent\n");
3087	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3088
3089	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3090	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3091
3092	validate_status_exited(status, exitval);
3093
3094	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3095	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3096}
3097
3098ATF_TC(io_read_d_write_d_handshake1);
3099ATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
3100{
3101	atf_tc_set_md_var(tc, "descr",
3102	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
3103}
3104
3105ATF_TC_BODY(io_read_d_write_d_handshake1, tc)
3106{
3107	const int exitval = 5;
3108	const int sigval = SIGSTOP;
3109	pid_t child, wpid;
3110	uint8_t lookup_me_fromtracee = 0;
3111	const uint8_t magic_fromtracee = (uint8_t)random();
3112	uint8_t lookup_me_totracee = 0;
3113	const uint8_t magic_totracee = (uint8_t)random();
3114	struct ptrace_io_desc io_fromtracee = {
3115		.piod_op = PIOD_READ_D,
3116		.piod_offs = &lookup_me_fromtracee,
3117		.piod_addr = &lookup_me_fromtracee,
3118		.piod_len = sizeof(lookup_me_fromtracee)
3119	};
3120	struct ptrace_io_desc io_totracee = {
3121		.piod_op = PIOD_WRITE_D,
3122		.piod_offs = &lookup_me_totracee,
3123		.piod_addr = &lookup_me_totracee,
3124		.piod_len = sizeof(lookup_me_totracee)
3125	};
3126#if defined(TWAIT_HAVE_STATUS)
3127	int status;
3128#endif
3129
3130	DPRINTF("Before forking process PID=%d\n", getpid());
3131	SYSCALL_REQUIRE((child = fork()) != -1);
3132	if (child == 0) {
3133		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3134		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3135
3136		lookup_me_fromtracee = magic_fromtracee;
3137
3138		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3139		FORKEE_ASSERT(raise(sigval) == 0);
3140
3141		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3142
3143		DPRINTF("Before exiting of the child process\n");
3144		_exit(exitval);
3145	}
3146	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3147
3148	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3149	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3150
3151	validate_status_stopped(status, sigval);
3152
3153	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3154	    child, getpid());
3155	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
3156
3157	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3158	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
3159	    magic_fromtracee);
3160
3161	lookup_me_totracee = magic_totracee;
3162
3163	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
3164	    child, getpid());
3165	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
3166
3167	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
3168	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
3169	    magic_totracee);
3170
3171	DPRINTF("Before resuming the child process where it left off and "
3172	    "without signal to be sent\n");
3173	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3174
3175	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3176	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3177
3178	validate_status_exited(status, exitval);
3179
3180	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3181	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3182}
3183
3184ATF_TC(io_read_d_write_d_handshake2);
3185ATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
3186{
3187	atf_tc_set_md_var(tc, "descr",
3188	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
3189}
3190
3191ATF_TC_BODY(io_read_d_write_d_handshake2, tc)
3192{
3193	const int exitval = 5;
3194	const int sigval = SIGSTOP;
3195	pid_t child, wpid;
3196	uint8_t lookup_me_fromtracee = 0;
3197	const uint8_t magic_fromtracee = (uint8_t)random();
3198	uint8_t lookup_me_totracee = 0;
3199	const uint8_t magic_totracee = (uint8_t)random();
3200	struct ptrace_io_desc io_fromtracee = {
3201		.piod_op = PIOD_READ_D,
3202		.piod_offs = &lookup_me_fromtracee,
3203		.piod_addr = &lookup_me_fromtracee,
3204		.piod_len = sizeof(lookup_me_fromtracee)
3205	};
3206	struct ptrace_io_desc io_totracee = {
3207		.piod_op = PIOD_WRITE_D,
3208		.piod_offs = &lookup_me_totracee,
3209		.piod_addr = &lookup_me_totracee,
3210		.piod_len = sizeof(lookup_me_totracee)
3211	};
3212#if defined(TWAIT_HAVE_STATUS)
3213	int status;
3214#endif
3215
3216	DPRINTF("Before forking process PID=%d\n", getpid());
3217	SYSCALL_REQUIRE((child = fork()) != -1);
3218	if (child == 0) {
3219		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3220		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3221
3222		lookup_me_fromtracee = magic_fromtracee;
3223
3224		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3225		FORKEE_ASSERT(raise(sigval) == 0);
3226
3227		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3228
3229		DPRINTF("Before exiting of the child process\n");
3230		_exit(exitval);
3231	}
3232	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3233
3234	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3235	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3236
3237	validate_status_stopped(status, sigval);
3238
3239	lookup_me_totracee = magic_totracee;
3240
3241	DPRINTF("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
3242	    child, getpid());
3243	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
3244
3245	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
3246	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
3247	    magic_totracee);
3248
3249	DPRINTF("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3250	    child, getpid());
3251	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
3252
3253	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3254	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
3255	    magic_fromtracee);
3256
3257	DPRINTF("Before resuming the child process where it left off and "
3258	    "without signal to be sent\n");
3259	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3260
3261	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3262	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3263
3264	validate_status_exited(status, exitval);
3265
3266	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3267	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3268}
3269
3270ATF_TC(read_d_write_d_handshake1);
3271ATF_TC_HEAD(read_d_write_d_handshake1, tc)
3272{
3273	atf_tc_set_md_var(tc, "descr",
3274	    "Verify PT_READ_D with PT_WRITE_D handshake");
3275}
3276
3277ATF_TC_BODY(read_d_write_d_handshake1, tc)
3278{
3279	const int exitval = 5;
3280	const int sigval = SIGSTOP;
3281	pid_t child, wpid;
3282	int lookup_me_fromtracee = 0;
3283	const int magic_fromtracee = (int)random();
3284	int lookup_me_totracee = 0;
3285	const int magic_totracee = (int)random();
3286#if defined(TWAIT_HAVE_STATUS)
3287	int status;
3288#endif
3289
3290	DPRINTF("Before forking process PID=%d\n", getpid());
3291	SYSCALL_REQUIRE((child = fork()) != -1);
3292	if (child == 0) {
3293		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3294		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3295
3296		lookup_me_fromtracee = magic_fromtracee;
3297
3298		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3299		FORKEE_ASSERT(raise(sigval) == 0);
3300
3301		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3302
3303		DPRINTF("Before exiting of the child process\n");
3304		_exit(exitval);
3305	}
3306	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3307
3308	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3309	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3310
3311	validate_status_stopped(status, sigval);
3312
3313	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3314	    child, getpid());
3315	errno = 0;
3316	lookup_me_fromtracee =
3317	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
3318	SYSCALL_REQUIRE_ERRNO(errno, 0);
3319
3320	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3321	    "got value %#x != expected %#x", lookup_me_fromtracee,
3322	    magic_fromtracee);
3323
3324	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
3325	    child, getpid());
3326	ATF_REQUIRE
3327	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
3328	    != -1);
3329
3330	DPRINTF("Before resuming the child process where it left off and "
3331	    "without signal to be sent\n");
3332	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3333
3334	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3335	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3336
3337	validate_status_exited(status, exitval);
3338
3339	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3340	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3341}
3342
3343ATF_TC(read_d_write_d_handshake2);
3344ATF_TC_HEAD(read_d_write_d_handshake2, tc)
3345{
3346	atf_tc_set_md_var(tc, "descr",
3347	    "Verify PT_WRITE_D with PT_READ_D handshake");
3348}
3349
3350ATF_TC_BODY(read_d_write_d_handshake2, tc)
3351{
3352	const int exitval = 5;
3353	const int sigval = SIGSTOP;
3354	pid_t child, wpid;
3355	int lookup_me_fromtracee = 0;
3356	const int magic_fromtracee = (int)random();
3357	int lookup_me_totracee = 0;
3358	const int magic_totracee = (int)random();
3359#if defined(TWAIT_HAVE_STATUS)
3360	int status;
3361#endif
3362
3363	DPRINTF("Before forking process PID=%d\n", getpid());
3364	SYSCALL_REQUIRE((child = fork()) != -1);
3365	if (child == 0) {
3366		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3367		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3368
3369		lookup_me_fromtracee = magic_fromtracee;
3370
3371		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3372		FORKEE_ASSERT(raise(sigval) == 0);
3373
3374		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
3375
3376		DPRINTF("Before exiting of the child process\n");
3377		_exit(exitval);
3378	}
3379	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3380
3381	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3382	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3383
3384	validate_status_stopped(status, sigval);
3385
3386	DPRINTF("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
3387	    child, getpid());
3388	ATF_REQUIRE
3389	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
3390	    != -1);
3391
3392	DPRINTF("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
3393	    child, getpid());
3394	errno = 0;
3395	lookup_me_fromtracee =
3396	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
3397	SYSCALL_REQUIRE_ERRNO(errno, 0);
3398
3399	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
3400	    "got value %#x != expected %#x", lookup_me_fromtracee,
3401	    magic_fromtracee);
3402
3403	DPRINTF("Before resuming the child process where it left off and "
3404	    "without signal to be sent\n");
3405	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3406
3407	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3408	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3409
3410	validate_status_exited(status, exitval);
3411
3412	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3413	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3414}
3415
3416/* These dummy functions are used to be copied with ptrace(2) calls */
3417static int __used
3418dummy_fn1(int a, int b, int c, int d)
3419{
3420
3421	a *= 1;
3422	b += 2;
3423	c -= 3;
3424	d /= 4;
3425
3426	return a + b * c - d;
3427}
3428
3429static int __used
3430dummy_fn2(int a, int b, int c, int d)
3431{
3432
3433	a *= 4;
3434	b += 3;
3435	c -= 2;
3436	d /= 1;
3437
3438	return a + b * c - d;
3439}
3440
3441static int __used
3442dummy_fn3(int a, int b, int c, int d)
3443{
3444
3445	a *= 10;
3446	b += 20;
3447	c -= 30;
3448	d /= 40;
3449
3450	return a + b * c - d;
3451}
3452
3453static int __used
3454dummy_fn4(int a, int b, int c, int d)
3455{
3456
3457	a *= 40;
3458	b += 30;
3459	c -= 20;
3460	d /= 10;
3461
3462	return a + b * c - d;
3463}
3464
3465ATF_TC(io_read_i1);
3466ATF_TC_HEAD(io_read_i1, tc)
3467{
3468	atf_tc_set_md_var(tc, "descr",
3469	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
3470}
3471
3472ATF_TC_BODY(io_read_i1, tc)
3473{
3474	const int exitval = 5;
3475	const int sigval = SIGSTOP;
3476	pid_t child, wpid;
3477	uint8_t lookup_me = 0;
3478	uint8_t magic;
3479	memcpy(&magic, dummy_fn1, sizeof(magic));
3480	struct ptrace_io_desc io = {
3481		.piod_op = PIOD_READ_I,
3482		.piod_offs = dummy_fn1,
3483		.piod_addr = &lookup_me,
3484		.piod_len = sizeof(lookup_me)
3485	};
3486#if defined(TWAIT_HAVE_STATUS)
3487	int status;
3488#endif
3489
3490	DPRINTF("Before forking process PID=%d\n", getpid());
3491	SYSCALL_REQUIRE((child = fork()) != -1);
3492	if (child == 0) {
3493		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3494		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3495
3496		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3497		FORKEE_ASSERT(raise(sigval) == 0);
3498
3499		DPRINTF("Before exiting of the child process\n");
3500		_exit(exitval);
3501	}
3502	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3503
3504	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3505	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3506
3507	validate_status_stopped(status, sigval);
3508
3509	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3510	    child, getpid());
3511	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3512
3513	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3514	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
3515
3516	DPRINTF("Before resuming the child process where it left off and "
3517	    "without signal to be sent\n");
3518	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3519
3520	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3521	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3522
3523	validate_status_exited(status, exitval);
3524
3525	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3526	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3527}
3528
3529ATF_TC(io_read_i2);
3530ATF_TC_HEAD(io_read_i2, tc)
3531{
3532	atf_tc_set_md_var(tc, "descr",
3533	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
3534}
3535
3536ATF_TC_BODY(io_read_i2, tc)
3537{
3538	const int exitval = 5;
3539	const int sigval = SIGSTOP;
3540	pid_t child, wpid;
3541	uint16_t lookup_me = 0;
3542	uint16_t magic;
3543	memcpy(&magic, dummy_fn1, sizeof(magic));
3544	struct ptrace_io_desc io = {
3545		.piod_op = PIOD_READ_I,
3546		.piod_offs = dummy_fn1,
3547		.piod_addr = &lookup_me,
3548		.piod_len = sizeof(lookup_me)
3549	};
3550#if defined(TWAIT_HAVE_STATUS)
3551	int status;
3552#endif
3553
3554	DPRINTF("Before forking process PID=%d\n", getpid());
3555	SYSCALL_REQUIRE((child = fork()) != -1);
3556	if (child == 0) {
3557		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3558		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3559
3560		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3561		FORKEE_ASSERT(raise(sigval) == 0);
3562
3563		DPRINTF("Before exiting of the child process\n");
3564		_exit(exitval);
3565	}
3566	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3567
3568	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3569	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3570
3571	validate_status_stopped(status, sigval);
3572
3573	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3574	    child, getpid());
3575	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3576
3577	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3578	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
3579
3580	DPRINTF("Before resuming the child process where it left off and "
3581	    "without signal to be sent\n");
3582	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3583
3584	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3585	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3586
3587	validate_status_exited(status, exitval);
3588
3589	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3590	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3591}
3592
3593ATF_TC(io_read_i3);
3594ATF_TC_HEAD(io_read_i3, tc)
3595{
3596	atf_tc_set_md_var(tc, "descr",
3597	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
3598}
3599
3600ATF_TC_BODY(io_read_i3, tc)
3601{
3602	const int exitval = 5;
3603	const int sigval = SIGSTOP;
3604	pid_t child, wpid;
3605	uint32_t lookup_me = 0;
3606	uint32_t magic;
3607	memcpy(&magic, dummy_fn1, sizeof(magic));
3608	struct ptrace_io_desc io = {
3609		.piod_op = PIOD_READ_I,
3610		.piod_offs = dummy_fn1,
3611		.piod_addr = &lookup_me,
3612		.piod_len = sizeof(lookup_me)
3613	};
3614#if defined(TWAIT_HAVE_STATUS)
3615	int status;
3616#endif
3617
3618	DPRINTF("Before forking process PID=%d\n", getpid());
3619	SYSCALL_REQUIRE((child = fork()) != -1);
3620	if (child == 0) {
3621		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3622		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3623
3624		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3625		FORKEE_ASSERT(raise(sigval) == 0);
3626
3627		DPRINTF("Before exiting of the child process\n");
3628		_exit(exitval);
3629	}
3630	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3631
3632	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3633	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3634
3635	validate_status_stopped(status, sigval);
3636
3637	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3638	    child, getpid());
3639	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3640
3641	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3642	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
3643
3644	DPRINTF("Before resuming the child process where it left off and "
3645	    "without signal to be sent\n");
3646	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3647
3648	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3649	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3650
3651	validate_status_exited(status, exitval);
3652
3653	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3654	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3655}
3656
3657ATF_TC(io_read_i4);
3658ATF_TC_HEAD(io_read_i4, tc)
3659{
3660	atf_tc_set_md_var(tc, "descr",
3661	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
3662}
3663
3664ATF_TC_BODY(io_read_i4, tc)
3665{
3666	const int exitval = 5;
3667	const int sigval = SIGSTOP;
3668	pid_t child, wpid;
3669	uint64_t lookup_me = 0;
3670	uint64_t magic;
3671	memcpy(&magic, dummy_fn1, sizeof(magic));
3672	struct ptrace_io_desc io = {
3673		.piod_op = PIOD_READ_I,
3674		.piod_offs = dummy_fn1,
3675		.piod_addr = &lookup_me,
3676		.piod_len = sizeof(lookup_me)
3677	};
3678#if defined(TWAIT_HAVE_STATUS)
3679	int status;
3680#endif
3681
3682	DPRINTF("Before forking process PID=%d\n", getpid());
3683	SYSCALL_REQUIRE((child = fork()) != -1);
3684	if (child == 0) {
3685		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3686		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3687
3688		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3689		FORKEE_ASSERT(raise(sigval) == 0);
3690
3691		DPRINTF("Before exiting of the child process\n");
3692		_exit(exitval);
3693	}
3694	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3695
3696	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3697	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3698
3699	validate_status_stopped(status, sigval);
3700
3701	DPRINTF("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3702	    child, getpid());
3703	SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3704
3705	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3706	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
3707
3708	DPRINTF("Before resuming the child process where it left off and "
3709	    "without signal to be sent\n");
3710	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3711
3712	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3713	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3714
3715	validate_status_exited(status, exitval);
3716
3717	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3718	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3719}
3720
3721ATF_TC(read_i1);
3722ATF_TC_HEAD(read_i1, tc)
3723{
3724	atf_tc_set_md_var(tc, "descr",
3725	    "Verify PT_READ_I called once");
3726}
3727
3728ATF_TC_BODY(read_i1, tc)
3729{
3730	const int exitval = 5;
3731	const int sigval = SIGSTOP;
3732	pid_t child, wpid;
3733	int lookup_me = 0;
3734	int magic;
3735	memcpy(&magic, dummy_fn1, sizeof(magic));
3736#if defined(TWAIT_HAVE_STATUS)
3737	int status;
3738#endif
3739
3740	DPRINTF("Before forking process PID=%d\n", getpid());
3741	SYSCALL_REQUIRE((child = fork()) != -1);
3742	if (child == 0) {
3743		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3744		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3745
3746		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3747		FORKEE_ASSERT(raise(sigval) == 0);
3748
3749		DPRINTF("Before exiting of the child process\n");
3750		_exit(exitval);
3751	}
3752	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3753
3754	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3755	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3756
3757	validate_status_stopped(status, sigval);
3758
3759	DPRINTF("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3760	    child, getpid());
3761	errno = 0;
3762	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
3763	SYSCALL_REQUIRE_ERRNO(errno, 0);
3764
3765	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3766	    "got value %#x != expected %#x", lookup_me, magic);
3767
3768	DPRINTF("Before resuming the child process where it left off and "
3769	    "without signal to be sent\n");
3770	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3771
3772	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3773	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3774
3775	validate_status_exited(status, exitval);
3776
3777	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3778	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3779}
3780
3781ATF_TC(read_i2);
3782ATF_TC_HEAD(read_i2, tc)
3783{
3784	atf_tc_set_md_var(tc, "descr",
3785	    "Verify PT_READ_I called twice");
3786}
3787
3788ATF_TC_BODY(read_i2, tc)
3789{
3790	const int exitval = 5;
3791	const int sigval = SIGSTOP;
3792	pid_t child, wpid;
3793	int lookup_me1 = 0;
3794	int lookup_me2 = 0;
3795	int magic1;
3796	int magic2;
3797	memcpy(&magic1, dummy_fn1, sizeof(magic1));
3798	memcpy(&magic2, dummy_fn2, sizeof(magic2));
3799#if defined(TWAIT_HAVE_STATUS)
3800	int status;
3801#endif
3802
3803	DPRINTF("Before forking process PID=%d\n", getpid());
3804	SYSCALL_REQUIRE((child = fork()) != -1);
3805	if (child == 0) {
3806		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3807		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3808
3809		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3810		FORKEE_ASSERT(raise(sigval) == 0);
3811
3812		DPRINTF("Before exiting of the child process\n");
3813		_exit(exitval);
3814	}
3815	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3816
3817	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3818	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3819
3820	validate_status_stopped(status, sigval);
3821
3822	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3823	    child, getpid());
3824	errno = 0;
3825	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3826	SYSCALL_REQUIRE_ERRNO(errno, 0);
3827
3828	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3829	    "got value %#x != expected %#x", lookup_me1, magic1);
3830
3831	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3832	    child, getpid());
3833	errno = 0;
3834	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3835	SYSCALL_REQUIRE_ERRNO(errno, 0);
3836
3837	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3838	    "got value %#x != expected %#x", lookup_me2, magic2);
3839
3840	DPRINTF("Before resuming the child process where it left off and "
3841	    "without signal to be sent\n");
3842	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3843
3844	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3845	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3846
3847	validate_status_exited(status, exitval);
3848
3849	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3850	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3851}
3852
3853ATF_TC(read_i3);
3854ATF_TC_HEAD(read_i3, tc)
3855{
3856	atf_tc_set_md_var(tc, "descr",
3857	    "Verify PT_READ_I called three times");
3858}
3859
3860ATF_TC_BODY(read_i3, tc)
3861{
3862	const int exitval = 5;
3863	const int sigval = SIGSTOP;
3864	pid_t child, wpid;
3865	int lookup_me1 = 0;
3866	int lookup_me2 = 0;
3867	int lookup_me3 = 0;
3868	int magic1;
3869	int magic2;
3870	int magic3;
3871	memcpy(&magic1, dummy_fn1, sizeof(magic1));
3872	memcpy(&magic2, dummy_fn2, sizeof(magic2));
3873	memcpy(&magic3, dummy_fn3, sizeof(magic3));
3874#if defined(TWAIT_HAVE_STATUS)
3875	int status;
3876#endif
3877
3878	DPRINTF("Before forking process PID=%d\n", getpid());
3879	SYSCALL_REQUIRE((child = fork()) != -1);
3880	if (child == 0) {
3881		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3882		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3883
3884		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3885		FORKEE_ASSERT(raise(sigval) == 0);
3886
3887		DPRINTF("Before exiting of the child process\n");
3888		_exit(exitval);
3889	}
3890	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3891
3892	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3893	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3894
3895	validate_status_stopped(status, sigval);
3896
3897	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3898	    child, getpid());
3899	errno = 0;
3900	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3901	SYSCALL_REQUIRE_ERRNO(errno, 0);
3902
3903	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3904	    "got value %#x != expected %#x", lookup_me1, magic1);
3905
3906	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3907	    child, getpid());
3908	errno = 0;
3909	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3910	SYSCALL_REQUIRE_ERRNO(errno, 0);
3911
3912	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3913	    "got value %#x != expected %#x", lookup_me2, magic2);
3914
3915	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
3916	    child, getpid());
3917	errno = 0;
3918	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
3919	SYSCALL_REQUIRE_ERRNO(errno, 0);
3920
3921	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
3922	    "got value %#x != expected %#x", lookup_me3, magic3);
3923
3924	DPRINTF("Before resuming the child process where it left off and "
3925	    "without signal to be sent\n");
3926	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3927
3928	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3929	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3930
3931	validate_status_exited(status, exitval);
3932
3933	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3934	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3935}
3936
3937ATF_TC(read_i4);
3938ATF_TC_HEAD(read_i4, tc)
3939{
3940	atf_tc_set_md_var(tc, "descr",
3941	    "Verify PT_READ_I called four times");
3942}
3943
3944ATF_TC_BODY(read_i4, tc)
3945{
3946	const int exitval = 5;
3947	const int sigval = SIGSTOP;
3948	pid_t child, wpid;
3949	int lookup_me1 = 0;
3950	int lookup_me2 = 0;
3951	int lookup_me3 = 0;
3952	int lookup_me4 = 0;
3953	int magic1;
3954	int magic2;
3955	int magic3;
3956	int magic4;
3957	memcpy(&magic1, dummy_fn1, sizeof(magic1));
3958	memcpy(&magic2, dummy_fn2, sizeof(magic2));
3959	memcpy(&magic3, dummy_fn3, sizeof(magic3));
3960	memcpy(&magic4, dummy_fn4, sizeof(magic4));
3961#if defined(TWAIT_HAVE_STATUS)
3962	int status;
3963#endif
3964
3965	DPRINTF("Before forking process PID=%d\n", getpid());
3966	SYSCALL_REQUIRE((child = fork()) != -1);
3967	if (child == 0) {
3968		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3969		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3970
3971		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3972		FORKEE_ASSERT(raise(sigval) == 0);
3973
3974		DPRINTF("Before exiting of the child process\n");
3975		_exit(exitval);
3976	}
3977	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3978
3979	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3980	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3981
3982	validate_status_stopped(status, sigval);
3983
3984	DPRINTF("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3985	    child, getpid());
3986	errno = 0;
3987	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3988	SYSCALL_REQUIRE_ERRNO(errno, 0);
3989
3990	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3991	    "got value %#x != expected %#x", lookup_me1, magic1);
3992
3993	DPRINTF("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3994	    child, getpid());
3995	errno = 0;
3996	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3997	SYSCALL_REQUIRE_ERRNO(errno, 0);
3998
3999	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
4000	    "got value %#x != expected %#x", lookup_me2, magic2);
4001
4002	DPRINTF("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
4003	    child, getpid());
4004	errno = 0;
4005	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
4006	SYSCALL_REQUIRE_ERRNO(errno, 0);
4007
4008	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
4009	    "got value %#x != expected %#x", lookup_me3, magic3);
4010
4011	DPRINTF("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
4012	    child, getpid());
4013	errno = 0;
4014	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
4015	SYSCALL_REQUIRE_ERRNO(errno, 0);
4016
4017	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
4018	    "got value %#x != expected %#x", lookup_me4, magic4);
4019
4020	DPRINTF("Before resuming the child process where it left off and "
4021	    "without signal to be sent\n");
4022	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4023
4024	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4025	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4026
4027	validate_status_exited(status, exitval);
4028
4029	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4030	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4031}
4032
4033#if defined(HAVE_GPREGS)
4034ATF_TC(regs1);
4035ATF_TC_HEAD(regs1, tc)
4036{
4037	atf_tc_set_md_var(tc, "descr",
4038	    "Verify plain PT_GETREGS call without further steps");
4039}
4040
4041ATF_TC_BODY(regs1, tc)
4042{
4043	const int exitval = 5;
4044	const int sigval = SIGSTOP;
4045	pid_t child, wpid;
4046#if defined(TWAIT_HAVE_STATUS)
4047	int status;
4048#endif
4049	struct reg r;
4050
4051	DPRINTF("Before forking process PID=%d\n", getpid());
4052	SYSCALL_REQUIRE((child = fork()) != -1);
4053	if (child == 0) {
4054		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4055		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4056
4057		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4058		FORKEE_ASSERT(raise(sigval) == 0);
4059
4060		DPRINTF("Before exiting of the child process\n");
4061		_exit(exitval);
4062	}
4063	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4064
4065	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4066	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4067
4068	validate_status_stopped(status, sigval);
4069
4070	DPRINTF("Call GETREGS for the child process\n");
4071	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4072
4073	DPRINTF("Before resuming the child process where it left off and "
4074	    "without signal to be sent\n");
4075	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4076
4077	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4078	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4079
4080	validate_status_exited(status, exitval);
4081
4082	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4083	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4084}
4085#endif
4086
4087#if defined(HAVE_GPREGS)
4088ATF_TC(regs2);
4089ATF_TC_HEAD(regs2, tc)
4090{
4091	atf_tc_set_md_var(tc, "descr",
4092	    "Verify plain PT_GETREGS call and retrieve PC");
4093}
4094
4095ATF_TC_BODY(regs2, tc)
4096{
4097	const int exitval = 5;
4098	const int sigval = SIGSTOP;
4099	pid_t child, wpid;
4100#if defined(TWAIT_HAVE_STATUS)
4101	int status;
4102#endif
4103	struct reg r;
4104
4105	DPRINTF("Before forking process PID=%d\n", getpid());
4106	SYSCALL_REQUIRE((child = fork()) != -1);
4107	if (child == 0) {
4108		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4109		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4110
4111		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4112		FORKEE_ASSERT(raise(sigval) == 0);
4113
4114		DPRINTF("Before exiting of the child process\n");
4115		_exit(exitval);
4116	}
4117	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4118
4119	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4120	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4121
4122	validate_status_stopped(status, sigval);
4123
4124	DPRINTF("Call GETREGS for the child process\n");
4125	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4126
4127	DPRINTF("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
4128
4129	DPRINTF("Before resuming the child process where it left off and "
4130	    "without signal to be sent\n");
4131	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4132
4133	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4134	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4135
4136	validate_status_exited(status, exitval);
4137
4138	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4139	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4140}
4141#endif
4142
4143#if defined(HAVE_GPREGS)
4144ATF_TC(regs3);
4145ATF_TC_HEAD(regs3, tc)
4146{
4147	atf_tc_set_md_var(tc, "descr",
4148	    "Verify plain PT_GETREGS call and retrieve SP");
4149}
4150
4151ATF_TC_BODY(regs3, tc)
4152{
4153	const int exitval = 5;
4154	const int sigval = SIGSTOP;
4155	pid_t child, wpid;
4156#if defined(TWAIT_HAVE_STATUS)
4157	int status;
4158#endif
4159	struct reg r;
4160
4161	DPRINTF("Before forking process PID=%d\n", getpid());
4162	SYSCALL_REQUIRE((child = fork()) != -1);
4163	if (child == 0) {
4164		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4165		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4166
4167		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4168		FORKEE_ASSERT(raise(sigval) == 0);
4169
4170		DPRINTF("Before exiting of the child process\n");
4171		_exit(exitval);
4172	}
4173	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4174
4175	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4176	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4177
4178	validate_status_stopped(status, sigval);
4179
4180	DPRINTF("Call GETREGS for the child process\n");
4181	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4182
4183	DPRINTF("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
4184
4185	DPRINTF("Before resuming the child process where it left off and "
4186	    "without signal to be sent\n");
4187	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4188
4189	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4190	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4191
4192	validate_status_exited(status, exitval);
4193
4194	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4195	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4196}
4197#endif
4198
4199#if defined(HAVE_GPREGS)
4200ATF_TC(regs4);
4201ATF_TC_HEAD(regs4, tc)
4202{
4203	atf_tc_set_md_var(tc, "descr",
4204	    "Verify plain PT_GETREGS call and retrieve INTRV");
4205}
4206
4207ATF_TC_BODY(regs4, tc)
4208{
4209	const int exitval = 5;
4210	const int sigval = SIGSTOP;
4211	pid_t child, wpid;
4212#if defined(TWAIT_HAVE_STATUS)
4213	int status;
4214#endif
4215	struct reg r;
4216
4217	DPRINTF("Before forking process PID=%d\n", getpid());
4218	SYSCALL_REQUIRE((child = fork()) != -1);
4219	if (child == 0) {
4220		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4221		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4222
4223		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4224		FORKEE_ASSERT(raise(sigval) == 0);
4225
4226		DPRINTF("Before exiting of the child process\n");
4227		_exit(exitval);
4228	}
4229	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4230
4231	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4232	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4233
4234	validate_status_stopped(status, sigval);
4235
4236	DPRINTF("Call GETREGS for the child process\n");
4237	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4238
4239	DPRINTF("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
4240
4241	DPRINTF("Before resuming the child process where it left off and "
4242	    "without signal to be sent\n");
4243	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4244
4245	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4246	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4247
4248	validate_status_exited(status, exitval);
4249
4250	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4251	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4252}
4253#endif
4254
4255#if defined(HAVE_GPREGS)
4256ATF_TC(regs5);
4257ATF_TC_HEAD(regs5, tc)
4258{
4259	atf_tc_set_md_var(tc, "descr",
4260	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
4261}
4262
4263ATF_TC_BODY(regs5, tc)
4264{
4265	const int exitval = 5;
4266	const int sigval = SIGSTOP;
4267	pid_t child, wpid;
4268#if defined(TWAIT_HAVE_STATUS)
4269	int status;
4270#endif
4271	struct reg r;
4272
4273	DPRINTF("Before forking process PID=%d\n", getpid());
4274	SYSCALL_REQUIRE((child = fork()) != -1);
4275	if (child == 0) {
4276		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4277		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4278
4279		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4280		FORKEE_ASSERT(raise(sigval) == 0);
4281
4282		DPRINTF("Before exiting of the child process\n");
4283		_exit(exitval);
4284	}
4285	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4286
4287	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4288	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4289
4290	validate_status_stopped(status, sigval);
4291
4292	DPRINTF("Call GETREGS for the child process\n");
4293	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4294
4295	DPRINTF("Call SETREGS for the child process (without changed regs)\n");
4296	SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
4297
4298	DPRINTF("Before resuming the child process where it left off and "
4299	    "without signal to be sent\n");
4300	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4301
4302	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4303	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4304
4305	validate_status_exited(status, exitval);
4306
4307	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4308	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4309}
4310#endif
4311
4312#if defined(HAVE_FPREGS)
4313ATF_TC(fpregs1);
4314ATF_TC_HEAD(fpregs1, tc)
4315{
4316	atf_tc_set_md_var(tc, "descr",
4317	    "Verify plain PT_GETFPREGS call without further steps");
4318}
4319
4320ATF_TC_BODY(fpregs1, tc)
4321{
4322	const int exitval = 5;
4323	const int sigval = SIGSTOP;
4324	pid_t child, wpid;
4325#if defined(TWAIT_HAVE_STATUS)
4326	int status;
4327#endif
4328	struct fpreg r;
4329
4330	DPRINTF("Before forking process PID=%d\n", getpid());
4331	SYSCALL_REQUIRE((child = fork()) != -1);
4332	if (child == 0) {
4333		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4334		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4335
4336		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4337		FORKEE_ASSERT(raise(sigval) == 0);
4338
4339		DPRINTF("Before exiting of the child process\n");
4340		_exit(exitval);
4341	}
4342	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4343
4344	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4345	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4346
4347	validate_status_stopped(status, sigval);
4348
4349	DPRINTF("Call GETFPREGS for the child process\n");
4350	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
4351
4352	DPRINTF("Before resuming the child process where it left off and "
4353	    "without signal to be sent\n");
4354	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4355
4356	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4357	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4358
4359	validate_status_exited(status, exitval);
4360
4361	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4362	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4363}
4364#endif
4365
4366#if defined(HAVE_FPREGS)
4367ATF_TC(fpregs2);
4368ATF_TC_HEAD(fpregs2, tc)
4369{
4370	atf_tc_set_md_var(tc, "descr",
4371	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
4372	    "regs");
4373}
4374
4375ATF_TC_BODY(fpregs2, tc)
4376{
4377	const int exitval = 5;
4378	const int sigval = SIGSTOP;
4379	pid_t child, wpid;
4380#if defined(TWAIT_HAVE_STATUS)
4381	int status;
4382#endif
4383	struct fpreg r;
4384
4385	DPRINTF("Before forking process PID=%d\n", getpid());
4386	SYSCALL_REQUIRE((child = fork()) != -1);
4387	if (child == 0) {
4388		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4389		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4390
4391		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4392		FORKEE_ASSERT(raise(sigval) == 0);
4393
4394		DPRINTF("Before exiting of the child process\n");
4395		_exit(exitval);
4396	}
4397	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4398
4399	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4400	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4401
4402	validate_status_stopped(status, sigval);
4403
4404	DPRINTF("Call GETFPREGS for the child process\n");
4405	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
4406
4407	DPRINTF("Call SETFPREGS for the child (without changed regs)\n");
4408	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
4409
4410	DPRINTF("Before resuming the child process where it left off and "
4411	    "without signal to be sent\n");
4412	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4413
4414	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4415	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4416
4417	validate_status_exited(status, exitval);
4418
4419	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4420	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4421}
4422#endif
4423
4424#if defined(PT_STEP)
4425static void
4426ptrace_step(int N, int setstep)
4427{
4428	const int exitval = 5;
4429	const int sigval = SIGSTOP;
4430	pid_t child, wpid;
4431#if defined(TWAIT_HAVE_STATUS)
4432	int status;
4433#endif
4434	int happy;
4435
4436#if defined(__arm__)
4437	/* PT_STEP not supported on arm 32-bit */
4438	atf_tc_expect_fail("PR kern/52119");
4439#endif
4440
4441	DPRINTF("Before forking process PID=%d\n", getpid());
4442	SYSCALL_REQUIRE((child = fork()) != -1);
4443	if (child == 0) {
4444		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4445		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4446
4447		happy = check_happy(999);
4448
4449		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4450		FORKEE_ASSERT(raise(sigval) == 0);
4451
4452		FORKEE_ASSERT_EQ(happy, check_happy(999));
4453
4454		DPRINTF("Before exiting of the child process\n");
4455		_exit(exitval);
4456	}
4457	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4458
4459	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4460	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4461
4462	validate_status_stopped(status, sigval);
4463
4464	while (N --> 0) {
4465		if (setstep) {
4466			DPRINTF("Before resuming the child process where it "
4467			    "left off and without signal to be sent (use "
4468			    "PT_SETSTEP and PT_CONTINUE)\n");
4469			SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1);
4470			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
4471			    != -1);
4472		} else {
4473			DPRINTF("Before resuming the child process where it "
4474			    "left off and without signal to be sent (use "
4475			    "PT_STEP)\n");
4476			SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0)
4477			    != -1);
4478		}
4479
4480		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4481		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4482		    child);
4483
4484		validate_status_stopped(status, SIGTRAP);
4485
4486		if (setstep) {
4487			SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1);
4488		}
4489	}
4490
4491	DPRINTF("Before resuming the child process where it left off and "
4492	    "without signal to be sent\n");
4493	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4494
4495	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4496	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4497
4498	validate_status_exited(status, exitval);
4499
4500	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4501	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4502}
4503#endif
4504
4505#if defined(PT_STEP)
4506ATF_TC(step1);
4507ATF_TC_HEAD(step1, tc)
4508{
4509	atf_tc_set_md_var(tc, "descr",
4510	    "Verify single PT_STEP call");
4511}
4512
4513ATF_TC_BODY(step1, tc)
4514{
4515	ptrace_step(1, 0);
4516}
4517#endif
4518
4519#if defined(PT_STEP)
4520ATF_TC(step2);
4521ATF_TC_HEAD(step2, tc)
4522{
4523	atf_tc_set_md_var(tc, "descr",
4524	    "Verify PT_STEP called twice");
4525}
4526
4527ATF_TC_BODY(step2, tc)
4528{
4529	ptrace_step(2, 0);
4530}
4531#endif
4532
4533#if defined(PT_STEP)
4534ATF_TC(step3);
4535ATF_TC_HEAD(step3, tc)
4536{
4537	atf_tc_set_md_var(tc, "descr",
4538	    "Verify PT_STEP called three times");
4539}
4540
4541ATF_TC_BODY(step3, tc)
4542{
4543	ptrace_step(3, 0);
4544}
4545#endif
4546
4547#if defined(PT_STEP)
4548ATF_TC(step4);
4549ATF_TC_HEAD(step4, tc)
4550{
4551	atf_tc_set_md_var(tc, "descr",
4552	    "Verify PT_STEP called four times");
4553}
4554
4555ATF_TC_BODY(step4, tc)
4556{
4557	ptrace_step(4, 0);
4558}
4559#endif
4560
4561#if defined(PT_STEP)
4562ATF_TC(setstep1);
4563ATF_TC_HEAD(setstep1, tc)
4564{
4565	atf_tc_set_md_var(tc, "descr",
4566	    "Verify single PT_SETSTEP call");
4567}
4568
4569ATF_TC_BODY(setstep1, tc)
4570{
4571	ptrace_step(1, 1);
4572}
4573#endif
4574
4575#if defined(PT_STEP)
4576ATF_TC(setstep2);
4577ATF_TC_HEAD(setstep2, tc)
4578{
4579	atf_tc_set_md_var(tc, "descr",
4580	    "Verify PT_SETSTEP called twice");
4581}
4582
4583ATF_TC_BODY(setstep2, tc)
4584{
4585	ptrace_step(2, 1);
4586}
4587#endif
4588
4589#if defined(PT_STEP)
4590ATF_TC(setstep3);
4591ATF_TC_HEAD(setstep3, tc)
4592{
4593	atf_tc_set_md_var(tc, "descr",
4594	    "Verify PT_SETSTEP called three times");
4595}
4596
4597ATF_TC_BODY(setstep3, tc)
4598{
4599	ptrace_step(3, 1);
4600}
4601#endif
4602
4603#if defined(PT_STEP)
4604ATF_TC(setstep4);
4605ATF_TC_HEAD(setstep4, tc)
4606{
4607	atf_tc_set_md_var(tc, "descr",
4608	    "Verify PT_SETSTEP called four times");
4609}
4610
4611ATF_TC_BODY(setstep4, tc)
4612{
4613	ptrace_step(4, 1);
4614}
4615#endif
4616
4617ATF_TC(kill1);
4618ATF_TC_HEAD(kill1, tc)
4619{
4620	atf_tc_set_md_var(tc, "descr",
4621	    "Verify that PT_CONTINUE with SIGKILL terminates child");
4622}
4623
4624ATF_TC_BODY(kill1, tc)
4625{
4626	const int sigval = SIGSTOP, sigsent = SIGKILL;
4627	pid_t child, wpid;
4628#if defined(TWAIT_HAVE_STATUS)
4629	int status;
4630#endif
4631
4632	DPRINTF("Before forking process PID=%d\n", getpid());
4633	SYSCALL_REQUIRE((child = fork()) != -1);
4634	if (child == 0) {
4635		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4636		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4637
4638		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4639		FORKEE_ASSERT(raise(sigval) == 0);
4640
4641		/* NOTREACHED */
4642		FORKEE_ASSERTX(0 &&
4643		    "Child should be terminated by a signal from its parent");
4644	}
4645	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4646
4647	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4648	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4649
4650	validate_status_stopped(status, sigval);
4651
4652	DPRINTF("Before resuming the child process where it left off and "
4653	    "without signal to be sent\n");
4654	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
4655
4656	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4657	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4658
4659	validate_status_signaled(status, sigsent, 0);
4660
4661	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4662	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4663}
4664
4665ATF_TC(kill2);
4666ATF_TC_HEAD(kill2, tc)
4667{
4668	atf_tc_set_md_var(tc, "descr",
4669	    "Verify that PT_KILL terminates child");
4670}
4671
4672ATF_TC_BODY(kill2, tc)
4673{
4674	const int sigval = SIGSTOP;
4675	pid_t child, wpid;
4676#if defined(TWAIT_HAVE_STATUS)
4677	int status;
4678#endif
4679
4680	DPRINTF("Before forking process PID=%d\n", getpid());
4681	SYSCALL_REQUIRE((child = fork()) != -1);
4682	if (child == 0) {
4683		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4684		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4685
4686		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4687		FORKEE_ASSERT(raise(sigval) == 0);
4688
4689		/* NOTREACHED */
4690		FORKEE_ASSERTX(0 &&
4691		    "Child should be terminated by a signal from its parent");
4692	}
4693	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4694
4695	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4696	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4697
4698	validate_status_stopped(status, sigval);
4699
4700	DPRINTF("Before resuming the child process where it left off and "
4701	    "without signal to be sent\n");
4702	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
4703
4704	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4705	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4706
4707	validate_status_signaled(status, SIGKILL, 0);
4708
4709	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4710	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4711}
4712
4713ATF_TC(lwpinfo1);
4714ATF_TC_HEAD(lwpinfo1, tc)
4715{
4716	atf_tc_set_md_var(tc, "descr",
4717	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
4718}
4719
4720ATF_TC_BODY(lwpinfo1, tc)
4721{
4722	const int exitval = 5;
4723	const int sigval = SIGSTOP;
4724	pid_t child, wpid;
4725#if defined(TWAIT_HAVE_STATUS)
4726	int status;
4727#endif
4728	struct ptrace_lwpinfo info = {0, 0};
4729
4730	DPRINTF("Before forking process PID=%d\n", getpid());
4731	SYSCALL_REQUIRE((child = fork()) != -1);
4732	if (child == 0) {
4733		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4734		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4735
4736		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4737		FORKEE_ASSERT(raise(sigval) == 0);
4738
4739		DPRINTF("Before exiting of the child process\n");
4740		_exit(exitval);
4741	}
4742	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4743
4744	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4745	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4746
4747	validate_status_stopped(status, sigval);
4748
4749	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4750	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
4751
4752	DPRINTF("Assert that there exists a thread\n");
4753	ATF_REQUIRE(info.pl_lwpid > 0);
4754
4755	DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
4756	    info.pl_lwpid);
4757	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
4758	    "Received event %d != expected event %d",
4759	    info.pl_event, PL_EVENT_SIGNAL);
4760
4761	DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4762	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
4763
4764	DPRINTF("Assert that there are no more lwp threads in child\n");
4765	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
4766
4767	DPRINTF("Before resuming the child process where it left off and "
4768	    "without signal to be sent\n");
4769	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4770
4771	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4772	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4773
4774	validate_status_exited(status, exitval);
4775
4776	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4777	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4778}
4779
4780#if defined(TWAIT_HAVE_PID)
4781ATF_TC(lwpinfo2);
4782ATF_TC_HEAD(lwpinfo2, tc)
4783{
4784	atf_tc_set_md_var(tc, "descr",
4785	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
4786	    "tracer)");
4787}
4788
4789ATF_TC_BODY(lwpinfo2, tc)
4790{
4791	struct msg_fds parent_tracee, parent_tracer;
4792	const int exitval_tracee = 5;
4793	const int exitval_tracer = 10;
4794	pid_t tracee, tracer, wpid;
4795	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4796#if defined(TWAIT_HAVE_STATUS)
4797	int status;
4798#endif
4799	struct ptrace_lwpinfo info = {0, 0};
4800
4801	DPRINTF("Spawn tracee\n");
4802	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
4803	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
4804	tracee = atf_utils_fork();
4805	if (tracee == 0) {
4806
4807		/* Wait for message from the parent */
4808		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
4809		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
4810
4811		_exit(exitval_tracee);
4812	}
4813	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
4814
4815	DPRINTF("Spawn debugger\n");
4816	tracer = atf_utils_fork();
4817	if (tracer == 0) {
4818		/* No IPC to communicate with the child */
4819		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
4820		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4821
4822		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4823		FORKEE_REQUIRE_SUCCESS(
4824		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4825
4826		forkee_status_stopped(status, SIGSTOP);
4827
4828		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4829		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
4830		    != -1);
4831
4832		DPRINTF("Assert that there exists a thread\n");
4833		FORKEE_ASSERTX(info.pl_lwpid > 0);
4834
4835		DPRINTF("Assert that lwp thread %d received event "
4836		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
4837		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
4838
4839		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
4840		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
4841		    != -1);
4842
4843		DPRINTF("Assert that there are no more lwp threads in child\n");
4844		FORKEE_ASSERTX(info.pl_lwpid == 0);
4845
4846		/* Resume tracee with PT_CONTINUE */
4847		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4848
4849		/* Inform parent that tracer has attached to tracee */
4850		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
4851		/* Wait for parent */
4852		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
4853
4854		/* Wait for tracee and assert that it exited */
4855		FORKEE_REQUIRE_SUCCESS(
4856		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4857
4858		forkee_status_exited(status, exitval_tracee);
4859
4860		DPRINTF("Before exiting of the tracer process\n");
4861		_exit(exitval_tracer);
4862	}
4863
4864	DPRINTF("Wait for the tracer to attach to the tracee\n");
4865	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
4866
4867	DPRINTF("Resume the tracee and let it exit\n");
4868	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
4869
4870	DPRINTF("Detect that tracee is zombie\n");
4871	await_zombie(tracee);
4872
4873	DPRINTF("Assert that there is no status about tracee - "
4874	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4875	TWAIT_REQUIRE_SUCCESS(
4876	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4877
4878	DPRINTF("Resume the tracer and let it detect exited tracee\n");
4879	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
4880
4881	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
4882	    TWAIT_FNAME);
4883	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
4884	    tracer);
4885
4886	validate_status_exited(status, exitval_tracer);
4887
4888	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4889	    TWAIT_FNAME);
4890	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4891	    tracee);
4892
4893	validate_status_exited(status, exitval_tracee);
4894
4895	msg_close(&parent_tracer);
4896	msg_close(&parent_tracee);
4897}
4898#endif
4899
4900ATF_TC(siginfo1);
4901ATF_TC_HEAD(siginfo1, tc)
4902{
4903	atf_tc_set_md_var(tc, "descr",
4904	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
4905}
4906
4907ATF_TC_BODY(siginfo1, tc)
4908{
4909	const int exitval = 5;
4910	const int sigval = SIGTRAP;
4911	pid_t child, wpid;
4912#if defined(TWAIT_HAVE_STATUS)
4913	int status;
4914#endif
4915	struct ptrace_siginfo info;
4916	memset(&info, 0, sizeof(info));
4917
4918	DPRINTF("Before forking process PID=%d\n", getpid());
4919	SYSCALL_REQUIRE((child = fork()) != -1);
4920	if (child == 0) {
4921		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4922		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4923
4924		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4925		FORKEE_ASSERT(raise(sigval) == 0);
4926
4927		DPRINTF("Before exiting of the child process\n");
4928		_exit(exitval);
4929	}
4930	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4931
4932	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4933	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4934
4935	validate_status_stopped(status, sigval);
4936
4937	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4938	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4939
4940	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4941	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4942	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4943	    info.psi_siginfo.si_errno);
4944
4945	DPRINTF("Before resuming the child process where it left off and "
4946	    "without signal to be sent\n");
4947	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4948
4949	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4950	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4951
4952	validate_status_exited(status, exitval);
4953
4954	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4955	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4956}
4957
4958ATF_TC(siginfo2);
4959ATF_TC_HEAD(siginfo2, tc)
4960{
4961	atf_tc_set_md_var(tc, "descr",
4962	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
4963	    "modification of SIGINT from tracee");
4964}
4965
4966static int siginfo2_caught = 0;
4967
4968static void
4969siginfo2_sighandler(int sig)
4970{
4971	FORKEE_ASSERT_EQ(sig, SIGINT);
4972
4973	++siginfo2_caught;
4974}
4975
4976ATF_TC_BODY(siginfo2, tc)
4977{
4978	const int exitval = 5;
4979	const int sigval = SIGINT;
4980	pid_t child, wpid;
4981	struct sigaction sa;
4982#if defined(TWAIT_HAVE_STATUS)
4983	int status;
4984#endif
4985	struct ptrace_siginfo info;
4986	memset(&info, 0, sizeof(info));
4987
4988	DPRINTF("Before forking process PID=%d\n", getpid());
4989	SYSCALL_REQUIRE((child = fork()) != -1);
4990	if (child == 0) {
4991		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4992		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4993
4994		sa.sa_handler = siginfo2_sighandler;
4995		sa.sa_flags = SA_SIGINFO;
4996		sigemptyset(&sa.sa_mask);
4997
4998		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
4999
5000		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5001		FORKEE_ASSERT(raise(sigval) == 0);
5002
5003		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
5004
5005		DPRINTF("Before exiting of the child process\n");
5006		_exit(exitval);
5007	}
5008	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5009
5010	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5011	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5012
5013	validate_status_stopped(status, sigval);
5014
5015	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5016	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5017
5018	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5019	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5020	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5021	    info.psi_siginfo.si_errno);
5022
5023	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
5024	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
5025
5026	DPRINTF("Before resuming the child process where it left off and "
5027	    "without signal to be sent\n");
5028	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
5029
5030	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5031	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5032
5033	validate_status_exited(status, exitval);
5034
5035	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5036	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5037}
5038
5039ATF_TC(siginfo3);
5040ATF_TC_HEAD(siginfo3, tc)
5041{
5042	atf_tc_set_md_var(tc, "descr",
5043	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
5044	    "setting signal to new value");
5045}
5046
5047static int siginfo3_caught = 0;
5048
5049static void
5050siginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
5051{
5052	FORKEE_ASSERT_EQ(sig, SIGTRAP);
5053
5054	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
5055	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
5056
5057	++siginfo3_caught;
5058}
5059
5060ATF_TC_BODY(siginfo3, tc)
5061{
5062	const int exitval = 5;
5063	const int sigval = SIGINT;
5064	const int sigfaked = SIGTRAP;
5065	const int sicodefaked = TRAP_BRKPT;
5066	pid_t child, wpid;
5067	struct sigaction sa;
5068#if defined(TWAIT_HAVE_STATUS)
5069	int status;
5070#endif
5071	struct ptrace_siginfo info;
5072	memset(&info, 0, sizeof(info));
5073
5074	DPRINTF("Before forking process PID=%d\n", getpid());
5075	SYSCALL_REQUIRE((child = fork()) != -1);
5076	if (child == 0) {
5077		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5078		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5079
5080		sa.sa_sigaction = siginfo3_sigaction;
5081		sa.sa_flags = SA_SIGINFO;
5082		sigemptyset(&sa.sa_mask);
5083
5084		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
5085
5086		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5087		FORKEE_ASSERT(raise(sigval) == 0);
5088
5089		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
5090
5091		DPRINTF("Before exiting of the child process\n");
5092		_exit(exitval);
5093	}
5094	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5095
5096	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5097	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5098
5099	validate_status_stopped(status, sigval);
5100
5101	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5102	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5103
5104	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5105	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5106	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5107	    info.psi_siginfo.si_errno);
5108
5109	DPRINTF("Before setting new faked signal to signo=%d si_code=%d\n",
5110	    sigfaked, sicodefaked);
5111	info.psi_siginfo.si_signo = sigfaked;
5112	info.psi_siginfo.si_code = sicodefaked;
5113
5114	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
5115	SYSCALL_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
5116
5117	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5118	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5119
5120	DPRINTF("Before checking siginfo_t\n");
5121	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
5122	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
5123
5124	DPRINTF("Before resuming the child process where it left off and "
5125	    "without signal to be sent\n");
5126	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
5127
5128	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5129	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5130
5131	validate_status_exited(status, exitval);
5132
5133	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5134	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5135}
5136
5137ATF_TC(siginfo4);
5138ATF_TC_HEAD(siginfo4, tc)
5139{
5140	atf_tc_set_md_var(tc, "descr",
5141	    "Detect SIGTRAP TRAP_EXEC from tracee");
5142}
5143
5144ATF_TC_BODY(siginfo4, tc)
5145{
5146	const int sigval = SIGTRAP;
5147	pid_t child, wpid;
5148#if defined(TWAIT_HAVE_STATUS)
5149	int status;
5150#endif
5151
5152	struct ptrace_siginfo info;
5153	memset(&info, 0, sizeof(info));
5154
5155	DPRINTF("Before forking process PID=%d\n", getpid());
5156	SYSCALL_REQUIRE((child = fork()) != -1);
5157	if (child == 0) {
5158		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5159		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5160
5161		DPRINTF("Before calling execve(2) from child\n");
5162		execlp("/bin/echo", "/bin/echo", NULL);
5163
5164		FORKEE_ASSERT(0 && "Not reached");
5165	}
5166	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5167
5168	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5169	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5170
5171	validate_status_stopped(status, sigval);
5172
5173	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5174	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5175
5176	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5177	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5178	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5179	    info.psi_siginfo.si_errno);
5180
5181	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5182	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
5183
5184	DPRINTF("Before resuming the child process where it left off and "
5185	    "without signal to be sent\n");
5186	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5187
5188	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5189	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5190
5191	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5192	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5193}
5194
5195#if defined(TWAIT_HAVE_PID)
5196ATF_TC(siginfo5);
5197ATF_TC_HEAD(siginfo5, tc)
5198{
5199	atf_tc_set_md_var(tc, "descr",
5200	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
5201	    "set to PTRACE_FORK and reports correct signal information");
5202}
5203
5204ATF_TC_BODY(siginfo5, tc)
5205{
5206	const int exitval = 5;
5207	const int exitval2 = 15;
5208	const int sigval = SIGSTOP;
5209	pid_t child, child2, wpid;
5210#if defined(TWAIT_HAVE_STATUS)
5211	int status;
5212#endif
5213	ptrace_state_t state;
5214	const int slen = sizeof(state);
5215	ptrace_event_t event;
5216	const int elen = sizeof(event);
5217	struct ptrace_siginfo info;
5218
5219	memset(&info, 0, sizeof(info));
5220
5221	DPRINTF("Before forking process PID=%d\n", getpid());
5222	SYSCALL_REQUIRE((child = fork()) != -1);
5223	if (child == 0) {
5224		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5225		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5226
5227		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5228		FORKEE_ASSERT(raise(sigval) == 0);
5229
5230		FORKEE_ASSERT((child2 = fork()) != -1);
5231
5232		if (child2 == 0)
5233			_exit(exitval2);
5234
5235		FORKEE_REQUIRE_SUCCESS
5236		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
5237
5238		forkee_status_exited(status, exitval2);
5239
5240		DPRINTF("Before exiting of the child process\n");
5241		_exit(exitval);
5242	}
5243	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5244
5245	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5246	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5247
5248	validate_status_stopped(status, sigval);
5249
5250	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5251	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5252
5253	DPRINTF("Before checking siginfo_t\n");
5254	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5255	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5256
5257	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
5258	event.pe_set_event = PTRACE_FORK;
5259	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5260
5261	DPRINTF("Before resuming the child process where it left off and "
5262	    "without signal to be sent\n");
5263        DPRINTF("We expect two SIGTRAP events, for child %d (TRAP_CHLD, "
5264               "pe_report_event=PTRACE_FORK, state.pe_other_pid=child2) and "
5265               "for child2 (TRAP_CHLD, pe_report_event=PTRACE_FORK, "
5266                "state.pe_other_pid=child)\n", child);
5267	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5268
5269	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
5270	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5271
5272	validate_status_stopped(status, SIGTRAP);
5273
5274	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5275	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5276
5277	DPRINTF("Before checking siginfo_t\n");
5278	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5279	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
5280
5281	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5282	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
5283
5284	child2 = state.pe_other_pid;
5285	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
5286
5287	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
5288	    TWAIT_FNAME, child2, child);
5289	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5290	    child2);
5291
5292	validate_status_stopped(status, SIGTRAP);
5293
5294	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5295	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5296
5297	DPRINTF("Before checking siginfo_t\n");
5298	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5299	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
5300
5301	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
5302	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
5303	ATF_REQUIRE_EQ(state.pe_other_pid, child);
5304
5305	DPRINTF("Before resuming the forkee process where it left off and "
5306	    "without signal to be sent\n");
5307	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
5308
5309	DPRINTF("Before resuming the child process where it left off and "
5310	    "without signal to be sent\n");
5311	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5312
5313	DPRINTF("Before calling %s() for the forkee - expected exited\n",
5314	    TWAIT_FNAME);
5315	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
5316	    child2);
5317
5318	validate_status_exited(status, exitval2);
5319
5320	DPRINTF("Before calling %s() for the forkee - expected no process\n",
5321	    TWAIT_FNAME);
5322	TWAIT_REQUIRE_FAILURE(ECHILD,
5323	    wpid = TWAIT_GENERIC(child2, &status, 0));
5324
5325	DPRINTF("Before calling %s() for the child - expected stopped "
5326	    "SIGCHLD\n", TWAIT_FNAME);
5327	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5328
5329	validate_status_stopped(status, SIGCHLD);
5330
5331	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5332	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5333
5334	DPRINTF("Before checking siginfo_t\n");
5335	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
5336	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
5337
5338	DPRINTF("Before resuming the child process where it left off and "
5339	    "without signal to be sent\n");
5340	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5341
5342	DPRINTF("Before calling %s() for the child - expected exited\n",
5343	    TWAIT_FNAME);
5344	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5345
5346	validate_status_exited(status, exitval);
5347
5348	DPRINTF("Before calling %s() for the child - expected no process\n",
5349	    TWAIT_FNAME);
5350	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5351}
5352#endif
5353
5354#if defined(PT_STEP)
5355ATF_TC(siginfo6);
5356ATF_TC_HEAD(siginfo6, tc)
5357{
5358	atf_tc_set_md_var(tc, "descr",
5359	    "Verify single PT_STEP call with signal information check");
5360}
5361
5362ATF_TC_BODY(siginfo6, tc)
5363{
5364	const int exitval = 5;
5365	const int sigval = SIGSTOP;
5366	pid_t child, wpid;
5367#if defined(TWAIT_HAVE_STATUS)
5368	int status;
5369#endif
5370	int happy;
5371	struct ptrace_siginfo info;
5372
5373#if defined(__arm__)
5374	/* PT_STEP not supported on arm 32-bit */
5375	atf_tc_expect_fail("PR kern/52119");
5376#endif
5377
5378	memset(&info, 0, sizeof(info));
5379
5380	DPRINTF("Before forking process PID=%d\n", getpid());
5381	SYSCALL_REQUIRE((child = fork()) != -1);
5382	if (child == 0) {
5383		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5384		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5385
5386		happy = check_happy(100);
5387
5388		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5389		FORKEE_ASSERT(raise(sigval) == 0);
5390
5391		FORKEE_ASSERT_EQ(happy, check_happy(100));
5392
5393		DPRINTF("Before exiting of the child process\n");
5394		_exit(exitval);
5395	}
5396	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5397
5398	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5399	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5400
5401	validate_status_stopped(status, sigval);
5402
5403	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5404	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5405
5406	DPRINTF("Before checking siginfo_t\n");
5407	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5408	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5409
5410	DPRINTF("Before resuming the child process where it left off and "
5411	    "without signal to be sent (use PT_STEP)\n");
5412	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
5413
5414	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5415	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5416
5417	validate_status_stopped(status, SIGTRAP);
5418
5419	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5420	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5421
5422	DPRINTF("Before checking siginfo_t\n");
5423	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
5424	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
5425
5426	DPRINTF("Before resuming the child process where it left off and "
5427	    "without signal to be sent\n");
5428	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5429
5430	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5431	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5432
5433	validate_status_exited(status, exitval);
5434
5435	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5436	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5437}
5438#endif
5439
5440volatile lwpid_t the_lwp_id = 0;
5441
5442static void
5443lwp_main_func(void *arg)
5444{
5445	the_lwp_id = _lwp_self();
5446	_lwp_exit();
5447}
5448
5449ATF_TC(lwp_create1);
5450ATF_TC_HEAD(lwp_create1, tc)
5451{
5452	atf_tc_set_md_var(tc, "descr",
5453	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
5454	    "EVENT_MASK set to PTRACE_LWP_CREATE");
5455}
5456
5457ATF_TC_BODY(lwp_create1, tc)
5458{
5459	const int exitval = 5;
5460	const int sigval = SIGSTOP;
5461	pid_t child, wpid;
5462#if defined(TWAIT_HAVE_STATUS)
5463	int status;
5464#endif
5465	ptrace_state_t state;
5466	const int slen = sizeof(state);
5467	ptrace_event_t event;
5468	const int elen = sizeof(event);
5469	ucontext_t uc;
5470	lwpid_t lid;
5471	static const size_t ssize = 16*1024;
5472	void *stack;
5473
5474	DPRINTF("Before forking process PID=%d\n", getpid());
5475	SYSCALL_REQUIRE((child = fork()) != -1);
5476	if (child == 0) {
5477		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5478		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5479
5480		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5481		FORKEE_ASSERT(raise(sigval) == 0);
5482
5483		DPRINTF("Before allocating memory for stack in child\n");
5484		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5485
5486		DPRINTF("Before making context for new lwp in child\n");
5487		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5488
5489		DPRINTF("Before creating new in child\n");
5490		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5491
5492		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5493		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5494
5495		DPRINTF("Before verifying that reported %d and running lid %d "
5496		    "are the same\n", lid, the_lwp_id);
5497		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5498
5499		DPRINTF("Before exiting of the child process\n");
5500		_exit(exitval);
5501	}
5502	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5503
5504	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5505	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5506
5507	validate_status_stopped(status, sigval);
5508
5509	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
5510	event.pe_set_event = PTRACE_LWP_CREATE;
5511	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5512
5513	DPRINTF("Before resuming the child process where it left off and "
5514	    "without signal to be sent\n");
5515	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5516
5517	DPRINTF("Before calling %s() for the child - expected stopped "
5518	    "SIGTRAP\n", TWAIT_FNAME);
5519	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5520
5521	validate_status_stopped(status, SIGTRAP);
5522
5523	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5524
5525	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
5526
5527	lid = state.pe_lwp;
5528	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
5529
5530	DPRINTF("Before resuming the child process where it left off and "
5531	    "without signal to be sent\n");
5532	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5533
5534	DPRINTF("Before calling %s() for the child - expected exited\n",
5535	    TWAIT_FNAME);
5536	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5537
5538	validate_status_exited(status, exitval);
5539
5540	DPRINTF("Before calling %s() for the child - expected no process\n",
5541	    TWAIT_FNAME);
5542	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5543}
5544
5545ATF_TC(lwp_exit1);
5546ATF_TC_HEAD(lwp_exit1, tc)
5547{
5548	atf_tc_set_md_var(tc, "descr",
5549	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
5550	    "EVENT_MASK set to PTRACE_LWP_EXIT");
5551}
5552
5553ATF_TC_BODY(lwp_exit1, tc)
5554{
5555	const int exitval = 5;
5556	const int sigval = SIGSTOP;
5557	pid_t child, wpid;
5558#if defined(TWAIT_HAVE_STATUS)
5559	int status;
5560#endif
5561	ptrace_state_t state;
5562	const int slen = sizeof(state);
5563	ptrace_event_t event;
5564	const int elen = sizeof(event);
5565	ucontext_t uc;
5566	lwpid_t lid;
5567	static const size_t ssize = 16*1024;
5568	void *stack;
5569
5570	DPRINTF("Before forking process PID=%d\n", getpid());
5571	SYSCALL_REQUIRE((child = fork()) != -1);
5572	if (child == 0) {
5573		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5574		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5575
5576		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5577		FORKEE_ASSERT(raise(sigval) == 0);
5578
5579		DPRINTF("Before allocating memory for stack in child\n");
5580		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
5581
5582		DPRINTF("Before making context for new lwp in child\n");
5583		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
5584
5585		DPRINTF("Before creating new in child\n");
5586		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
5587
5588		DPRINTF("Before waiting for lwp %d to exit\n", lid);
5589		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
5590
5591		DPRINTF("Before verifying that reported %d and running lid %d "
5592		    "are the same\n", lid, the_lwp_id);
5593		FORKEE_ASSERT_EQ(lid, the_lwp_id);
5594
5595		DPRINTF("Before exiting of the child process\n");
5596		_exit(exitval);
5597	}
5598	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5599
5600	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5601	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5602
5603	validate_status_stopped(status, sigval);
5604
5605	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
5606	event.pe_set_event = PTRACE_LWP_EXIT;
5607	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
5608
5609	DPRINTF("Before resuming the child process where it left off and "
5610	    "without signal to be sent\n");
5611	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5612
5613	DPRINTF("Before calling %s() for the child - expected stopped "
5614	    "SIGTRAP\n", TWAIT_FNAME);
5615	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5616
5617	validate_status_stopped(status, SIGTRAP);
5618
5619	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
5620
5621	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
5622
5623	lid = state.pe_lwp;
5624	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
5625
5626	DPRINTF("Before resuming the child process where it left off and "
5627	    "without signal to be sent\n");
5628	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5629
5630	DPRINTF("Before calling %s() for the child - expected exited\n",
5631	    TWAIT_FNAME);
5632	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5633
5634	validate_status_exited(status, exitval);
5635
5636	DPRINTF("Before calling %s() for the child - expected no process\n",
5637	    TWAIT_FNAME);
5638	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5639}
5640
5641ATF_TC(signal1);
5642ATF_TC_HEAD(signal1, tc)
5643{
5644	atf_tc_set_md_var(tc, "descr",
5645	    "Verify that masking single unrelated signal does not stop tracer "
5646	    "from catching other signals");
5647}
5648
5649ATF_TC_BODY(signal1, tc)
5650{
5651	const int exitval = 5;
5652	const int sigval = SIGSTOP;
5653	const int sigmasked = SIGTRAP;
5654	const int signotmasked = SIGINT;
5655	pid_t child, wpid;
5656#if defined(TWAIT_HAVE_STATUS)
5657	int status;
5658#endif
5659	sigset_t intmask;
5660
5661	DPRINTF("Before forking process PID=%d\n", getpid());
5662	SYSCALL_REQUIRE((child = fork()) != -1);
5663	if (child == 0) {
5664		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5665		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5666
5667		sigemptyset(&intmask);
5668		sigaddset(&intmask, sigmasked);
5669		sigprocmask(SIG_BLOCK, &intmask, NULL);
5670
5671		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5672		FORKEE_ASSERT(raise(sigval) == 0);
5673
5674		DPRINTF("Before raising %s from child\n",
5675		    strsignal(signotmasked));
5676		FORKEE_ASSERT(raise(signotmasked) == 0);
5677
5678		DPRINTF("Before exiting of the child process\n");
5679		_exit(exitval);
5680	}
5681	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5682
5683	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5684	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5685
5686	validate_status_stopped(status, sigval);
5687
5688	DPRINTF("Before resuming the child process where it left off and "
5689	    "without signal to be sent\n");
5690	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5691
5692	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5693	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5694
5695	validate_status_stopped(status, signotmasked);
5696
5697	DPRINTF("Before resuming the child process where it left off and "
5698	    "without signal to be sent\n");
5699	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5700
5701	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5702	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5703
5704	validate_status_exited(status, exitval);
5705
5706	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5707	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5708}
5709
5710ATF_TC(signal2);
5711ATF_TC_HEAD(signal2, tc)
5712{
5713	atf_tc_set_md_var(tc, "descr",
5714	    "Verify that masking SIGTRAP in tracee stops tracer from "
5715	    "catching this raised signal");
5716}
5717
5718ATF_TC_BODY(signal2, tc)
5719{
5720	const int exitval = 5;
5721	const int sigval = SIGSTOP;
5722	const int sigmasked = SIGTRAP;
5723	pid_t child, wpid;
5724#if defined(TWAIT_HAVE_STATUS)
5725	int status;
5726#endif
5727	sigset_t intmask;
5728
5729	DPRINTF("Before forking process PID=%d\n", getpid());
5730	SYSCALL_REQUIRE((child = fork()) != -1);
5731	if (child == 0) {
5732		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5733		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5734
5735		sigemptyset(&intmask);
5736		sigaddset(&intmask, sigmasked);
5737		sigprocmask(SIG_BLOCK, &intmask, NULL);
5738
5739		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5740		FORKEE_ASSERT(raise(sigval) == 0);
5741
5742		DPRINTF("Before raising %s breakpoint from child\n",
5743		    strsignal(sigmasked));
5744		FORKEE_ASSERT(raise(sigmasked) == 0);
5745
5746		DPRINTF("Before exiting of the child process\n");
5747		_exit(exitval);
5748	}
5749	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5750
5751	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5752	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5753
5754	validate_status_stopped(status, sigval);
5755
5756	DPRINTF("Before resuming the child process where it left off and "
5757	    "without signal to be sent\n");
5758	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5759
5760	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5761	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5762
5763	validate_status_exited(status, exitval);
5764
5765	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5766	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5767}
5768
5769ATF_TC(signal3);
5770ATF_TC_HEAD(signal3, tc)
5771{
5772	atf_tc_set_md_var(tc, "timeout", "5");
5773	atf_tc_set_md_var(tc, "descr",
5774	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5775	    "catching software breakpoints");
5776}
5777
5778ATF_TC_BODY(signal3, tc)
5779{
5780	const int exitval = 5;
5781	const int sigval = SIGSTOP;
5782	const int sigmasked = SIGTRAP;
5783	pid_t child, wpid;
5784#if defined(TWAIT_HAVE_STATUS)
5785	int status;
5786#endif
5787	sigset_t intmask;
5788
5789	atf_tc_expect_fail("PR kern/51918");
5790
5791	// This test breaks now on some ports, temporarily disable it
5792	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
5793
5794#if defined(__sparc__)
5795	atf_tc_expect_timeout("PR kern/52167");
5796
5797	// timeout wins, failure still valid
5798	// atf_tc_expect_fail("PR kern/51918");
5799#endif
5800
5801	DPRINTF("Before forking process PID=%d\n", getpid());
5802	SYSCALL_REQUIRE((child = fork()) != -1);
5803	if (child == 0) {
5804		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5805		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5806
5807		sigemptyset(&intmask);
5808		sigaddset(&intmask, sigmasked);
5809		sigprocmask(SIG_BLOCK, &intmask, NULL);
5810
5811		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5812		FORKEE_ASSERT(raise(sigval) == 0);
5813
5814		DPRINTF("Before raising software breakpoint from child\n");
5815
5816#ifdef PTRACE_BREAKPOINT_ASM
5817		PTRACE_BREAKPOINT_ASM;
5818#else
5819		/* port me */
5820#endif
5821
5822		DPRINTF("Before exiting of the child process\n");
5823		_exit(exitval);
5824	}
5825	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5826
5827	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5828	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5829
5830	validate_status_stopped(status, sigval);
5831
5832	DPRINTF("Before resuming the child process where it left off and "
5833	    "without signal to be sent\n");
5834	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5835
5836	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5837	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5838
5839	validate_status_stopped(status, sigmasked);
5840
5841	DPRINTF("Before resuming the child process where it left off and "
5842	    "without signal to be sent\n");
5843	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5844
5845	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5846	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5847
5848	validate_status_exited(status, exitval);
5849
5850	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5851	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5852}
5853
5854#if defined(PT_STEP)
5855ATF_TC(signal4);
5856ATF_TC_HEAD(signal4, tc)
5857{
5858	atf_tc_set_md_var(tc, "descr",
5859	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5860	    "catching single step trap");
5861}
5862
5863ATF_TC_BODY(signal4, tc)
5864{
5865	const int exitval = 5;
5866	const int sigval = SIGSTOP;
5867	const int sigmasked = SIGTRAP;
5868	pid_t child, wpid;
5869#if defined(TWAIT_HAVE_STATUS)
5870	int status;
5871#endif
5872	sigset_t intmask;
5873	int happy;
5874
5875#if defined(__arm__)
5876	/* PT_STEP not supported on arm 32-bit */
5877	atf_tc_expect_fail("PR kern/51918 PR kern/52119");
5878#endif
5879
5880	DPRINTF("Before forking process PID=%d\n", getpid());
5881	SYSCALL_REQUIRE((child = fork()) != -1);
5882	if (child == 0) {
5883		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5884		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5885
5886		happy = check_happy(100);
5887
5888		sigemptyset(&intmask);
5889		sigaddset(&intmask, sigmasked);
5890		sigprocmask(SIG_BLOCK, &intmask, NULL);
5891
5892		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5893		FORKEE_ASSERT(raise(sigval) == 0);
5894
5895		FORKEE_ASSERT_EQ(happy, check_happy(100));
5896
5897		DPRINTF("Before exiting of the child process\n");
5898		_exit(exitval);
5899	}
5900	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5901
5902	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5903	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5904
5905	validate_status_stopped(status, sigval);
5906
5907	DPRINTF("Before resuming the child process where it left off and "
5908	    "without signal to be sent\n");
5909	SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
5910
5911	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5912	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5913
5914	validate_status_stopped(status, sigmasked);
5915
5916	DPRINTF("Before resuming the child process where it left off and "
5917	    "without signal to be sent\n");
5918	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5919
5920	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5921	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5922
5923	validate_status_exited(status, exitval);
5924
5925	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5926	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5927}
5928#endif
5929
5930ATF_TC(signal5);
5931ATF_TC_HEAD(signal5, tc)
5932{
5933	atf_tc_set_md_var(tc, "descr",
5934	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
5935	    "catching exec() breakpoint");
5936}
5937
5938ATF_TC_BODY(signal5, tc)
5939{
5940	const int exitval = 5;
5941	const int sigval = SIGSTOP;
5942	const int sigmasked = SIGTRAP;
5943	pid_t child, wpid;
5944#if defined(TWAIT_HAVE_STATUS)
5945	int status;
5946#endif
5947	sigset_t intmask;
5948
5949	atf_tc_expect_fail("wrong signal");
5950
5951	DPRINTF("Before forking process PID=%d\n", getpid());
5952	SYSCALL_REQUIRE((child = fork()) != -1);
5953	if (child == 0) {
5954		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5955		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5956
5957		sigemptyset(&intmask);
5958		sigaddset(&intmask, sigmasked);
5959		sigprocmask(SIG_BLOCK, &intmask, NULL);
5960
5961		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5962		FORKEE_ASSERT(raise(sigval) == 0);
5963
5964		DPRINTF("Before calling execve(2) from child\n");
5965		execlp("/bin/echo", "/bin/echo", NULL);
5966
5967		DPRINTF("Before exiting of the child process\n");
5968		_exit(exitval);
5969	}
5970	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5971
5972	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5973	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5974
5975	validate_status_stopped(status, sigval);
5976
5977	DPRINTF("Before resuming the child process where it left off and "
5978	    "without signal to be sent\n");
5979	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5980
5981	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5982	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5983
5984	validate_status_stopped(status, sigmasked);
5985
5986	DPRINTF("Before resuming the child process where it left off and "
5987	    "without signal to be sent\n");
5988	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5989
5990	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5991	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5992
5993	validate_status_exited(status, exitval);
5994
5995	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5996	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5997}
5998
5999#if defined(TWAIT_HAVE_PID)
6000ATF_TC(signal6);
6001ATF_TC_HEAD(signal6, tc)
6002{
6003	atf_tc_set_md_var(tc, "timeout", "5");
6004	atf_tc_set_md_var(tc, "descr",
6005	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
6006	    "catching PTRACE_FORK breakpoint");
6007}
6008
6009ATF_TC_BODY(signal6, tc)
6010{
6011	const int exitval = 5;
6012	const int exitval2 = 15;
6013	const int sigval = SIGSTOP;
6014	const int sigmasked = SIGTRAP;
6015	pid_t child, child2, wpid;
6016#if defined(TWAIT_HAVE_STATUS)
6017	int status;
6018#endif
6019	sigset_t intmask;
6020	ptrace_state_t state;
6021	const int slen = sizeof(state);
6022	ptrace_event_t event;
6023	const int elen = sizeof(event);
6024
6025	atf_tc_expect_fail("PR kern/51918");
6026
6027	DPRINTF("Before forking process PID=%d\n", getpid());
6028	SYSCALL_REQUIRE((child = fork()) != -1);
6029	if (child == 0) {
6030		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6031		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6032
6033		sigemptyset(&intmask);
6034		sigaddset(&intmask, sigmasked);
6035		sigprocmask(SIG_BLOCK, &intmask, NULL);
6036
6037		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6038		FORKEE_ASSERT(raise(sigval) == 0);
6039
6040		FORKEE_ASSERT((child2 = fork()) != -1);
6041
6042		if (child2 == 0)
6043			_exit(exitval2);
6044
6045		FORKEE_REQUIRE_SUCCESS
6046			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6047
6048		forkee_status_exited(status, exitval2);
6049
6050		DPRINTF("Before exiting of the child process\n");
6051		_exit(exitval);
6052	}
6053	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6054
6055	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6056	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6057
6058	validate_status_stopped(status, sigval);
6059
6060	DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
6061	event.pe_set_event = PTRACE_FORK;
6062	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6063
6064	DPRINTF("Before resuming the child process where it left off and "
6065	    "without signal to be sent\n");
6066	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6067
6068	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6069	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6070
6071	validate_status_stopped(status, sigmasked);
6072
6073	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6074	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
6075
6076	child2 = state.pe_other_pid;
6077	DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2);
6078
6079	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
6080	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6081	    child2);
6082
6083	validate_status_stopped(status, SIGTRAP);
6084
6085	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
6086	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
6087	ATF_REQUIRE_EQ(state.pe_other_pid, child);
6088
6089	DPRINTF("Before resuming the forkee process where it left off and "
6090	    "without signal to be sent\n");
6091	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
6092
6093	DPRINTF("Before resuming the child process where it left off and "
6094	    "without signal to be sent\n");
6095	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6096
6097	DPRINTF("Before calling %s() for the forkee - expected exited\n",
6098	    TWAIT_FNAME);
6099	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6100	    child2);
6101
6102	validate_status_exited(status, exitval2);
6103
6104	DPRINTF("Before calling %s() for the forkee - expected no process\n",
6105	    TWAIT_FNAME);
6106	TWAIT_REQUIRE_FAILURE(ECHILD,
6107	    wpid = TWAIT_GENERIC(child2, &status, 0));
6108
6109	DPRINTF("Before calling %s() for the child - expected stopped "
6110	    "SIGCHLD\n", TWAIT_FNAME);
6111	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6112
6113	validate_status_stopped(status, SIGCHLD);
6114
6115	DPRINTF("Before resuming the child process where it left off and "
6116	    "without signal to be sent\n");
6117	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6118
6119	DPRINTF("Before calling %s() for the child - expected exited\n",
6120	    TWAIT_FNAME);
6121	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6122
6123	validate_status_exited(status, exitval);
6124
6125	DPRINTF("Before calling %s() for the child - expected no process\n",
6126	    TWAIT_FNAME);
6127	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6128}
6129#endif
6130
6131#if defined(TWAIT_HAVE_PID)
6132ATF_TC(signal7);
6133ATF_TC_HEAD(signal7, tc)
6134{
6135	atf_tc_set_md_var(tc, "descr",
6136	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
6137	    "catching PTRACE_VFORK breakpoint");
6138}
6139
6140ATF_TC_BODY(signal7, tc)
6141{
6142	const int exitval = 5;
6143	const int exitval2 = 15;
6144	const int sigval = SIGSTOP;
6145	const int sigmasked = SIGTRAP;
6146	pid_t child, child2, wpid;
6147#if defined(TWAIT_HAVE_STATUS)
6148	int status;
6149#endif
6150	sigset_t intmask;
6151	ptrace_state_t state;
6152	const int slen = sizeof(state);
6153	ptrace_event_t event;
6154	const int elen = sizeof(event);
6155
6156	atf_tc_expect_fail("PR kern/51918");
6157
6158	DPRINTF("Before forking process PID=%d\n", getpid());
6159	SYSCALL_REQUIRE((child = fork()) != -1);
6160	if (child == 0) {
6161		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6162		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6163
6164		sigemptyset(&intmask);
6165		sigaddset(&intmask, sigmasked);
6166		sigprocmask(SIG_BLOCK, &intmask, NULL);
6167
6168		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6169		FORKEE_ASSERT(raise(sigval) == 0);
6170
6171		FORKEE_ASSERT((child2 = fork()) != -1);
6172
6173		if (child2 == 0)
6174			_exit(exitval2);
6175
6176		FORKEE_REQUIRE_SUCCESS
6177			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6178
6179		forkee_status_exited(status, exitval2);
6180
6181		DPRINTF("Before exiting of the child process\n");
6182		_exit(exitval);
6183	}
6184	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6185
6186	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6187	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6188
6189	validate_status_stopped(status, sigval);
6190
6191	DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
6192	event.pe_set_event = PTRACE_VFORK;
6193	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || errno == ENOTSUP);
6194
6195	DPRINTF("Before resuming the child process where it left off and "
6196	    "without signal to be sent\n");
6197	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6198
6199	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6200	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6201
6202	validate_status_stopped(status, sigmasked);
6203
6204	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6205	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
6206
6207	child2 = state.pe_other_pid;
6208	DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2);
6209
6210	DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME);
6211	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6212	    child2);
6213
6214	validate_status_stopped(status, SIGTRAP);
6215
6216	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
6217	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
6218	ATF_REQUIRE_EQ(state.pe_other_pid, child);
6219
6220	DPRINTF("Before resuming the forkee process where it left off and "
6221	    "without signal to be sent\n");
6222	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
6223
6224	DPRINTF("Before resuming the child process where it left off and "
6225	    "without signal to be sent\n");
6226	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6227
6228	DPRINTF("Before calling %s() for the forkee - expected exited\n",
6229	    TWAIT_FNAME);
6230	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6231	    child2);
6232
6233	validate_status_exited(status, exitval2);
6234
6235	DPRINTF("Before calling %s() for the forkee - expected no process\n",
6236	    TWAIT_FNAME);
6237	TWAIT_REQUIRE_FAILURE(ECHILD,
6238	    wpid = TWAIT_GENERIC(child2, &status, 0));
6239
6240	DPRINTF("Before calling %s() for the child - expected stopped "
6241	    "SIGCHLD\n", TWAIT_FNAME);
6242	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6243
6244	validate_status_stopped(status, SIGCHLD);
6245
6246	DPRINTF("Before resuming the child process where it left off and "
6247	    "without signal to be sent\n");
6248	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6249
6250	DPRINTF("Before calling %s() for the child - expected exited\n",
6251	    TWAIT_FNAME);
6252	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6253
6254	validate_status_exited(status, exitval);
6255
6256	DPRINTF("Before calling %s() for the child - expected no process\n",
6257	    TWAIT_FNAME);
6258	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6259}
6260#endif
6261
6262ATF_TC(signal8);
6263ATF_TC_HEAD(signal8, tc)
6264{
6265	atf_tc_set_md_var(tc, "descr",
6266	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
6267	    "catching PTRACE_VFORK_DONE breakpoint");
6268}
6269
6270ATF_TC_BODY(signal8, tc)
6271{
6272	const int exitval = 5;
6273	const int exitval2 = 15;
6274	const int sigval = SIGSTOP;
6275	const int sigmasked = SIGTRAP;
6276	pid_t child, child2, wpid;
6277#if defined(TWAIT_HAVE_STATUS)
6278	int status;
6279#endif
6280	sigset_t intmask;
6281	ptrace_state_t state;
6282	const int slen = sizeof(state);
6283	ptrace_event_t event;
6284	const int elen = sizeof(event);
6285
6286	atf_tc_expect_fail("PR kern/51918");
6287
6288	DPRINTF("Before forking process PID=%d\n", getpid());
6289	SYSCALL_REQUIRE((child = fork()) != -1);
6290	if (child == 0) {
6291		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6292		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6293
6294		sigemptyset(&intmask);
6295		sigaddset(&intmask, sigmasked);
6296		sigprocmask(SIG_BLOCK, &intmask, NULL);
6297
6298		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6299		FORKEE_ASSERT(raise(sigval) == 0);
6300
6301		FORKEE_ASSERT((child2 = vfork()) != -1);
6302
6303		if (child2 == 0)
6304			_exit(exitval2);
6305
6306		FORKEE_REQUIRE_SUCCESS
6307			(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6308
6309		forkee_status_exited(status, exitval2);
6310
6311		DPRINTF("Before exiting of the child process\n");
6312		_exit(exitval);
6313	}
6314	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6315
6316	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6317	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6318
6319	validate_status_stopped(status, sigval);
6320
6321	DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n",
6322	    child);
6323	event.pe_set_event = PTRACE_VFORK_DONE;
6324	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6325
6326	DPRINTF("Before resuming the child process where it left off and "
6327	    "without signal to be sent\n");
6328	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6329
6330	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6331	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6332
6333	validate_status_stopped(status, sigmasked);
6334
6335	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6336	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
6337
6338	child2 = state.pe_other_pid;
6339	DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2);
6340
6341	DPRINTF("Before resuming the child process where it left off and "
6342	    "without signal to be sent\n");
6343	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6344
6345	DPRINTF("Before calling %s() for the child - expected stopped "
6346	    "SIGCHLD\n", TWAIT_FNAME);
6347	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6348
6349	validate_status_stopped(status, SIGCHLD);
6350
6351	DPRINTF("Before resuming the child process where it left off and "
6352	    "without signal to be sent\n");
6353	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6354
6355	DPRINTF("Before calling %s() for the child - expected exited\n",
6356	    TWAIT_FNAME);
6357	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6358
6359	validate_status_exited(status, exitval);
6360
6361	DPRINTF("Before calling %s() for the child - expected no process\n",
6362	    TWAIT_FNAME);
6363	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6364}
6365
6366ATF_TC(signal9);
6367ATF_TC_HEAD(signal9, tc)
6368{
6369	atf_tc_set_md_var(tc, "descr",
6370	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
6371	    "catching PTRACE_LWP_CREATE breakpoint");
6372}
6373
6374ATF_TC_BODY(signal9, tc)
6375{
6376	const int exitval = 5;
6377	const int sigval = SIGSTOP;
6378	const int sigmasked = SIGTRAP;
6379	pid_t child, wpid;
6380#if defined(TWAIT_HAVE_STATUS)
6381	int status;
6382#endif
6383	sigset_t intmask;
6384	ptrace_state_t state;
6385	const int slen = sizeof(state);
6386	ptrace_event_t event;
6387	const int elen = sizeof(event);
6388	ucontext_t uc;
6389	lwpid_t lid;
6390	static const size_t ssize = 16*1024;
6391	void *stack;
6392
6393	atf_tc_expect_fail("PR kern/51918");
6394
6395	DPRINTF("Before forking process PID=%d\n", getpid());
6396	SYSCALL_REQUIRE((child = fork()) != -1);
6397	if (child == 0) {
6398		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6399		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6400
6401		sigemptyset(&intmask);
6402		sigaddset(&intmask, sigmasked);
6403		sigprocmask(SIG_BLOCK, &intmask, NULL);
6404
6405		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6406		FORKEE_ASSERT(raise(sigval) == 0);
6407
6408		DPRINTF("Before allocating memory for stack in child\n");
6409		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6410
6411		DPRINTF("Before making context for new lwp in child\n");
6412		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
6413
6414		DPRINTF("Before creating new in child\n");
6415		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6416
6417		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6418		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6419
6420		DPRINTF("Before verifying that reported %d and running lid %d "
6421		    "are the same\n", lid, the_lwp_id);
6422		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6423
6424		DPRINTF("Before exiting of the child process\n");
6425		_exit(exitval);
6426	}
6427	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6428
6429	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6430	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6431
6432	validate_status_stopped(status, sigval);
6433
6434	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
6435	event.pe_set_event = PTRACE_LWP_CREATE;
6436	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6437
6438	DPRINTF("Before resuming the child process where it left off and "
6439	    "without signal to be sent\n");
6440	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6441
6442	DPRINTF("Before calling %s() for the child - expected stopped "
6443	    "SIGTRAP\n", TWAIT_FNAME);
6444	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6445
6446	validate_status_stopped(status, sigmasked);
6447
6448	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6449
6450	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
6451
6452	lid = state.pe_lwp;
6453	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
6454
6455	DPRINTF("Before resuming the child process where it left off and "
6456	    "without signal to be sent\n");
6457	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6458
6459	DPRINTF("Before calling %s() for the child - expected exited\n",
6460	    TWAIT_FNAME);
6461	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6462
6463	validate_status_exited(status, exitval);
6464
6465	DPRINTF("Before calling %s() for the child - expected no process\n",
6466	    TWAIT_FNAME);
6467	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6468}
6469
6470ATF_TC(signal10);
6471ATF_TC_HEAD(signal10, tc)
6472{
6473	atf_tc_set_md_var(tc, "descr",
6474	    "Verify that masking SIGTRAP in tracee does not stop tracer from "
6475	    "catching PTRACE_LWP_EXIT breakpoint");
6476}
6477
6478ATF_TC_BODY(signal10, tc)
6479{
6480	const int exitval = 5;
6481	const int sigval = SIGSTOP;
6482	const int sigmasked = SIGTRAP;
6483	pid_t child, wpid;
6484#if defined(TWAIT_HAVE_STATUS)
6485	int status;
6486#endif
6487	sigset_t intmask;
6488	ptrace_state_t state;
6489	const int slen = sizeof(state);
6490	ptrace_event_t event;
6491	const int elen = sizeof(event);
6492	ucontext_t uc;
6493	lwpid_t lid;
6494	static const size_t ssize = 16*1024;
6495	void *stack;
6496
6497	atf_tc_expect_fail("PR kern/51918");
6498
6499	DPRINTF("Before forking process PID=%d\n", getpid());
6500	SYSCALL_REQUIRE((child = fork()) != -1);
6501	if (child == 0) {
6502		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6503		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6504
6505		sigemptyset(&intmask);
6506		sigaddset(&intmask, sigmasked);
6507		sigprocmask(SIG_BLOCK, &intmask, NULL);
6508
6509		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6510		FORKEE_ASSERT(raise(sigval) == 0);
6511
6512		DPRINTF("Before allocating memory for stack in child\n");
6513		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6514
6515		DPRINTF("Before making context for new lwp in child\n");
6516		_lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
6517
6518		DPRINTF("Before creating new in child\n");
6519		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6520
6521		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6522		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6523
6524		DPRINTF("Before verifying that reported %d and running lid %d "
6525		    "are the same\n", lid, the_lwp_id);
6526		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6527
6528		DPRINTF("Before exiting of the child process\n");
6529		_exit(exitval);
6530	}
6531	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6532
6533	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6534	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6535
6536	validate_status_stopped(status, sigval);
6537
6538	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
6539	event.pe_set_event = PTRACE_LWP_EXIT;
6540	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6541
6542	DPRINTF("Before resuming the child process where it left off and "
6543	    "without signal to be sent\n");
6544	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6545
6546	DPRINTF("Before calling %s() for the child - expected stopped "
6547	    "SIGTRAP\n", TWAIT_FNAME);
6548	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6549
6550	validate_status_stopped(status, sigmasked);
6551
6552	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6553
6554	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT);
6555
6556	lid = state.pe_lwp;
6557	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
6558
6559	DPRINTF("Before resuming the child process where it left off and "
6560	    "without signal to be sent\n");
6561	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6562
6563	DPRINTF("Before calling %s() for the child - expected exited\n",
6564	    TWAIT_FNAME);
6565	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6566
6567	validate_status_exited(status, exitval);
6568
6569	DPRINTF("Before calling %s() for the child - expected no process\n",
6570	    TWAIT_FNAME);
6571	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6572}
6573
6574static void
6575lwp_main_stop(void *arg)
6576{
6577	the_lwp_id = _lwp_self();
6578
6579	raise(SIGTRAP);
6580
6581	_lwp_exit();
6582}
6583
6584ATF_TC(suspend1);
6585ATF_TC_HEAD(suspend1, tc)
6586{
6587	atf_tc_set_md_var(tc, "descr",
6588	    "Verify that a thread can be suspended by a debugger and later "
6589	    "resumed by a tracee");
6590}
6591
6592ATF_TC_BODY(suspend1, tc)
6593{
6594	const int exitval = 5;
6595	const int sigval = SIGSTOP;
6596	pid_t child, wpid;
6597#if defined(TWAIT_HAVE_STATUS)
6598	int status;
6599#endif
6600	ucontext_t uc;
6601	lwpid_t lid;
6602	static const size_t ssize = 16*1024;
6603	void *stack;
6604	struct ptrace_lwpinfo pl;
6605	struct ptrace_siginfo psi;
6606	volatile int go = 0;
6607
6608	// Feature pending for refactoring
6609	atf_tc_expect_fail("PR kern/51995");
6610
6611	// Hangs with qemu
6612	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
6613
6614	DPRINTF("Before forking process PID=%d\n", getpid());
6615	SYSCALL_REQUIRE((child = fork()) != -1);
6616	if (child == 0) {
6617		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6618		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6619
6620		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6621		FORKEE_ASSERT(raise(sigval) == 0);
6622
6623		DPRINTF("Before allocating memory for stack in child\n");
6624		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6625
6626		DPRINTF("Before making context for new lwp in child\n");
6627		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
6628
6629		DPRINTF("Before creating new in child\n");
6630		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6631
6632		while (go == 0)
6633			continue;
6634
6635		raise(SIGINT);
6636
6637		FORKEE_ASSERT(_lwp_continue(lid) == 0);
6638
6639		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6640		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6641
6642		DPRINTF("Before verifying that reported %d and running lid %d "
6643		    "are the same\n", lid, the_lwp_id);
6644		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6645
6646		DPRINTF("Before exiting of the child process\n");
6647		_exit(exitval);
6648	}
6649	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6650
6651	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6652	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6653
6654	validate_status_stopped(status, sigval);
6655
6656	DPRINTF("Before resuming the child process where it left off and "
6657	    "without signal to be sent\n");
6658	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6659
6660	DPRINTF("Before calling %s() for the child - expected stopped "
6661	    "SIGTRAP\n", TWAIT_FNAME);
6662	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6663
6664	validate_status_stopped(status, SIGTRAP);
6665
6666	DPRINTF("Before reading siginfo and lwpid_t\n");
6667	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6668
6669	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6670	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6671
6672        DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n",
6673	    child, getpid());
6674	SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1);
6675
6676	DPRINTF("Before resuming the child process where it left off and "
6677	    "without signal to be sent\n");
6678	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6679
6680	DPRINTF("Before calling %s() for the child - expected stopped "
6681	    "SIGINT\n", TWAIT_FNAME);
6682	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6683
6684	validate_status_stopped(status, SIGINT);
6685
6686	pl.pl_lwpid = 0;
6687
6688	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6689	while (pl.pl_lwpid != 0) {
6690
6691		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6692		switch (pl.pl_lwpid) {
6693		case 1:
6694			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
6695			break;
6696		case 2:
6697			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
6698			break;
6699		}
6700	}
6701
6702	DPRINTF("Before resuming the child process where it left off and "
6703	    "without signal to be sent\n");
6704	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6705
6706	DPRINTF("Before calling %s() for the child - expected exited\n",
6707	    TWAIT_FNAME);
6708	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6709
6710	validate_status_exited(status, exitval);
6711
6712	DPRINTF("Before calling %s() for the child - expected no process\n",
6713	    TWAIT_FNAME);
6714	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6715}
6716
6717ATF_TC(suspend2);
6718ATF_TC_HEAD(suspend2, tc)
6719{
6720	atf_tc_set_md_var(tc, "descr",
6721	    "Verify that the while the only thread within a process is "
6722	    "suspended, the whole process cannot be unstopped");
6723}
6724
6725ATF_TC_BODY(suspend2, tc)
6726{
6727	const int exitval = 5;
6728	const int sigval = SIGSTOP;
6729	pid_t child, wpid;
6730#if defined(TWAIT_HAVE_STATUS)
6731	int status;
6732#endif
6733	struct ptrace_siginfo psi;
6734
6735	// Feature pending for refactoring
6736	atf_tc_expect_fail("PR kern/51995");
6737
6738	// Hangs with qemu
6739	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
6740
6741	DPRINTF("Before forking process PID=%d\n", getpid());
6742	SYSCALL_REQUIRE((child = fork()) != -1);
6743	if (child == 0) {
6744		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6745		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6746
6747		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6748		FORKEE_ASSERT(raise(sigval) == 0);
6749
6750		DPRINTF("Before exiting of the child process\n");
6751		_exit(exitval);
6752	}
6753	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6754
6755	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6756	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6757
6758	validate_status_stopped(status, sigval);
6759
6760	DPRINTF("Before reading siginfo and lwpid_t\n");
6761	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6762
6763	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6764	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6765
6766	DPRINTF("Before resuming the child process where it left off and "
6767	    "without signal to be sent\n");
6768	ATF_REQUIRE_ERRNO(EDEADLK,
6769	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
6770
6771	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
6772	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
6773
6774	DPRINTF("Before resuming the child process where it left off and "
6775	    "without signal to be sent\n");
6776	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6777
6778	DPRINTF("Before calling %s() for the child - expected exited\n",
6779	    TWAIT_FNAME);
6780	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6781
6782	validate_status_exited(status, exitval);
6783
6784	DPRINTF("Before calling %s() for the child - expected no process\n",
6785	    TWAIT_FNAME);
6786	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6787}
6788
6789ATF_TC(resume1);
6790ATF_TC_HEAD(resume1, tc)
6791{
6792	atf_tc_set_md_var(tc, "timeout", "5");
6793	atf_tc_set_md_var(tc, "descr",
6794	    "Verify that a thread can be suspended by a debugger and later "
6795	    "resumed by the debugger");
6796}
6797
6798ATF_TC_BODY(resume1, tc)
6799{
6800	struct msg_fds fds;
6801	const int exitval = 5;
6802	const int sigval = SIGSTOP;
6803	pid_t child, wpid;
6804	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
6805#if defined(TWAIT_HAVE_STATUS)
6806	int status;
6807#endif
6808	ucontext_t uc;
6809	lwpid_t lid;
6810	static const size_t ssize = 16*1024;
6811	void *stack;
6812	struct ptrace_lwpinfo pl;
6813	struct ptrace_siginfo psi;
6814
6815	// Feature pending for refactoring
6816	atf_tc_expect_fail("PR kern/51995");
6817
6818	// Hangs with qemu
6819	ATF_REQUIRE(0 && "In order to get reliable failure, abort");
6820
6821	SYSCALL_REQUIRE(msg_open(&fds) == 0);
6822
6823	DPRINTF("Before forking process PID=%d\n", getpid());
6824	SYSCALL_REQUIRE((child = fork()) != -1);
6825	if (child == 0) {
6826		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6827		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6828
6829		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6830		FORKEE_ASSERT(raise(sigval) == 0);
6831
6832		DPRINTF("Before allocating memory for stack in child\n");
6833		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
6834
6835		DPRINTF("Before making context for new lwp in child\n");
6836		_lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize);
6837
6838		DPRINTF("Before creating new in child\n");
6839		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
6840
6841		CHILD_TO_PARENT("Message", fds, msg);
6842
6843		raise(SIGINT);
6844
6845		DPRINTF("Before waiting for lwp %d to exit\n", lid);
6846		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
6847
6848		DPRINTF("Before verifying that reported %d and running lid %d "
6849		    "are the same\n", lid, the_lwp_id);
6850		FORKEE_ASSERT_EQ(lid, the_lwp_id);
6851
6852		DPRINTF("Before exiting of the child process\n");
6853		_exit(exitval);
6854	}
6855	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6856
6857	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6858	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6859
6860	validate_status_stopped(status, sigval);
6861
6862	DPRINTF("Before resuming the child process where it left off and "
6863	    "without signal to be sent\n");
6864	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6865
6866	DPRINTF("Before calling %s() for the child - expected stopped "
6867	    "SIGTRAP\n", TWAIT_FNAME);
6868	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6869
6870	validate_status_stopped(status, SIGTRAP);
6871
6872	DPRINTF("Before reading siginfo and lwpid_t\n");
6873	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6874
6875	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6876	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6877
6878	PARENT_FROM_CHILD("Message", fds, msg);
6879
6880	DPRINTF("Before resuming the child process where it left off and "
6881	    "without signal to be sent\n");
6882	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6883
6884	DPRINTF("Before calling %s() for the child - expected stopped "
6885	    "SIGINT\n", TWAIT_FNAME);
6886	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6887
6888	validate_status_stopped(status, SIGINT);
6889
6890	pl.pl_lwpid = 0;
6891
6892	SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6893	while (pl.pl_lwpid != 0) {
6894		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1);
6895		switch (pl.pl_lwpid) {
6896		case 1:
6897			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL);
6898			break;
6899		case 2:
6900			ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED);
6901			break;
6902		}
6903	}
6904
6905	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
6906	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
6907
6908	DPRINTF("Before resuming the child process where it left off and "
6909	    "without signal to be sent\n");
6910	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6911
6912	DPRINTF("Before calling %s() for the child - expected exited\n",
6913	    TWAIT_FNAME);
6914	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6915
6916	validate_status_exited(status, exitval);
6917
6918	DPRINTF("Before calling %s() for the child - expected no process\n",
6919	    TWAIT_FNAME);
6920	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6921
6922	msg_close(&fds);
6923
6924	DPRINTF("XXX: Test worked this time but for consistency timeout it\n");
6925	sleep(10);
6926}
6927
6928ATF_TC(syscall1);
6929ATF_TC_HEAD(syscall1, tc)
6930{
6931	atf_tc_set_md_var(tc, "descr",
6932	    "Verify that getpid(2) can be traced with PT_SYSCALL");
6933}
6934
6935ATF_TC_BODY(syscall1, tc)
6936{
6937	const int exitval = 5;
6938	const int sigval = SIGSTOP;
6939	pid_t child, wpid;
6940#if defined(TWAIT_HAVE_STATUS)
6941	int status;
6942#endif
6943	struct ptrace_siginfo info;
6944	memset(&info, 0, sizeof(info));
6945
6946	DPRINTF("Before forking process PID=%d\n", getpid());
6947	SYSCALL_REQUIRE((child = fork()) != -1);
6948	if (child == 0) {
6949		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6950		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6951
6952		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6953		FORKEE_ASSERT(raise(sigval) == 0);
6954
6955		syscall(SYS_getpid);
6956
6957		DPRINTF("Before exiting of the child process\n");
6958		_exit(exitval);
6959	}
6960	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6961
6962	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6963	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6964
6965	validate_status_stopped(status, sigval);
6966
6967	DPRINTF("Before resuming the child process where it left off and "
6968	    "without signal to be sent\n");
6969	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6970
6971	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6972	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6973
6974	validate_status_stopped(status, SIGTRAP);
6975
6976	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6977	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6978
6979	DPRINTF("Before checking siginfo_t and lwpid\n");
6980	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
6981	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6982	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE);
6983
6984	DPRINTF("Before resuming the child process where it left off and "
6985	    "without signal to be sent\n");
6986	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
6987
6988	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6989	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6990
6991	validate_status_stopped(status, SIGTRAP);
6992
6993	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6994	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6995
6996	DPRINTF("Before checking siginfo_t and lwpid\n");
6997	ATF_REQUIRE_EQ(info.psi_lwpid, 1);
6998	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6999	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX);
7000
7001	DPRINTF("Before resuming the child process where it left off and "
7002	    "without signal to be sent\n");
7003	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7004
7005	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7006	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7007
7008	validate_status_exited(status, exitval);
7009
7010	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7011	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7012}
7013
7014ATF_TC(syscallemu1);
7015ATF_TC_HEAD(syscallemu1, tc)
7016{
7017	atf_tc_set_md_var(tc, "descr",
7018	    "Verify that exit(2) can be intercepted with PT_SYSCALLEMU");
7019}
7020
7021ATF_TC_BODY(syscallemu1, tc)
7022{
7023	const int exitval = 5;
7024	const int sigval = SIGSTOP;
7025	pid_t child, wpid;
7026#if defined(TWAIT_HAVE_STATUS)
7027	int status;
7028#endif
7029
7030#if defined(__sparc__) && !defined(__sparc64__)
7031	/* syscallemu does not work on sparc (32-bit) */
7032	atf_tc_expect_fail("PR kern/52166");
7033#endif
7034
7035	DPRINTF("Before forking process PID=%d\n", getpid());
7036	SYSCALL_REQUIRE((child = fork()) != -1);
7037	if (child == 0) {
7038		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7039		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7040
7041		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7042		FORKEE_ASSERT(raise(sigval) == 0);
7043
7044		syscall(SYS_exit, 100);
7045
7046		DPRINTF("Before exiting of the child process\n");
7047		_exit(exitval);
7048	}
7049	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7050
7051	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7052	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7053
7054	validate_status_stopped(status, sigval);
7055
7056	DPRINTF("Before resuming the child process where it left off and "
7057	    "without signal to be sent\n");
7058	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
7059
7060	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7061	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7062
7063	validate_status_stopped(status, SIGTRAP);
7064
7065	DPRINTF("Set SYSCALLEMU for intercepted syscall\n");
7066	SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1);
7067
7068	DPRINTF("Before resuming the child process where it left off and "
7069	    "without signal to be sent\n");
7070	SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1);
7071
7072	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7073	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7074
7075	validate_status_stopped(status, SIGTRAP);
7076
7077	DPRINTF("Before resuming the child process where it left off and "
7078	    "without signal to be sent\n");
7079	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7080
7081	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7082	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7083
7084	validate_status_exited(status, exitval);
7085
7086	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7087	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7088}
7089
7090#if defined(TWAIT_HAVE_PID)
7091ATF_TC(race1);
7092ATF_TC_HEAD(race1, tc)
7093{
7094	atf_tc_set_md_var(tc, "descr",
7095	    "Assert that await_zombie() in attach1 always finds a single "
7096	    "process and no other error is reported");
7097}
7098
7099ATF_TC_BODY(race1, tc)
7100{
7101	time_t start, end;
7102	double diff;
7103	unsigned long N = 0;
7104
7105	/* Reuse this test with attach1 */
7106
7107	start = time(NULL);
7108	while (true) {
7109		DPRINTF("Step: %lu\n", N);
7110		attach1_raw(true);
7111		end = time(NULL);
7112		diff = difftime(end, start);
7113		if (diff >= 5.0)
7114			break;
7115		++N;
7116	}
7117	DPRINTF("Iterations: %lu\n", N);
7118}
7119#endif
7120
7121#include "t_ptrace_amd64_wait.h"
7122#include "t_ptrace_i386_wait.h"
7123#include "t_ptrace_x86_wait.h"
7124
7125ATF_TP_ADD_TCS(tp)
7126{
7127	setvbuf(stdout, NULL, _IONBF, 0);
7128	setvbuf(stderr, NULL, _IONBF, 0);
7129
7130	ATF_TP_ADD_TC(tp, traceme_raise1);
7131	ATF_TP_ADD_TC(tp, traceme_raise2);
7132	ATF_TP_ADD_TC(tp, traceme_raise3);
7133	ATF_TP_ADD_TC(tp, traceme_raise4);
7134	ATF_TP_ADD_TC(tp, traceme_raise5);
7135
7136	ATF_TP_ADD_TC(tp, traceme_sighandler_catch1);
7137	ATF_TP_ADD_TC(tp, traceme_sighandler_catch2);
7138	ATF_TP_ADD_TC(tp, traceme_sighandler_catch3);
7139
7140	ATF_TP_ADD_TC(tp, traceme_signal_nohandler1);
7141	ATF_TP_ADD_TC(tp, traceme_signal_nohandler2);
7142	ATF_TP_ADD_TC(tp, traceme_signal_nohandler3);
7143	ATF_TP_ADD_TC(tp, traceme_signal_nohandler4);
7144	ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);
7145
7146	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
7147
7148	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
7149	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
7150	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
7151	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
7152	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
7153	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
7154	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
7155	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
7156
7157	ATF_TP_ADD_TC(tp, traceme_vfork_breakpoint);
7158
7159	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
7160
7161	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
7162	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
7163	ATF_TP_ADD_TC(tp, attach3);
7164	ATF_TP_ADD_TC(tp, attach4);
7165	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
7166	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
7167	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
7168
7169	ATF_TP_ADD_TC(tp, eventmask1);
7170	ATF_TP_ADD_TC(tp, eventmask2);
7171	ATF_TP_ADD_TC(tp, eventmask3);
7172	ATF_TP_ADD_TC(tp, eventmask4);
7173	ATF_TP_ADD_TC(tp, eventmask5);
7174	ATF_TP_ADD_TC(tp, eventmask6);
7175
7176	ATF_TP_ADD_TC(tp, fork1);
7177	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
7178	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
7179	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
7180	ATF_TP_ADD_TC(tp, fork5);
7181	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
7182	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
7183	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
7184
7185	ATF_TP_ADD_TC(tp, vfork1);
7186	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
7187	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
7188	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
7189	ATF_TP_ADD_TC(tp, vfork5);
7190	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
7191	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
7192	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
7193
7194	ATF_TP_ADD_TC(tp, io_read_d1);
7195	ATF_TP_ADD_TC(tp, io_read_d2);
7196	ATF_TP_ADD_TC(tp, io_read_d3);
7197	ATF_TP_ADD_TC(tp, io_read_d4);
7198
7199	ATF_TP_ADD_TC(tp, io_write_d1);
7200	ATF_TP_ADD_TC(tp, io_write_d2);
7201	ATF_TP_ADD_TC(tp, io_write_d3);
7202	ATF_TP_ADD_TC(tp, io_write_d4);
7203
7204	ATF_TP_ADD_TC(tp, read_d1);
7205	ATF_TP_ADD_TC(tp, read_d2);
7206	ATF_TP_ADD_TC(tp, read_d3);
7207	ATF_TP_ADD_TC(tp, read_d4);
7208
7209	ATF_TP_ADD_TC(tp, write_d1);
7210	ATF_TP_ADD_TC(tp, write_d2);
7211	ATF_TP_ADD_TC(tp, write_d3);
7212	ATF_TP_ADD_TC(tp, write_d4);
7213
7214	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
7215	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
7216
7217	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
7218	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
7219
7220	ATF_TP_ADD_TC(tp, io_read_i1);
7221	ATF_TP_ADD_TC(tp, io_read_i2);
7222	ATF_TP_ADD_TC(tp, io_read_i3);
7223	ATF_TP_ADD_TC(tp, io_read_i4);
7224
7225	ATF_TP_ADD_TC(tp, read_i1);
7226	ATF_TP_ADD_TC(tp, read_i2);
7227	ATF_TP_ADD_TC(tp, read_i3);
7228	ATF_TP_ADD_TC(tp, read_i4);
7229
7230	ATF_TP_ADD_TC(tp, io_read_auxv1);
7231
7232	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
7233	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
7234	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
7235	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
7236	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
7237
7238	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
7239	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
7240
7241	ATF_TP_ADD_TC_PT_STEP(tp, step1);
7242	ATF_TP_ADD_TC_PT_STEP(tp, step2);
7243	ATF_TP_ADD_TC_PT_STEP(tp, step3);
7244	ATF_TP_ADD_TC_PT_STEP(tp, step4);
7245
7246	ATF_TP_ADD_TC_PT_STEP(tp, setstep1);
7247	ATF_TP_ADD_TC_PT_STEP(tp, setstep2);
7248	ATF_TP_ADD_TC_PT_STEP(tp, setstep3);
7249	ATF_TP_ADD_TC_PT_STEP(tp, setstep4);
7250
7251	ATF_TP_ADD_TC(tp, kill1);
7252	ATF_TP_ADD_TC(tp, kill2);
7253
7254	ATF_TP_ADD_TC(tp, lwpinfo1);
7255	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
7256
7257	ATF_TP_ADD_TC(tp, siginfo1);
7258	ATF_TP_ADD_TC(tp, siginfo2);
7259	ATF_TP_ADD_TC(tp, siginfo3);
7260	ATF_TP_ADD_TC(tp, siginfo4);
7261	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
7262	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
7263
7264	ATF_TP_ADD_TC(tp, lwp_create1);
7265
7266	ATF_TP_ADD_TC(tp, lwp_exit1);
7267
7268	ATF_TP_ADD_TC(tp, signal1);
7269	ATF_TP_ADD_TC(tp, signal2);
7270	ATF_TP_ADD_TC(tp, signal3);
7271	ATF_TP_ADD_TC_PT_STEP(tp, signal4);
7272	ATF_TP_ADD_TC(tp, signal5);
7273	ATF_TP_ADD_TC_HAVE_PID(tp, signal6);
7274	ATF_TP_ADD_TC_HAVE_PID(tp, signal7);
7275	ATF_TP_ADD_TC(tp, signal8);
7276	ATF_TP_ADD_TC(tp, signal9);
7277	ATF_TP_ADD_TC(tp, signal10);
7278
7279	ATF_TP_ADD_TC(tp, suspend1);
7280	ATF_TP_ADD_TC(tp, suspend2);
7281
7282	ATF_TP_ADD_TC(tp, resume1);
7283
7284	ATF_TP_ADD_TC(tp, syscall1);
7285
7286	ATF_TP_ADD_TC(tp, syscallemu1);
7287
7288	ATF_TP_ADD_TC_HAVE_PID(tp, race1);
7289
7290	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
7291	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
7292	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
7293
7294	return atf_no_error();
7295}
7296