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