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