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