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