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