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