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