t_ptrace_wait.c revision 313680
1/*	$NetBSD: t_ptrace_wait.c,v 1.53 2017/01/10 05:08:24 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 2017/01/10 05:08:24 kamil Exp $");
31
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/ptrace.h>
35#include <sys/resource.h>
36#include <sys/stat.h>
37#include <sys/sysctl.h>
38#include <sys/wait.h>
39#include <machine/reg.h>
40#include <err.h>
41#include <errno.h>
42#include <signal.h>
43#include <stdint.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <strings.h>
47#include <unistd.h>
48
49#include <atf-c.h>
50
51#include "../h_macros.h"
52
53#include "t_ptrace_wait.h"
54#include "msg.h"
55
56#define PARENT_TO_CHILD(info, fds, msg) \
57    ATF_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0)
58
59#define CHILD_FROM_PARENT(info, fds, msg) \
60    FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
61
62#define CHILD_TO_PARENT(info, fds, msg) \
63    FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0)
64
65#define PARENT_FROM_CHILD(info, fds, msg) \
66    ATF_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0)
67
68ATF_TC(traceme1);
69ATF_TC_HEAD(traceme1, tc)
70{
71	atf_tc_set_md_var(tc, "descr",
72	    "Verify SIGSTOP followed by _exit(2) in a child");
73}
74
75ATF_TC_BODY(traceme1, tc)
76{
77	const int exitval = 5;
78	const int sigval = SIGSTOP;
79	pid_t child, wpid;
80#if defined(TWAIT_HAVE_STATUS)
81	int status;
82#endif
83
84	printf("Before forking process PID=%d\n", getpid());
85	ATF_REQUIRE((child = fork()) != -1);
86	if (child == 0) {
87		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
88		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
89
90		printf("Before raising %s from child\n", strsignal(sigval));
91		FORKEE_ASSERT(raise(sigval) == 0);
92
93		printf("Before exiting of the child process\n");
94		_exit(exitval);
95	}
96	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
97
98	printf("Before calling %s() for the child\n", TWAIT_FNAME);
99	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
100
101	validate_status_stopped(status, sigval);
102
103	printf("Before resuming the child process where it left off and "
104	    "without signal to be sent\n");
105	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
106
107	printf("Before calling %s() for the child\n", TWAIT_FNAME);
108	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
109
110	validate_status_exited(status, exitval);
111
112	printf("Before calling %s() for the child\n", TWAIT_FNAME);
113	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
114}
115
116ATF_TC(traceme2);
117ATF_TC_HEAD(traceme2, tc)
118{
119	atf_tc_set_md_var(tc, "descr",
120	    "Verify SIGSTOP followed by _exit(2) in a child");
121}
122
123static int traceme2_caught = 0;
124
125static void
126traceme2_sighandler(int sig)
127{
128	FORKEE_ASSERT_EQ(sig, SIGINT);
129
130	++traceme2_caught;
131}
132
133ATF_TC_BODY(traceme2, tc)
134{
135	const int exitval = 5;
136	const int sigval = SIGSTOP, sigsent = SIGINT;
137	pid_t child, wpid;
138	struct sigaction sa;
139#if defined(TWAIT_HAVE_STATUS)
140	int status;
141#endif
142
143	printf("Before forking process PID=%d\n", getpid());
144	ATF_REQUIRE((child = fork()) != -1);
145	if (child == 0) {
146		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
147		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
148
149		sa.sa_handler = traceme2_sighandler;
150		sa.sa_flags = SA_SIGINFO;
151		sigemptyset(&sa.sa_mask);
152
153		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
154
155		printf("Before raising %s from child\n", strsignal(sigval));
156		FORKEE_ASSERT(raise(sigval) == 0);
157
158		FORKEE_ASSERT_EQ(traceme2_caught, 1);
159
160		printf("Before exiting of the child process\n");
161		_exit(exitval);
162	}
163	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
164
165	printf("Before calling %s() for the child\n", TWAIT_FNAME);
166	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
167
168	validate_status_stopped(status, sigval);
169
170	printf("Before resuming the child process where it left off and with "
171	    "signal %s to be sent\n", strsignal(sigsent));
172	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
173
174	printf("Before calling %s() for the child\n", TWAIT_FNAME);
175	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
176
177	validate_status_exited(status, exitval);
178
179	printf("Before calling %s() for the exited child\n", TWAIT_FNAME);
180	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
181}
182
183ATF_TC(traceme3);
184ATF_TC_HEAD(traceme3, tc)
185{
186	atf_tc_set_md_var(tc, "descr",
187	    "Verify SIGSTOP followed by termination by a signal in a child");
188}
189
190ATF_TC_BODY(traceme3, tc)
191{
192	const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */;
193	pid_t child, wpid;
194#if defined(TWAIT_HAVE_STATUS)
195	int status;
196#endif
197
198	printf("Before forking process PID=%d\n", getpid());
199	ATF_REQUIRE((child = fork()) != -1);
200	if (child == 0) {
201		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
202		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
203
204		printf("Before raising %s from child\n", strsignal(sigval));
205		FORKEE_ASSERT(raise(sigval) == 0);
206
207		/* NOTREACHED */
208		FORKEE_ASSERTX(0 &&
209		    "Child should be terminated by a signal from its parent");
210	}
211	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
212
213	printf("Before calling %s() for the child\n", TWAIT_FNAME);
214	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
215
216	validate_status_stopped(status, sigval);
217
218	printf("Before resuming the child process where it left off and with "
219	    "signal %s to be sent\n", strsignal(sigsent));
220	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
221
222	printf("Before calling %s() for the child\n", TWAIT_FNAME);
223	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
224
225	validate_status_signaled(status, sigsent, 0);
226
227	printf("Before calling %s() for the exited child\n", TWAIT_FNAME);
228	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
229}
230
231ATF_TC(traceme4);
232ATF_TC_HEAD(traceme4, tc)
233{
234	atf_tc_set_md_var(tc, "descr",
235	    "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child");
236}
237
238ATF_TC_BODY(traceme4, tc)
239{
240	const int exitval = 5;
241	const int sigval = SIGSTOP, sigsent = SIGCONT;
242	pid_t child, wpid;
243#if defined(TWAIT_HAVE_STATUS)
244	int status;
245#endif
246
247	printf("Before forking process PID=%d\n", getpid());
248	ATF_REQUIRE((child = fork()) != -1);
249	if (child == 0) {
250		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
251		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
252
253		printf("Before raising %s from child\n", strsignal(sigval));
254		FORKEE_ASSERT(raise(sigval) == 0);
255
256		printf("Before raising %s from child\n", strsignal(sigsent));
257		FORKEE_ASSERT(raise(sigsent) == 0);
258
259		printf("Before exiting of the child process\n");
260		_exit(exitval);
261	}
262	printf("Parent process PID=%d, child's PID=%d\n", getpid(),child);
263
264	printf("Before calling %s() for the child\n", TWAIT_FNAME);
265	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
266
267	validate_status_stopped(status, sigval);
268
269	printf("Before resuming the child process where it left off and "
270	    "without signal to be sent\n");
271	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
272
273	printf("Before calling %s() for the child\n", TWAIT_FNAME);
274	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
275
276	validate_status_stopped(status, sigsent);
277
278	printf("Before resuming the child process where it left off and "
279	    "without signal to be sent\n");
280	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
281
282	printf("Before calling %s() for the child\n", TWAIT_FNAME);
283	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
284
285	validate_status_exited(status, exitval);
286
287	printf("Before calling %s() for the exited child\n", TWAIT_FNAME);
288	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
289}
290
291#if defined(TWAIT_HAVE_PID)
292ATF_TC(attach1);
293ATF_TC_HEAD(attach1, tc)
294{
295	atf_tc_set_md_var(tc, "descr",
296	    "Assert that tracer sees process termination before the parent");
297}
298
299ATF_TC_BODY(attach1, tc)
300{
301	struct msg_fds parent_tracee, parent_tracer;
302	const int exitval_tracee = 5;
303	const int exitval_tracer = 10;
304	pid_t tracee, tracer, wpid;
305	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
306#if defined(TWAIT_HAVE_STATUS)
307	int status;
308#endif
309
310	printf("Spawn tracee\n");
311	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
312	tracee = atf_utils_fork();
313	if (tracee == 0) {
314		// Wait for parent to let us exit
315		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
316		_exit(exitval_tracee);
317	}
318
319	printf("Spawn debugger\n");
320	ATF_REQUIRE(msg_open(&parent_tracer) == 0);
321	tracer = atf_utils_fork();
322	if (tracer == 0) {
323		printf("Before calling PT_ATTACH from tracee %d\n", getpid());
324		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
325
326		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
327		FORKEE_REQUIRE_SUCCESS(
328		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
329
330		forkee_status_stopped(status, SIGSTOP);
331
332		/* Resume tracee with PT_CONTINUE */
333		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
334
335		/* Inform parent that tracer has attached to tracee */
336		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
337
338		/* Wait for parent to tell use that tracee should have exited */
339		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
340
341		/* Wait for tracee and assert that it exited */
342		FORKEE_REQUIRE_SUCCESS(
343		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
344
345		forkee_status_exited(status, exitval_tracee);
346		printf("Tracee %d exited with %d\n", tracee, exitval_tracee);
347
348		printf("Before exiting of the tracer process\n");
349		_exit(exitval_tracer);
350	}
351
352	printf("Wait for the tracer to attach to the tracee\n");
353	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
354
355	printf("Resume the tracee and let it exit\n");
356	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
357
358	printf("Detect that tracee is zombie\n");
359	await_zombie(tracee);
360
361
362	printf("Assert that there is no status about tracee %d - "
363	    "Tracer must detect zombie first - calling %s()\n", tracee,
364	    TWAIT_FNAME);
365	TWAIT_REQUIRE_SUCCESS(
366	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
367
368	printf("Tell the tracer child should have exited\n");
369	PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
370	printf("Wait for tracer to finish its job and exit - calling %s()\n",
371	    TWAIT_FNAME);
372
373	printf("Wait from tracer child to complete waiting for tracee\n");
374	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
375	    tracer);
376
377	validate_status_exited(status, exitval_tracer);
378
379	printf("Wait for tracee to finish its job and exit - calling %s()\n",
380	    TWAIT_FNAME);
381	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
382	    tracee);
383
384	validate_status_exited(status, exitval_tracee);
385
386	msg_close(&parent_tracer);
387	msg_close(&parent_tracee);
388}
389#endif
390
391#if defined(TWAIT_HAVE_PID)
392ATF_TC(attach2);
393ATF_TC_HEAD(attach2, tc)
394{
395	atf_tc_set_md_var(tc, "descr",
396	    "Assert that any tracer sees process termination before its "
397	    "parent");
398}
399
400ATF_TC_BODY(attach2, tc)
401{
402	struct msg_fds parent_tracer, parent_tracee;
403	const int exitval_tracee = 5;
404	const int exitval_tracer1 = 10, exitval_tracer2 = 20;
405	pid_t tracee, tracer, wpid;
406	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
407#if defined(TWAIT_HAVE_STATUS)
408	int status;
409#endif
410
411	printf("Spawn tracee\n");
412	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
413	tracee = atf_utils_fork();
414	if (tracee == 0) {
415		/* Wait for message from the parent */
416		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
417		_exit(exitval_tracee);
418	}
419
420	printf("Spawn debugger\n");
421	ATF_REQUIRE(msg_open(&parent_tracer) == 0);
422	tracer = atf_utils_fork();
423	if (tracer == 0) {
424		/* Fork again and drop parent to reattach to PID 1 */
425		tracer = atf_utils_fork();
426		if (tracer != 0)
427			_exit(exitval_tracer1);
428
429		printf("Before calling PT_ATTACH from tracee %d\n", getpid());
430		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
431
432		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
433		FORKEE_REQUIRE_SUCCESS(
434		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
435
436		forkee_status_stopped(status, SIGSTOP);
437
438		/* Resume tracee with PT_CONTINUE */
439		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
440
441		/* Inform parent that tracer has attached to tracee */
442		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
443		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
444
445		/* Wait for tracee and assert that it exited */
446		FORKEE_REQUIRE_SUCCESS(
447		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
448
449		forkee_status_exited(status, exitval_tracee);
450
451		printf("Before exiting of the tracer process\n");
452		_exit(exitval_tracer2);
453	}
454	printf("Wait for the tracer process (direct child) to exit calling "
455	    "%s()\n", TWAIT_FNAME);
456	TWAIT_REQUIRE_SUCCESS(
457	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
458
459	validate_status_exited(status, exitval_tracer1);
460
461	printf("Wait for the non-exited tracee process with %s()\n",
462	    TWAIT_FNAME);
463	TWAIT_REQUIRE_SUCCESS(
464	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
465
466	printf("Wait for the tracer to attach to the tracee\n");
467	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
468	printf("Resume the tracee and let it exit\n");
469	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
470
471	printf("Detect that tracee is zombie\n");
472	await_zombie(tracee);
473
474	printf("Assert that there is no status about tracee - "
475	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
476	TWAIT_REQUIRE_SUCCESS(
477	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
478
479	printf("Resume the tracer and let it detect exited tracee\n");
480	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
481
482	printf("Wait for tracee to finish its job and exit - calling %s()\n",
483	    TWAIT_FNAME);
484	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
485	    tracee);
486
487	validate_status_exited(status, exitval_tracee);
488
489	msg_close(&parent_tracer);
490	msg_close(&parent_tracee);
491
492}
493#endif
494
495ATF_TC(attach3);
496ATF_TC_HEAD(attach3, tc)
497{
498	atf_tc_set_md_var(tc, "descr",
499	    "Assert that tracer parent can PT_ATTACH to its child");
500}
501
502ATF_TC_BODY(attach3, tc)
503{
504	struct msg_fds parent_tracee;
505	const int exitval_tracee = 5;
506	pid_t tracee, wpid;
507	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
508#if defined(TWAIT_HAVE_STATUS)
509	int status;
510#endif
511
512	printf("Spawn tracee\n");
513	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
514	tracee = atf_utils_fork();
515	if (tracee == 0) {
516		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
517		printf("Parent should now attach to tracee\n");
518
519		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
520		/* Wait for message from the parent */
521		_exit(exitval_tracee);
522	}
523	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
524
525	printf("Before calling PT_ATTACH for tracee %d\n", tracee);
526	ATF_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
527
528	printf("Wait for the stopped tracee process with %s()\n",
529	    TWAIT_FNAME);
530	TWAIT_REQUIRE_SUCCESS(
531	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
532
533	validate_status_stopped(status, SIGSTOP);
534
535	printf("Resume tracee with PT_CONTINUE\n");
536	ATF_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
537
538	printf("Let the tracee exit now\n");
539	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
540
541	printf("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
542	TWAIT_REQUIRE_SUCCESS(
543	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
544
545	validate_status_exited(status, exitval_tracee);
546
547	printf("Before calling %s() for tracee\n", TWAIT_FNAME);
548	TWAIT_REQUIRE_FAILURE(ECHILD,
549	    wpid = TWAIT_GENERIC(tracee, &status, 0));
550
551	msg_close(&parent_tracee);
552}
553
554ATF_TC(attach4);
555ATF_TC_HEAD(attach4, tc)
556{
557	atf_tc_set_md_var(tc, "descr",
558	    "Assert that tracer child can PT_ATTACH to its parent");
559}
560
561ATF_TC_BODY(attach4, tc)
562{
563	struct msg_fds parent_tracee;
564	const int exitval_tracer = 5;
565	pid_t tracer, wpid;
566	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
567#if defined(TWAIT_HAVE_STATUS)
568	int status;
569#endif
570
571	printf("Spawn tracer\n");
572	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
573	tracer = atf_utils_fork();
574	if (tracer == 0) {
575
576		/* Wait for message from the parent */
577		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
578
579		printf("Attach to parent PID %d with PT_ATTACH from child\n",
580		    getppid());
581		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
582
583		printf("Wait for the stopped parent process with %s()\n",
584		    TWAIT_FNAME);
585		FORKEE_REQUIRE_SUCCESS(
586		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
587
588		forkee_status_stopped(status, SIGSTOP);
589
590		printf("Resume parent with PT_DETACH\n");
591		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
592		    != -1);
593
594		/* Tell parent we are ready */
595		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
596
597		_exit(exitval_tracer);
598	}
599
600	printf("Wait for the tracer to become ready\n");
601	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
602	printf("Allow the tracer to exit now\n");
603	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
604
605	printf("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
606	TWAIT_REQUIRE_SUCCESS(
607	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
608
609	validate_status_exited(status, exitval_tracer);
610
611	printf("Before calling %s() for tracer\n", TWAIT_FNAME);
612	TWAIT_REQUIRE_FAILURE(ECHILD,
613	    wpid = TWAIT_GENERIC(tracer, &status, 0));
614
615	msg_close(&parent_tracee);
616}
617
618#if defined(TWAIT_HAVE_PID)
619ATF_TC(attach5);
620ATF_TC_HEAD(attach5, tc)
621{
622	atf_tc_set_md_var(tc, "descr",
623	    "Assert that tracer sees its parent when attached to tracer "
624	    "(check getppid(2))");
625}
626
627ATF_TC_BODY(attach5, tc)
628{
629	struct msg_fds parent_tracer, parent_tracee;
630	const int exitval_tracee = 5;
631	const int exitval_tracer = 10;
632	pid_t parent, tracee, tracer, wpid;
633	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
634#if defined(TWAIT_HAVE_STATUS)
635	int status;
636#endif
637
638	printf("Spawn tracee\n");
639	ATF_REQUIRE(msg_open(&parent_tracer) == 0);
640	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
641	tracee = atf_utils_fork();
642	if (tracee == 0) {
643		parent = getppid();
644
645		/* Emit message to the parent */
646		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
647		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
648
649		FORKEE_ASSERT_EQ(parent, getppid());
650
651		_exit(exitval_tracee);
652	}
653	printf("Wait for child to record its parent identifier (pid)\n");
654	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
655
656	printf("Spawn debugger\n");
657	tracer = atf_utils_fork();
658	if (tracer == 0) {
659		/* No IPC to communicate with the child */
660		printf("Before calling PT_ATTACH from tracee %d\n", getpid());
661		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
662
663		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
664		FORKEE_REQUIRE_SUCCESS(
665		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
666
667		forkee_status_stopped(status, SIGSTOP);
668
669		/* Resume tracee with PT_CONTINUE */
670		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
671
672		/* Inform parent that tracer has attached to tracee */
673		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
674
675		/* Wait for parent to tell use that tracee should have exited */
676		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
677
678		/* Wait for tracee and assert that it exited */
679		FORKEE_REQUIRE_SUCCESS(
680		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
681
682		forkee_status_exited(status, exitval_tracee);
683
684		printf("Before exiting of the tracer process\n");
685		_exit(exitval_tracer);
686	}
687
688	printf("Wait for the tracer to attach to the tracee\n");
689	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
690
691	printf("Resume the tracee and let it exit\n");
692	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
693
694	printf("Detect that tracee is zombie\n");
695	await_zombie(tracee);
696
697	printf("Assert that there is no status about tracee - "
698	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
699	TWAIT_REQUIRE_SUCCESS(
700	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
701
702	printf("Tell the tracer child should have exited\n");
703	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
704
705	printf("Wait from tracer child to complete waiting for tracee\n");
706	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
707	    tracer);
708
709	validate_status_exited(status, exitval_tracer);
710
711	printf("Wait for tracee to finish its job and exit - calling %s()\n",
712	    TWAIT_FNAME);
713	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
714	    tracee);
715
716	validate_status_exited(status, exitval_tracee);
717
718	msg_close(&parent_tracer);
719	msg_close(&parent_tracee);
720}
721#endif
722
723#if defined(TWAIT_HAVE_PID)
724ATF_TC(attach6);
725ATF_TC_HEAD(attach6, tc)
726{
727	atf_tc_set_md_var(tc, "descr",
728	    "Assert that tracer sees its parent when attached to tracer "
729	    "(check sysctl(7) and struct kinfo_proc2)");
730}
731
732ATF_TC_BODY(attach6, tc)
733{
734	struct msg_fds parent_tracee, parent_tracer;
735	const int exitval_tracee = 5;
736	const int exitval_tracer = 10;
737	pid_t parent, tracee, tracer, wpid;
738	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
739#if defined(TWAIT_HAVE_STATUS)
740	int status;
741#endif
742	int name[CTL_MAXNAME];
743	struct kinfo_proc2 kp;
744	size_t len = sizeof(kp);
745	unsigned int namelen;
746
747	printf("Spawn tracee\n");
748	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
749	ATF_REQUIRE(msg_open(&parent_tracer) == 0);
750	tracee = atf_utils_fork();
751	if (tracee == 0) {
752		parent = getppid();
753
754		/* Emit message to the parent */
755		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
756		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
757
758		namelen = 0;
759		name[namelen++] = CTL_KERN;
760		name[namelen++] = KERN_PROC2;
761		name[namelen++] = KERN_PROC_PID;
762		name[namelen++] = getpid();
763		name[namelen++] = len;
764		name[namelen++] = 1;
765
766		FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0);
767		FORKEE_ASSERT_EQ(parent, kp.p_ppid);
768
769		_exit(exitval_tracee);
770	}
771
772	printf("Wait for child to record its parent identifier (pid)\n");
773	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
774
775	printf("Spawn debugger\n");
776	tracer = atf_utils_fork();
777	if (tracer == 0) {
778		/* No IPC to communicate with the child */
779		printf("Before calling PT_ATTACH from tracee %d\n", getpid());
780		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
781
782		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
783		FORKEE_REQUIRE_SUCCESS(
784		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
785
786		forkee_status_stopped(status, SIGSTOP);
787
788		/* Resume tracee with PT_CONTINUE */
789		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
790
791		/* Inform parent that tracer has attached to tracee */
792		CHILD_TO_PARENT("Message 1", parent_tracer, msg);
793
794		CHILD_FROM_PARENT("Message 2", parent_tracer, msg);
795
796		/* Wait for tracee and assert that it exited */
797		FORKEE_REQUIRE_SUCCESS(
798		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
799
800		forkee_status_exited(status, exitval_tracee);
801
802		printf("Before exiting of the tracer process\n");
803		_exit(exitval_tracer);
804	}
805
806	printf("Wait for the tracer to attach to the tracee\n");
807	PARENT_FROM_CHILD("Message 1", parent_tracer, msg);
808
809	printf("Resume the tracee and let it exit\n");
810	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
811
812	printf("Detect that tracee is zombie\n");
813	await_zombie(tracee);
814
815	printf("Assert that there is no status about tracee - "
816	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
817	TWAIT_REQUIRE_SUCCESS(
818	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
819
820	printf("Resume the tracer and let it detect exited tracee\n");
821	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
822
823	printf("Wait for tracer to finish its job and exit - calling %s()\n",
824	    TWAIT_FNAME);
825	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
826	    tracer);
827
828	validate_status_exited(status, exitval_tracer);
829
830	printf("Wait for tracee to finish its job and exit - calling %s()\n",
831	    TWAIT_FNAME);
832	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
833	    tracee);
834
835	validate_status_exited(status, exitval_tracee);
836
837	msg_close(&parent_tracee);
838	msg_close(&parent_tracer);
839}
840#endif
841
842#if defined(TWAIT_HAVE_PID)
843ATF_TC(attach7);
844ATF_TC_HEAD(attach7, tc)
845{
846	atf_tc_set_md_var(tc, "descr",
847	    "Assert that tracer sees its parent when attached to tracer "
848	    "(check /proc/curproc/status 3rd column)");
849}
850
851ATF_TC_BODY(attach7, tc)
852{
853	struct msg_fds parent_tracee, parent_tracer;
854	int rv;
855	const int exitval_tracee = 5;
856	const int exitval_tracer = 10;
857	pid_t parent, tracee, tracer, wpid;
858	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
859#if defined(TWAIT_HAVE_STATUS)
860	int status;
861#endif
862	FILE *fp;
863	struct stat st;
864	const char *fname = "/proc/curproc/status";
865	char s_executable[MAXPATHLEN];
866	int s_pid, s_ppid;
867	/*
868	 * Format:
869	 *  EXECUTABLE PID PPID ...
870	 */
871
872	ATF_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT));
873	if (rv != 0) {
874		atf_tc_skip("/proc/curproc/status not found");
875	}
876
877	printf("Spawn tracee\n");
878	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
879	ATF_REQUIRE(msg_open(&parent_tracer) == 0);
880	tracee = atf_utils_fork();
881	if (tracee == 0) {
882		parent = getppid();
883
884		// Wait for parent to let us exit
885		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
886		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
887
888		FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
889		fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
890		FORKEE_ASSERT(fclose(fp) == 0);
891		FORKEE_ASSERT_EQ(parent, s_ppid);
892
893		_exit(exitval_tracee);
894	}
895
896	printf("Wait for child to record its parent identifier (pid)\n");
897	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
898
899	printf("Spawn debugger\n");
900	tracer = atf_utils_fork();
901	if (tracer == 0) {
902		printf("Before calling PT_ATTACH from tracee %d\n", getpid());
903		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
904
905		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
906		FORKEE_REQUIRE_SUCCESS(
907		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
908
909		forkee_status_stopped(status, SIGSTOP);
910
911		/* Resume tracee with PT_CONTINUE */
912		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
913
914		/* Inform parent that tracer has attached to tracee */
915		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
916
917		/* Wait for parent to tell use that tracee should have exited */
918		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
919
920		/* Wait for tracee and assert that it exited */
921		FORKEE_REQUIRE_SUCCESS(
922		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
923
924		forkee_status_exited(status, exitval_tracee);
925
926		printf("Before exiting of the tracer process\n");
927		_exit(exitval_tracer);
928	}
929	printf("Wait for the tracer to attach to the tracee\n");
930	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
931	printf("Resume the tracee and let it exit\n");
932	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
933
934	printf("Detect that tracee is zombie\n");
935	await_zombie(tracee);
936
937	printf("Assert that there is no status about tracee - "
938	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
939	TWAIT_REQUIRE_SUCCESS(
940	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
941
942	printf("Resume the tracer and let it detect exited tracee\n");
943	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
944
945	printf("Wait for tracer to finish its job and exit - calling %s()\n",
946	    TWAIT_FNAME);
947	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
948	    tracer);
949
950	validate_status_exited(status, exitval_tracer);
951
952	printf("Wait for tracee to finish its job and exit - calling %s()\n",
953	    TWAIT_FNAME);
954	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
955	    tracee);
956
957	validate_status_exited(status, exitval_tracee);
958
959	msg_close(&parent_tracee);
960	msg_close(&parent_tracer);
961}
962#endif
963
964ATF_TC(eventmask1);
965ATF_TC_HEAD(eventmask1, tc)
966{
967	atf_tc_set_md_var(tc, "descr",
968	    "Verify that empty EVENT_MASK is preserved");
969}
970
971ATF_TC_BODY(eventmask1, tc)
972{
973	const int exitval = 5;
974	const int sigval = SIGSTOP;
975	pid_t child, wpid;
976#if defined(TWAIT_HAVE_STATUS)
977	int status;
978#endif
979	ptrace_event_t set_event, get_event;
980	const int len = sizeof(ptrace_event_t);
981
982	printf("Before forking process PID=%d\n", getpid());
983	ATF_REQUIRE((child = fork()) != -1);
984	if (child == 0) {
985		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
986		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
987
988		printf("Before raising %s from child\n", strsignal(sigval));
989		FORKEE_ASSERT(raise(sigval) == 0);
990
991		printf("Before exiting of the child process\n");
992		_exit(exitval);
993	}
994	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
995
996	printf("Before calling %s() for the child\n", TWAIT_FNAME);
997	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
998
999	validate_status_stopped(status, sigval);
1000
1001	set_event.pe_set_event = 0;
1002	ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1003	ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1004	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1005
1006	printf("Before resuming the child process where it left off and "
1007	    "without signal to be sent\n");
1008	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1009
1010	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1011	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1012
1013	validate_status_exited(status, exitval);
1014
1015	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1016	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1017}
1018
1019ATF_TC(eventmask2);
1020ATF_TC_HEAD(eventmask2, tc)
1021{
1022	atf_tc_set_md_var(tc, "descr",
1023	    "Verify that PTRACE_FORK in EVENT_MASK is preserved");
1024}
1025
1026ATF_TC_BODY(eventmask2, tc)
1027{
1028	const int exitval = 5;
1029	const int sigval = SIGSTOP;
1030	pid_t child, wpid;
1031#if defined(TWAIT_HAVE_STATUS)
1032	int status;
1033#endif
1034	ptrace_event_t set_event, get_event;
1035	const int len = sizeof(ptrace_event_t);
1036
1037	printf("Before forking process PID=%d\n", getpid());
1038	ATF_REQUIRE((child = fork()) != -1);
1039	if (child == 0) {
1040		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1041		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1042
1043		printf("Before raising %s from child\n", strsignal(sigval));
1044		FORKEE_ASSERT(raise(sigval) == 0);
1045
1046		printf("Before exiting of the child process\n");
1047		_exit(exitval);
1048	}
1049	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1050
1051	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1052	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1053
1054	validate_status_stopped(status, sigval);
1055
1056	set_event.pe_set_event = PTRACE_FORK;
1057	ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
1058	ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
1059	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
1060
1061	printf("Before resuming the child process where it left off and "
1062	    "without signal to be sent\n");
1063	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1064
1065	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1066	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1067
1068	validate_status_exited(status, exitval);
1069
1070	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1071	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1072}
1073
1074#if defined(TWAIT_HAVE_PID)
1075ATF_TC(fork1);
1076ATF_TC_HEAD(fork1, tc)
1077{
1078	atf_tc_set_md_var(tc, "descr",
1079	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
1080	    "set to PTRACE_FORK");
1081}
1082
1083ATF_TC_BODY(fork1, tc)
1084{
1085	const int exitval = 5;
1086	const int exitval2 = 15;
1087	const int sigval = SIGSTOP;
1088	pid_t child, child2, wpid;
1089#if defined(TWAIT_HAVE_STATUS)
1090	int status;
1091#endif
1092	ptrace_state_t state;
1093	const int slen = sizeof(state);
1094	ptrace_event_t event;
1095	const int elen = sizeof(event);
1096
1097	printf("Before forking process PID=%d\n", getpid());
1098	ATF_REQUIRE((child = fork()) != -1);
1099	if (child == 0) {
1100		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1101		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1102
1103		printf("Before raising %s from child\n", strsignal(sigval));
1104		FORKEE_ASSERT(raise(sigval) == 0);
1105
1106		FORKEE_ASSERT((child2 = fork()) != 1);
1107
1108		if (child2 == 0)
1109			_exit(exitval2);
1110
1111		FORKEE_REQUIRE_SUCCESS
1112		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1113
1114		forkee_status_exited(status, exitval2);
1115
1116		printf("Before exiting of the child process\n");
1117		_exit(exitval);
1118	}
1119	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1120
1121	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1122	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1123
1124	validate_status_stopped(status, sigval);
1125
1126	printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
1127	event.pe_set_event = PTRACE_FORK;
1128	ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1129
1130	printf("Before resuming the child process where it left off and "
1131	    "without signal to be sent\n");
1132	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1133
1134	printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
1135	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1136
1137	validate_status_stopped(status, SIGTRAP);
1138
1139	ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1140	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
1141
1142	child2 = state.pe_other_pid;
1143	printf("Reported PTRACE_FORK event with forkee %d\n", child2);
1144
1145	printf("Before calling %s() for the forkee %d of the child %d\n",
1146	    TWAIT_FNAME, child2, child);
1147	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1148	    child2);
1149
1150	validate_status_stopped(status, SIGTRAP);
1151
1152	ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
1153	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
1154	ATF_REQUIRE_EQ(state.pe_other_pid, child);
1155
1156	printf("Before resuming the forkee process where it left off and "
1157	    "without signal to be sent\n");
1158	ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
1159
1160	printf("Before resuming the child process where it left off and "
1161	    "without signal to be sent\n");
1162	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1163
1164	printf("Before calling %s() for the forkee - expected exited\n",
1165	    TWAIT_FNAME);
1166	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1167	    child2);
1168
1169	validate_status_exited(status, exitval2);
1170
1171	printf("Before calling %s() for the forkee - expected no process\n",
1172	    TWAIT_FNAME);
1173	TWAIT_REQUIRE_FAILURE(ECHILD,
1174	    wpid = TWAIT_GENERIC(child2, &status, 0));
1175
1176	printf("Before calling %s() for the child - expected stopped "
1177	    "SIGCHLD\n", TWAIT_FNAME);
1178	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1179
1180	validate_status_stopped(status, SIGCHLD);
1181
1182	printf("Before resuming the child process where it left off and "
1183	    "without signal to be sent\n");
1184	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1185
1186	printf("Before calling %s() for the child - expected exited\n",
1187	    TWAIT_FNAME);
1188	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1189
1190	validate_status_exited(status, exitval);
1191
1192	printf("Before calling %s() for the child - expected no process\n",
1193	    TWAIT_FNAME);
1194	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1195}
1196#endif
1197
1198ATF_TC(fork2);
1199ATF_TC_HEAD(fork2, tc)
1200{
1201	atf_tc_set_md_var(tc, "descr",
1202	    "Verify that fork(2) is not intercepted by ptrace(2) with empty "
1203	    "EVENT_MASK");
1204}
1205
1206ATF_TC_BODY(fork2, tc)
1207{
1208	const int exitval = 5;
1209	const int exitval2 = 15;
1210	const int sigval = SIGSTOP;
1211	pid_t child, child2, wpid;
1212#if defined(TWAIT_HAVE_STATUS)
1213	int status;
1214#endif
1215	ptrace_event_t event;
1216	const int elen = sizeof(event);
1217
1218	printf("Before forking process PID=%d\n", getpid());
1219	ATF_REQUIRE((child = fork()) != -1);
1220	if (child == 0) {
1221		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1222		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1223
1224		printf("Before raising %s from child\n", strsignal(sigval));
1225		FORKEE_ASSERT(raise(sigval) == 0);
1226
1227		FORKEE_ASSERT((child2 = fork()) != 1);
1228
1229		if (child2 == 0)
1230			_exit(exitval2);
1231
1232		FORKEE_REQUIRE_SUCCESS
1233		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1234
1235		forkee_status_exited(status, exitval2);
1236
1237		printf("Before exiting of the child process\n");
1238		_exit(exitval);
1239	}
1240	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1241
1242	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1243	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1244
1245	validate_status_stopped(status, sigval);
1246
1247	printf("Set empty EVENT_MASK for the child %d\n", child);
1248	event.pe_set_event = 0;
1249	ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1250
1251	printf("Before resuming the child process where it left off and "
1252	    "without signal to be sent\n");
1253	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1254
1255	printf("Before calling %s() for the child - expected stopped "
1256	    "SIGCHLD\n", TWAIT_FNAME);
1257	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1258
1259	validate_status_stopped(status, SIGCHLD);
1260
1261	printf("Before resuming the child process where it left off and "
1262	    "without signal to be sent\n");
1263	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1264
1265	printf("Before calling %s() for the child - expected exited\n",
1266	    TWAIT_FNAME);
1267	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1268
1269	validate_status_exited(status, exitval);
1270
1271	printf("Before calling %s() for the child - expected no process\n",
1272	    TWAIT_FNAME);
1273	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1274}
1275
1276#if defined(TWAIT_HAVE_PID)
1277ATF_TC(vfork1);
1278ATF_TC_HEAD(vfork1, tc)
1279{
1280	atf_tc_set_md_var(tc, "descr",
1281	    "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK "
1282	    "set to PTRACE_VFORK");
1283}
1284
1285ATF_TC_BODY(vfork1, tc)
1286{
1287	const int exitval = 5;
1288	const int exitval2 = 15;
1289	const int sigval = SIGSTOP;
1290	pid_t child, child2, wpid;
1291#if defined(TWAIT_HAVE_STATUS)
1292	int status;
1293#endif
1294	ptrace_state_t state;
1295	const int slen = sizeof(state);
1296	ptrace_event_t event;
1297	const int elen = sizeof(event);
1298
1299	/*
1300	 * ptrace(2) command PT_SET_EVENT_MASK: option PTRACE_VFORK unsupported
1301	 */
1302#ifndef PTRACE_VFORK
1303#define PTRACE_VFORK 0
1304#endif
1305	atf_tc_expect_fail("PR kern/51630");
1306
1307	printf("Before forking process PID=%d\n", getpid());
1308	ATF_REQUIRE((child = fork()) != -1);
1309	if (child == 0) {
1310		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1311		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1312
1313		printf("Before raising %s from child\n", strsignal(sigval));
1314		FORKEE_ASSERT(raise(sigval) == 0);
1315
1316		FORKEE_ASSERT((child2 = vfork()) != 1);
1317
1318		if (child2 == 0)
1319			_exit(exitval2);
1320
1321		FORKEE_REQUIRE_SUCCESS
1322		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1323
1324		forkee_status_exited(status, exitval2);
1325
1326		printf("Before exiting of the child process\n");
1327		_exit(exitval);
1328	}
1329	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1330
1331	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1332	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1333
1334	validate_status_stopped(status, sigval);
1335
1336	printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child);
1337	event.pe_set_event = PTRACE_VFORK;
1338	ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1339
1340	printf("Before resuming the child process where it left off and "
1341	    "without signal to be sent\n");
1342	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1343
1344	printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
1345	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1346
1347	validate_status_stopped(status, SIGTRAP);
1348
1349	ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1350	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
1351
1352	child2 = state.pe_other_pid;
1353	printf("Reported PTRACE_VFORK event with forkee %d\n", child2);
1354
1355	printf("Before calling %s() for the forkee %d of the child %d\n",
1356	    TWAIT_FNAME, child2, child);
1357	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1358	    child2);
1359
1360	validate_status_stopped(status, SIGTRAP);
1361
1362	ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
1363	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK);
1364	ATF_REQUIRE_EQ(state.pe_other_pid, child);
1365
1366	printf("Before resuming the forkee process where it left off and "
1367	    "without signal to be sent\n");
1368	ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
1369
1370	printf("Before resuming the child process where it left off and "
1371	    "without signal to be sent\n");
1372	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1373
1374	printf("Before calling %s() for the forkee - expected exited\n",
1375	    TWAIT_FNAME);
1376	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
1377	    child2);
1378
1379	validate_status_exited(status, exitval2);
1380
1381	printf("Before calling %s() for the forkee - expected no process\n",
1382	    TWAIT_FNAME);
1383	TWAIT_REQUIRE_FAILURE(ECHILD,
1384	    wpid = TWAIT_GENERIC(child2, &status, 0));
1385
1386	printf("Before calling %s() for the child - expected stopped "
1387	    "SIGCHLD\n", TWAIT_FNAME);
1388	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1389
1390	validate_status_stopped(status, SIGCHLD);
1391
1392	printf("Before resuming the child process where it left off and "
1393	    "without signal to be sent\n");
1394	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1395
1396	printf("Before calling %s() for the child - expected exited\n",
1397	    TWAIT_FNAME);
1398	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1399
1400	validate_status_exited(status, exitval);
1401
1402	printf("Before calling %s() for the child - expected no process\n",
1403	    TWAIT_FNAME);
1404	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1405}
1406#endif
1407
1408ATF_TC(vfork2);
1409ATF_TC_HEAD(vfork2, tc)
1410{
1411	atf_tc_set_md_var(tc, "descr",
1412	    "Verify that vfork(2) is not intercepted by ptrace(2) with empty "
1413	    "EVENT_MASK");
1414}
1415
1416ATF_TC_BODY(vfork2, tc)
1417{
1418	const int exitval = 5;
1419	const int exitval2 = 15;
1420	const int sigval = SIGSTOP;
1421	pid_t child, child2, wpid;
1422#if defined(TWAIT_HAVE_STATUS)
1423	int status;
1424#endif
1425	ptrace_event_t event;
1426	const int elen = sizeof(event);
1427
1428	printf("Before forking process PID=%d\n", getpid());
1429	ATF_REQUIRE((child = fork()) != -1);
1430	if (child == 0) {
1431		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1432		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1433
1434		printf("Before raising %s from child\n", strsignal(sigval));
1435		FORKEE_ASSERT(raise(sigval) == 0);
1436
1437		FORKEE_ASSERT((child2 = vfork()) != 1);
1438
1439		if (child2 == 0)
1440			_exit(exitval2);
1441
1442		FORKEE_REQUIRE_SUCCESS
1443		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
1444
1445		forkee_status_exited(status, exitval2);
1446
1447		printf("Before exiting of the child process\n");
1448		_exit(exitval);
1449	}
1450	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1451
1452	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1453	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1454
1455	validate_status_stopped(status, sigval);
1456
1457	printf("Set empty EVENT_MASK for the child %d\n", child);
1458	event.pe_set_event = 0;
1459	ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1460
1461	printf("Before resuming the child process where it left off and "
1462	    "without signal to be sent\n");
1463	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1464
1465	printf("Before calling %s() for the child - expected stopped "
1466	    "SIGCHLD\n", TWAIT_FNAME);
1467	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1468
1469	validate_status_stopped(status, SIGCHLD);
1470
1471	printf("Before resuming the child process where it left off and "
1472	    "without signal to be sent\n");
1473	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1474
1475	printf("Before calling %s() for the child - expected exited\n",
1476	    TWAIT_FNAME);
1477	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1478
1479	validate_status_exited(status, exitval);
1480
1481	printf("Before calling %s() for the child - expected no process\n",
1482	    TWAIT_FNAME);
1483	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1484}
1485
1486ATF_TC(io_read_d1);
1487ATF_TC_HEAD(io_read_d1, tc)
1488{
1489	atf_tc_set_md_var(tc, "descr",
1490	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)");
1491}
1492
1493ATF_TC_BODY(io_read_d1, tc)
1494{
1495	const int exitval = 5;
1496	const int sigval = SIGSTOP;
1497	pid_t child, wpid;
1498	uint8_t lookup_me = 0;
1499	const uint8_t magic = 0xab;
1500	struct ptrace_io_desc io = {
1501		.piod_op = PIOD_READ_D,
1502		.piod_offs = &lookup_me,
1503		.piod_addr = &lookup_me,
1504		.piod_len = sizeof(lookup_me)
1505	};
1506#if defined(TWAIT_HAVE_STATUS)
1507	int status;
1508#endif
1509
1510	printf("Before forking process PID=%d\n", getpid());
1511	ATF_REQUIRE((child = fork()) != -1);
1512	if (child == 0) {
1513		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1514		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1515
1516		lookup_me = magic;
1517
1518		printf("Before raising %s from child\n", strsignal(sigval));
1519		FORKEE_ASSERT(raise(sigval) == 0);
1520
1521		printf("Before exiting of the child process\n");
1522		_exit(exitval);
1523	}
1524	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1525
1526	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1527	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1528
1529	validate_status_stopped(status, sigval);
1530
1531	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
1532	    child, getpid());
1533	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1534
1535	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
1536	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
1537
1538	printf("Before resuming the child process where it left off and "
1539	    "without signal to be sent\n");
1540	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1541
1542	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1543	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1544
1545	validate_status_exited(status, exitval);
1546
1547	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1548	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1549}
1550
1551ATF_TC(io_read_d2);
1552ATF_TC_HEAD(io_read_d2, tc)
1553{
1554	atf_tc_set_md_var(tc, "descr",
1555	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)");
1556}
1557
1558ATF_TC_BODY(io_read_d2, tc)
1559{
1560	const int exitval = 5;
1561	const int sigval = SIGSTOP;
1562	pid_t child, wpid;
1563	uint16_t lookup_me = 0;
1564	const uint16_t magic = 0x1234;
1565	struct ptrace_io_desc io = {
1566		.piod_op = PIOD_READ_D,
1567		.piod_offs = &lookup_me,
1568		.piod_addr = &lookup_me,
1569		.piod_len = sizeof(lookup_me)
1570	};
1571#if defined(TWAIT_HAVE_STATUS)
1572	int status;
1573#endif
1574
1575	printf("Before forking process PID=%d\n", getpid());
1576	ATF_REQUIRE((child = fork()) != -1);
1577	if (child == 0) {
1578		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1579		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1580
1581		lookup_me = magic;
1582
1583		printf("Before raising %s from child\n", strsignal(sigval));
1584		FORKEE_ASSERT(raise(sigval) == 0);
1585
1586		printf("Before exiting of the child process\n");
1587		_exit(exitval);
1588	}
1589	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1590
1591	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1592	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1593
1594	validate_status_stopped(status, sigval);
1595
1596	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
1597	    child, getpid());
1598	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1599
1600	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
1601	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
1602
1603	printf("Before resuming the child process where it left off and "
1604	    "without signal to be sent\n");
1605	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1606
1607	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1608	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1609
1610	validate_status_exited(status, exitval);
1611
1612	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1613	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1614}
1615
1616ATF_TC(io_read_d3);
1617ATF_TC_HEAD(io_read_d3, tc)
1618{
1619	atf_tc_set_md_var(tc, "descr",
1620	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)");
1621}
1622
1623ATF_TC_BODY(io_read_d3, tc)
1624{
1625	const int exitval = 5;
1626	const int sigval = SIGSTOP;
1627	pid_t child, wpid;
1628	uint32_t lookup_me = 0;
1629	const uint32_t magic = 0x1234abcd;
1630	struct ptrace_io_desc io = {
1631		.piod_op = PIOD_READ_D,
1632		.piod_offs = &lookup_me,
1633		.piod_addr = &lookup_me,
1634		.piod_len = sizeof(lookup_me)
1635	};
1636#if defined(TWAIT_HAVE_STATUS)
1637	int status;
1638#endif
1639
1640	printf("Before forking process PID=%d\n", getpid());
1641	ATF_REQUIRE((child = fork()) != -1);
1642	if (child == 0) {
1643		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1644		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1645
1646		lookup_me = magic;
1647
1648		printf("Before raising %s from child\n", strsignal(sigval));
1649		FORKEE_ASSERT(raise(sigval) == 0);
1650
1651		printf("Before exiting of the child process\n");
1652		_exit(exitval);
1653	}
1654	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1655
1656	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1657	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1658
1659	validate_status_stopped(status, sigval);
1660
1661	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
1662	    child, getpid());
1663	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1664
1665	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
1666	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
1667
1668	printf("Before resuming the child process where it left off and "
1669	    "without signal to be sent\n");
1670	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1671
1672	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1673	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1674
1675	validate_status_exited(status, exitval);
1676
1677	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1678	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1679}
1680
1681ATF_TC(io_read_d4);
1682ATF_TC_HEAD(io_read_d4, tc)
1683{
1684	atf_tc_set_md_var(tc, "descr",
1685	    "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)");
1686}
1687
1688ATF_TC_BODY(io_read_d4, tc)
1689{
1690	const int exitval = 5;
1691	const int sigval = SIGSTOP;
1692	pid_t child, wpid;
1693	uint64_t lookup_me = 0;
1694	const uint64_t magic = 0x1234abcd9876dcfa;
1695	struct ptrace_io_desc io = {
1696		.piod_op = PIOD_READ_D,
1697		.piod_offs = &lookup_me,
1698		.piod_addr = &lookup_me,
1699		.piod_len = sizeof(lookup_me)
1700	};
1701#if defined(TWAIT_HAVE_STATUS)
1702	int status;
1703#endif
1704
1705	printf("Before forking process PID=%d\n", getpid());
1706	ATF_REQUIRE((child = fork()) != -1);
1707	if (child == 0) {
1708		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1709		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1710
1711		lookup_me = magic;
1712
1713		printf("Before raising %s from child\n", strsignal(sigval));
1714		FORKEE_ASSERT(raise(sigval) == 0);
1715
1716		printf("Before exiting of the child process\n");
1717		_exit(exitval);
1718	}
1719	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1720
1721	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1722	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1723
1724	validate_status_stopped(status, sigval);
1725
1726	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
1727	    child, getpid());
1728	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1729
1730	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
1731	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
1732
1733	printf("Before resuming the child process where it left off and "
1734	    "without signal to be sent\n");
1735	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1736
1737	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1738	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1739
1740	validate_status_exited(status, exitval);
1741
1742	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1743	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1744}
1745
1746ATF_TC(io_write_d1);
1747ATF_TC_HEAD(io_write_d1, tc)
1748{
1749	atf_tc_set_md_var(tc, "descr",
1750	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)");
1751}
1752
1753ATF_TC_BODY(io_write_d1, tc)
1754{
1755	const int exitval = 5;
1756	const int sigval = SIGSTOP;
1757	pid_t child, wpid;
1758	uint8_t lookup_me = 0;
1759	const uint8_t magic = 0xab;
1760	struct ptrace_io_desc io = {
1761		.piod_op = PIOD_WRITE_D,
1762		.piod_offs = &lookup_me,
1763		.piod_addr = &lookup_me,
1764		.piod_len = sizeof(lookup_me)
1765	};
1766#if defined(TWAIT_HAVE_STATUS)
1767	int status;
1768#endif
1769
1770	printf("Before forking process PID=%d\n", getpid());
1771	ATF_REQUIRE((child = fork()) != -1);
1772	if (child == 0) {
1773		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1774		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1775
1776		printf("Before raising %s from child\n", strsignal(sigval));
1777		FORKEE_ASSERT(raise(sigval) == 0);
1778
1779		FORKEE_ASSERT_EQ(lookup_me, magic);
1780
1781		printf("Before exiting of the child process\n");
1782		_exit(exitval);
1783	}
1784	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1785
1786	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1787	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1788
1789	validate_status_stopped(status, sigval);
1790
1791	lookup_me = magic;
1792
1793	printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
1794	    child, getpid());
1795	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1796
1797	printf("Before resuming the child process where it left off and "
1798	    "without signal to be sent\n");
1799	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1800
1801	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1802	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1803
1804	validate_status_exited(status, exitval);
1805
1806	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1807	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1808}
1809
1810ATF_TC(io_write_d2);
1811ATF_TC_HEAD(io_write_d2, tc)
1812{
1813	atf_tc_set_md_var(tc, "descr",
1814	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)");
1815}
1816
1817ATF_TC_BODY(io_write_d2, tc)
1818{
1819	const int exitval = 5;
1820	const int sigval = SIGSTOP;
1821	pid_t child, wpid;
1822	uint16_t lookup_me = 0;
1823	const uint16_t magic = 0xab12;
1824	struct ptrace_io_desc io = {
1825		.piod_op = PIOD_WRITE_D,
1826		.piod_offs = &lookup_me,
1827		.piod_addr = &lookup_me,
1828		.piod_len = sizeof(lookup_me)
1829	};
1830#if defined(TWAIT_HAVE_STATUS)
1831	int status;
1832#endif
1833
1834	printf("Before forking process PID=%d\n", getpid());
1835	ATF_REQUIRE((child = fork()) != -1);
1836	if (child == 0) {
1837		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1838		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1839
1840		printf("Before raising %s from child\n", strsignal(sigval));
1841		FORKEE_ASSERT(raise(sigval) == 0);
1842
1843		FORKEE_ASSERT_EQ(lookup_me, magic);
1844
1845		printf("Before exiting of the child process\n");
1846		_exit(exitval);
1847	}
1848	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1849
1850	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1851	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1852
1853	validate_status_stopped(status, sigval);
1854
1855	lookup_me = magic;
1856
1857	printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
1858	    child, getpid());
1859	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1860
1861	printf("Before resuming the child process where it left off and "
1862	    "without signal to be sent\n");
1863	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1864
1865	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1866	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1867
1868	validate_status_exited(status, exitval);
1869
1870	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1871	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1872}
1873
1874ATF_TC(io_write_d3);
1875ATF_TC_HEAD(io_write_d3, tc)
1876{
1877	atf_tc_set_md_var(tc, "descr",
1878	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)");
1879}
1880
1881ATF_TC_BODY(io_write_d3, tc)
1882{
1883	const int exitval = 5;
1884	const int sigval = SIGSTOP;
1885	pid_t child, wpid;
1886	uint32_t lookup_me = 0;
1887	const uint32_t magic = 0xab127643;
1888	struct ptrace_io_desc io = {
1889		.piod_op = PIOD_WRITE_D,
1890		.piod_offs = &lookup_me,
1891		.piod_addr = &lookup_me,
1892		.piod_len = sizeof(lookup_me)
1893	};
1894#if defined(TWAIT_HAVE_STATUS)
1895	int status;
1896#endif
1897
1898	printf("Before forking process PID=%d\n", getpid());
1899	ATF_REQUIRE((child = fork()) != -1);
1900	if (child == 0) {
1901		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1902		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1903
1904		printf("Before raising %s from child\n", strsignal(sigval));
1905		FORKEE_ASSERT(raise(sigval) == 0);
1906
1907		FORKEE_ASSERT_EQ(lookup_me, magic);
1908
1909		printf("Before exiting of the child process\n");
1910		_exit(exitval);
1911	}
1912	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1913
1914	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1915	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1916
1917	validate_status_stopped(status, sigval);
1918
1919	lookup_me = magic;
1920
1921	printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
1922	    child, getpid());
1923	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1924
1925	printf("Before resuming the child process where it left off and "
1926	    "without signal to be sent\n");
1927	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1928
1929	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1930	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1931
1932	validate_status_exited(status, exitval);
1933
1934	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1935	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1936}
1937
1938ATF_TC(io_write_d4);
1939ATF_TC_HEAD(io_write_d4, tc)
1940{
1941	atf_tc_set_md_var(tc, "descr",
1942	    "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)");
1943}
1944
1945ATF_TC_BODY(io_write_d4, tc)
1946{
1947	const int exitval = 5;
1948	const int sigval = SIGSTOP;
1949	pid_t child, wpid;
1950	uint64_t lookup_me = 0;
1951	const uint64_t magic = 0xab12764376490123;
1952	struct ptrace_io_desc io = {
1953		.piod_op = PIOD_WRITE_D,
1954		.piod_offs = &lookup_me,
1955		.piod_addr = &lookup_me,
1956		.piod_len = sizeof(lookup_me)
1957	};
1958#if defined(TWAIT_HAVE_STATUS)
1959	int status;
1960#endif
1961
1962	printf("Before forking process PID=%d\n", getpid());
1963	ATF_REQUIRE((child = fork()) != -1);
1964	if (child == 0) {
1965		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1966		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1967
1968		printf("Before raising %s from child\n", strsignal(sigval));
1969		FORKEE_ASSERT(raise(sigval) == 0);
1970
1971		FORKEE_ASSERT_EQ(lookup_me, magic);
1972
1973		printf("Before exiting of the child process\n");
1974		_exit(exitval);
1975	}
1976	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1977
1978	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1979	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1980
1981	validate_status_stopped(status, sigval);
1982
1983	lookup_me = magic;
1984
1985	printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
1986	    child, getpid());
1987	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
1988
1989	printf("Before resuming the child process where it left off and "
1990	    "without signal to be sent\n");
1991	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1992
1993	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1994	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1995
1996	validate_status_exited(status, exitval);
1997
1998	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1999	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2000}
2001
2002ATF_TC(read_d1);
2003ATF_TC_HEAD(read_d1, tc)
2004{
2005	atf_tc_set_md_var(tc, "descr",
2006	    "Verify PT_READ_D called once");
2007}
2008
2009ATF_TC_BODY(read_d1, tc)
2010{
2011	const int exitval = 5;
2012	const int sigval = SIGSTOP;
2013	pid_t child, wpid;
2014	int lookup_me = 0;
2015	const int magic = (int)random();
2016#if defined(TWAIT_HAVE_STATUS)
2017	int status;
2018#endif
2019
2020	printf("Before forking process PID=%d\n", getpid());
2021	ATF_REQUIRE((child = fork()) != -1);
2022	if (child == 0) {
2023		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2024		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2025
2026		lookup_me = magic;
2027
2028		printf("Before raising %s from child\n", strsignal(sigval));
2029		FORKEE_ASSERT(raise(sigval) == 0);
2030
2031		printf("Before exiting of the child process\n");
2032		_exit(exitval);
2033	}
2034	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2035
2036	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2037	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2038
2039	validate_status_stopped(status, sigval);
2040
2041	printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2042	    child, getpid());
2043	errno = 0;
2044	lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0);
2045	ATF_REQUIRE_EQ(errno, 0);
2046
2047	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
2048	    "got value %#x != expected %#x", lookup_me, magic);
2049
2050	printf("Before resuming the child process where it left off and "
2051	    "without signal to be sent\n");
2052	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2053
2054	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2055	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2056
2057	validate_status_exited(status, exitval);
2058
2059	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2060	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2061}
2062
2063ATF_TC(read_d2);
2064ATF_TC_HEAD(read_d2, tc)
2065{
2066	atf_tc_set_md_var(tc, "descr",
2067	    "Verify PT_READ_D called twice");
2068}
2069
2070ATF_TC_BODY(read_d2, tc)
2071{
2072	const int exitval = 5;
2073	const int sigval = SIGSTOP;
2074	pid_t child, wpid;
2075	int lookup_me1 = 0;
2076	int lookup_me2 = 0;
2077	const int magic1 = (int)random();
2078	const int magic2 = (int)random();
2079#if defined(TWAIT_HAVE_STATUS)
2080	int status;
2081#endif
2082
2083	printf("Before forking process PID=%d\n", getpid());
2084	ATF_REQUIRE((child = fork()) != -1);
2085	if (child == 0) {
2086		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2087		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2088
2089		lookup_me1 = magic1;
2090		lookup_me2 = magic2;
2091
2092		printf("Before raising %s from child\n", strsignal(sigval));
2093		FORKEE_ASSERT(raise(sigval) == 0);
2094
2095		printf("Before exiting of the child process\n");
2096		_exit(exitval);
2097	}
2098	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2099
2100	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2101	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2102
2103	validate_status_stopped(status, sigval);
2104
2105	printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2106	    child, getpid());
2107	errno = 0;
2108	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2109	ATF_REQUIRE_EQ(errno, 0);
2110
2111	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2112	    "got value %#x != expected %#x", lookup_me1, magic1);
2113
2114	printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2115	    child, getpid());
2116	errno = 0;
2117	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2118	ATF_REQUIRE_EQ(errno, 0);
2119
2120	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2121	    "got value %#x != expected %#x", lookup_me2, magic2);
2122
2123	printf("Before resuming the child process where it left off and "
2124	    "without signal to be sent\n");
2125	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2126
2127	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2128	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2129
2130	validate_status_exited(status, exitval);
2131
2132	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2133	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2134}
2135
2136ATF_TC(read_d3);
2137ATF_TC_HEAD(read_d3, tc)
2138{
2139	atf_tc_set_md_var(tc, "descr",
2140	    "Verify PT_READ_D called three times");
2141}
2142
2143ATF_TC_BODY(read_d3, tc)
2144{
2145	const int exitval = 5;
2146	const int sigval = SIGSTOP;
2147	pid_t child, wpid;
2148	int lookup_me1 = 0;
2149	int lookup_me2 = 0;
2150	int lookup_me3 = 0;
2151	const int magic1 = (int)random();
2152	const int magic2 = (int)random();
2153	const int magic3 = (int)random();
2154#if defined(TWAIT_HAVE_STATUS)
2155	int status;
2156#endif
2157
2158	printf("Before forking process PID=%d\n", getpid());
2159	ATF_REQUIRE((child = fork()) != -1);
2160	if (child == 0) {
2161		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2162		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2163
2164		lookup_me1 = magic1;
2165		lookup_me2 = magic2;
2166		lookup_me3 = magic3;
2167
2168		printf("Before raising %s from child\n", strsignal(sigval));
2169		FORKEE_ASSERT(raise(sigval) == 0);
2170
2171		printf("Before exiting of the child process\n");
2172		_exit(exitval);
2173	}
2174	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2175
2176	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2177	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2178
2179	validate_status_stopped(status, sigval);
2180
2181	printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2182	    child, getpid());
2183	errno = 0;
2184	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2185	ATF_REQUIRE_EQ(errno, 0);
2186
2187	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2188	    "got value %#x != expected %#x", lookup_me1, magic1);
2189
2190	printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2191	    child, getpid());
2192	errno = 0;
2193	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2194	ATF_REQUIRE_EQ(errno, 0);
2195
2196	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2197	    "got value %#x != expected %#x", lookup_me2, magic2);
2198
2199	printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
2200	    child, getpid());
2201	errno = 0;
2202	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
2203	ATF_REQUIRE_EQ(errno, 0);
2204
2205	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
2206	    "got value %#x != expected %#x", lookup_me3, magic3);
2207
2208	printf("Before resuming the child process where it left off and "
2209	    "without signal to be sent\n");
2210	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2211
2212	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2213	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2214
2215	validate_status_exited(status, exitval);
2216
2217	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2218	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2219}
2220
2221ATF_TC(read_d4);
2222ATF_TC_HEAD(read_d4, tc)
2223{
2224	atf_tc_set_md_var(tc, "descr",
2225	    "Verify PT_READ_D called four times");
2226}
2227
2228ATF_TC_BODY(read_d4, tc)
2229{
2230	const int exitval = 5;
2231	const int sigval = SIGSTOP;
2232	pid_t child, wpid;
2233	int lookup_me1 = 0;
2234	int lookup_me2 = 0;
2235	int lookup_me3 = 0;
2236	int lookup_me4 = 0;
2237	const int magic1 = (int)random();
2238	const int magic2 = (int)random();
2239	const int magic3 = (int)random();
2240	const int magic4 = (int)random();
2241#if defined(TWAIT_HAVE_STATUS)
2242	int status;
2243#endif
2244
2245	printf("Before forking process PID=%d\n", getpid());
2246	ATF_REQUIRE((child = fork()) != -1);
2247	if (child == 0) {
2248		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2249		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2250
2251		lookup_me1 = magic1;
2252		lookup_me2 = magic2;
2253		lookup_me3 = magic3;
2254		lookup_me4 = magic4;
2255
2256		printf("Before raising %s from child\n", strsignal(sigval));
2257		FORKEE_ASSERT(raise(sigval) == 0);
2258
2259		printf("Before exiting of the child process\n");
2260		_exit(exitval);
2261	}
2262	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2263
2264	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2265	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2266
2267	validate_status_stopped(status, sigval);
2268
2269	printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
2270	    child, getpid());
2271	errno = 0;
2272	lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0);
2273	ATF_REQUIRE_EQ(errno, 0);
2274
2275	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
2276	    "got value %#x != expected %#x", lookup_me1, magic1);
2277
2278	printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
2279	    child, getpid());
2280	errno = 0;
2281	lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0);
2282	ATF_REQUIRE_EQ(errno, 0);
2283
2284	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
2285	    "got value %#x != expected %#x", lookup_me2, magic2);
2286
2287	printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
2288	    child, getpid());
2289	errno = 0;
2290	lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0);
2291	ATF_REQUIRE_EQ(errno, 0);
2292
2293	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
2294	    "got value %#x != expected %#x", lookup_me3, magic3);
2295
2296	printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
2297	    child, getpid());
2298	errno = 0;
2299	lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0);
2300	ATF_REQUIRE_EQ(errno, 0);
2301
2302	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
2303	    "got value %#x != expected %#x", lookup_me4, magic4);
2304
2305	printf("Before resuming the child process where it left off and "
2306	    "without signal to be sent\n");
2307	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2308
2309	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2310	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2311
2312	validate_status_exited(status, exitval);
2313
2314	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2315	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2316}
2317
2318ATF_TC(write_d1);
2319ATF_TC_HEAD(write_d1, tc)
2320{
2321	atf_tc_set_md_var(tc, "descr",
2322	    "Verify PT_WRITE_D called once");
2323}
2324
2325ATF_TC_BODY(write_d1, tc)
2326{
2327	const int exitval = 5;
2328	const int sigval = SIGSTOP;
2329	pid_t child, wpid;
2330	int lookup_me = 0;
2331	const int magic = (int)random();
2332#if defined(TWAIT_HAVE_STATUS)
2333	int status;
2334#endif
2335
2336	printf("Before forking process PID=%d\n", getpid());
2337	ATF_REQUIRE((child = fork()) != -1);
2338	if (child == 0) {
2339		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2340		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2341
2342		printf("Before raising %s from child\n", strsignal(sigval));
2343		FORKEE_ASSERT(raise(sigval) == 0);
2344
2345		FORKEE_ASSERT_EQ(lookup_me, magic);
2346
2347		printf("Before exiting of the child process\n");
2348		_exit(exitval);
2349	}
2350	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2351
2352	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2353	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2354
2355	validate_status_stopped(status, sigval);
2356
2357	printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n",
2358	    child, getpid());
2359	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1);
2360
2361	printf("Before resuming the child process where it left off and "
2362	    "without signal to be sent\n");
2363	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2364
2365	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2366	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2367
2368	validate_status_exited(status, exitval);
2369
2370	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2371	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2372}
2373
2374ATF_TC(write_d2);
2375ATF_TC_HEAD(write_d2, tc)
2376{
2377	atf_tc_set_md_var(tc, "descr",
2378	    "Verify PT_WRITE_D called twice");
2379}
2380
2381ATF_TC_BODY(write_d2, tc)
2382{
2383	const int exitval = 5;
2384	const int sigval = SIGSTOP;
2385	pid_t child, wpid;
2386	int lookup_me1 = 0;
2387	int lookup_me2 = 0;
2388	const int magic1 = (int)random();
2389	const int magic2 = (int)random();
2390#if defined(TWAIT_HAVE_STATUS)
2391	int status;
2392#endif
2393
2394	printf("Before forking process PID=%d\n", getpid());
2395	ATF_REQUIRE((child = fork()) != -1);
2396	if (child == 0) {
2397		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2398		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2399
2400		printf("Before raising %s from child\n", strsignal(sigval));
2401		FORKEE_ASSERT(raise(sigval) == 0);
2402
2403		FORKEE_ASSERT_EQ(lookup_me1, magic1);
2404		FORKEE_ASSERT_EQ(lookup_me2, magic2);
2405
2406		printf("Before exiting of the child process\n");
2407		_exit(exitval);
2408	}
2409	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2410
2411	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2412	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2413
2414	validate_status_stopped(status, sigval);
2415
2416	printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
2417	    child, getpid());
2418	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
2419
2420	printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
2421	    child, getpid());
2422	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
2423
2424	printf("Before resuming the child process where it left off and "
2425	    "without signal to be sent\n");
2426	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2427
2428	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2429	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2430
2431	validate_status_exited(status, exitval);
2432
2433	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2434	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2435}
2436
2437ATF_TC(write_d3);
2438ATF_TC_HEAD(write_d3, tc)
2439{
2440	atf_tc_set_md_var(tc, "descr",
2441	    "Verify PT_WRITE_D called three times");
2442}
2443
2444ATF_TC_BODY(write_d3, tc)
2445{
2446	const int exitval = 5;
2447	const int sigval = SIGSTOP;
2448	pid_t child, wpid;
2449	int lookup_me1 = 0;
2450	int lookup_me2 = 0;
2451	int lookup_me3 = 0;
2452	const int magic1 = (int)random();
2453	const int magic2 = (int)random();
2454	const int magic3 = (int)random();
2455#if defined(TWAIT_HAVE_STATUS)
2456	int status;
2457#endif
2458
2459	printf("Before forking process PID=%d\n", getpid());
2460	ATF_REQUIRE((child = fork()) != -1);
2461	if (child == 0) {
2462		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2463		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2464
2465		printf("Before raising %s from child\n", strsignal(sigval));
2466		FORKEE_ASSERT(raise(sigval) == 0);
2467
2468		FORKEE_ASSERT_EQ(lookup_me1, magic1);
2469		FORKEE_ASSERT_EQ(lookup_me2, magic2);
2470		FORKEE_ASSERT_EQ(lookup_me3, magic3);
2471
2472		printf("Before exiting of the child process\n");
2473		_exit(exitval);
2474	}
2475	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2476
2477	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2478	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2479
2480	validate_status_stopped(status, sigval);
2481
2482	printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
2483	    child, getpid());
2484	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
2485
2486	printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
2487	    child, getpid());
2488	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
2489
2490	printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
2491	    child, getpid());
2492	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
2493
2494	printf("Before resuming the child process where it left off and "
2495	    "without signal to be sent\n");
2496	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2497
2498	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2499	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2500
2501	validate_status_exited(status, exitval);
2502
2503	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2504	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2505}
2506
2507ATF_TC(write_d4);
2508ATF_TC_HEAD(write_d4, tc)
2509{
2510	atf_tc_set_md_var(tc, "descr",
2511	    "Verify PT_WRITE_D called four times");
2512}
2513
2514ATF_TC_BODY(write_d4, tc)
2515{
2516	const int exitval = 5;
2517	const int sigval = SIGSTOP;
2518	pid_t child, wpid;
2519	int lookup_me1 = 0;
2520	int lookup_me2 = 0;
2521	int lookup_me3 = 0;
2522	int lookup_me4 = 0;
2523	const int magic1 = (int)random();
2524	const int magic2 = (int)random();
2525	const int magic3 = (int)random();
2526	const int magic4 = (int)random();
2527#if defined(TWAIT_HAVE_STATUS)
2528	int status;
2529#endif
2530
2531	printf("Before forking process PID=%d\n", getpid());
2532	ATF_REQUIRE((child = fork()) != -1);
2533	if (child == 0) {
2534		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2535		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2536
2537		printf("Before raising %s from child\n", strsignal(sigval));
2538		FORKEE_ASSERT(raise(sigval) == 0);
2539
2540		FORKEE_ASSERT_EQ(lookup_me1, magic1);
2541		FORKEE_ASSERT_EQ(lookup_me2, magic2);
2542		FORKEE_ASSERT_EQ(lookup_me3, magic3);
2543		FORKEE_ASSERT_EQ(lookup_me4, magic4);
2544
2545		printf("Before exiting of the child process\n");
2546		_exit(exitval);
2547	}
2548	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2549
2550	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2551	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2552
2553	validate_status_stopped(status, sigval);
2554
2555	printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n",
2556	    child, getpid());
2557	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1);
2558
2559	printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n",
2560	    child, getpid());
2561	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1);
2562
2563	printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n",
2564	    child, getpid());
2565	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1);
2566
2567	printf("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n",
2568	    child, getpid());
2569	ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1);
2570
2571	printf("Before resuming the child process where it left off and "
2572	    "without signal to be sent\n");
2573	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2574
2575	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2576	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2577
2578	validate_status_exited(status, exitval);
2579
2580	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2581	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2582}
2583
2584ATF_TC(io_read_d_write_d_handshake1);
2585ATF_TC_HEAD(io_read_d_write_d_handshake1, tc)
2586{
2587	atf_tc_set_md_var(tc, "descr",
2588	    "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake");
2589}
2590
2591ATF_TC_BODY(io_read_d_write_d_handshake1, tc)
2592{
2593	const int exitval = 5;
2594	const int sigval = SIGSTOP;
2595	pid_t child, wpid;
2596	uint8_t lookup_me_fromtracee = 0;
2597	const uint8_t magic_fromtracee = (uint8_t)random();
2598	uint8_t lookup_me_totracee = 0;
2599	const uint8_t magic_totracee = (uint8_t)random();
2600	struct ptrace_io_desc io_fromtracee = {
2601		.piod_op = PIOD_READ_D,
2602		.piod_offs = &lookup_me_fromtracee,
2603		.piod_addr = &lookup_me_fromtracee,
2604		.piod_len = sizeof(lookup_me_fromtracee)
2605	};
2606	struct ptrace_io_desc io_totracee = {
2607		.piod_op = PIOD_WRITE_D,
2608		.piod_offs = &lookup_me_totracee,
2609		.piod_addr = &lookup_me_totracee,
2610		.piod_len = sizeof(lookup_me_totracee)
2611	};
2612#if defined(TWAIT_HAVE_STATUS)
2613	int status;
2614#endif
2615
2616	printf("Before forking process PID=%d\n", getpid());
2617	ATF_REQUIRE((child = fork()) != -1);
2618	if (child == 0) {
2619		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2620		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2621
2622		lookup_me_fromtracee = magic_fromtracee;
2623
2624		printf("Before raising %s from child\n", strsignal(sigval));
2625		FORKEE_ASSERT(raise(sigval) == 0);
2626
2627		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
2628
2629		printf("Before exiting of the child process\n");
2630		_exit(exitval);
2631	}
2632	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2633
2634	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2635	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2636
2637	validate_status_stopped(status, sigval);
2638
2639	printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
2640	    child, getpid());
2641	ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
2642
2643	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
2644	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
2645	    magic_fromtracee);
2646
2647	lookup_me_totracee = magic_totracee;
2648
2649	printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
2650	    child, getpid());
2651	ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
2652
2653	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
2654	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
2655	    magic_totracee);
2656
2657	printf("Before resuming the child process where it left off and "
2658	    "without signal to be sent\n");
2659	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2660
2661	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2662	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2663
2664	validate_status_exited(status, exitval);
2665
2666	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2667	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2668}
2669
2670ATF_TC(io_read_d_write_d_handshake2);
2671ATF_TC_HEAD(io_read_d_write_d_handshake2, tc)
2672{
2673	atf_tc_set_md_var(tc, "descr",
2674	    "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake");
2675}
2676
2677ATF_TC_BODY(io_read_d_write_d_handshake2, tc)
2678{
2679	const int exitval = 5;
2680	const int sigval = SIGSTOP;
2681	pid_t child, wpid;
2682	uint8_t lookup_me_fromtracee = 0;
2683	const uint8_t magic_fromtracee = (uint8_t)random();
2684	uint8_t lookup_me_totracee = 0;
2685	const uint8_t magic_totracee = (uint8_t)random();
2686	struct ptrace_io_desc io_fromtracee = {
2687		.piod_op = PIOD_READ_D,
2688		.piod_offs = &lookup_me_fromtracee,
2689		.piod_addr = &lookup_me_fromtracee,
2690		.piod_len = sizeof(lookup_me_fromtracee)
2691	};
2692	struct ptrace_io_desc io_totracee = {
2693		.piod_op = PIOD_WRITE_D,
2694		.piod_offs = &lookup_me_totracee,
2695		.piod_addr = &lookup_me_totracee,
2696		.piod_len = sizeof(lookup_me_totracee)
2697	};
2698#if defined(TWAIT_HAVE_STATUS)
2699	int status;
2700#endif
2701
2702	printf("Before forking process PID=%d\n", getpid());
2703	ATF_REQUIRE((child = fork()) != -1);
2704	if (child == 0) {
2705		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2706		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2707
2708		lookup_me_fromtracee = magic_fromtracee;
2709
2710		printf("Before raising %s from child\n", strsignal(sigval));
2711		FORKEE_ASSERT(raise(sigval) == 0);
2712
2713		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
2714
2715		printf("Before exiting of the child process\n");
2716		_exit(exitval);
2717	}
2718	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2719
2720	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2721	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2722
2723	validate_status_stopped(status, sigval);
2724
2725	lookup_me_totracee = magic_totracee;
2726
2727	printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n",
2728	    child, getpid());
2729	ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1);
2730
2731	ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee,
2732	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee,
2733	    magic_totracee);
2734
2735	printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
2736	    child, getpid());
2737	ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1);
2738
2739	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
2740	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee,
2741	    magic_fromtracee);
2742
2743	printf("Before resuming the child process where it left off and "
2744	    "without signal to be sent\n");
2745	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2746
2747	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2748	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2749
2750	validate_status_exited(status, exitval);
2751
2752	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2753	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2754}
2755
2756ATF_TC(read_d_write_d_handshake1);
2757ATF_TC_HEAD(read_d_write_d_handshake1, tc)
2758{
2759	atf_tc_set_md_var(tc, "descr",
2760	    "Verify PT_READ_D with PT_WRITE_D handshake");
2761}
2762
2763ATF_TC_BODY(read_d_write_d_handshake1, tc)
2764{
2765	const int exitval = 5;
2766	const int sigval = SIGSTOP;
2767	pid_t child, wpid;
2768	int lookup_me_fromtracee = 0;
2769	const int magic_fromtracee = (int)random();
2770	int lookup_me_totracee = 0;
2771	const int magic_totracee = (int)random();
2772#if defined(TWAIT_HAVE_STATUS)
2773	int status;
2774#endif
2775
2776	printf("Before forking process PID=%d\n", getpid());
2777	ATF_REQUIRE((child = fork()) != -1);
2778	if (child == 0) {
2779		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2780		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2781
2782		lookup_me_fromtracee = magic_fromtracee;
2783
2784		printf("Before raising %s from child\n", strsignal(sigval));
2785		FORKEE_ASSERT(raise(sigval) == 0);
2786
2787		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
2788
2789		printf("Before exiting of the child process\n");
2790		_exit(exitval);
2791	}
2792	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2793
2794	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2795	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2796
2797	validate_status_stopped(status, sigval);
2798
2799	printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
2800	    child, getpid());
2801	errno = 0;
2802	lookup_me_fromtracee =
2803	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
2804	ATF_REQUIRE_EQ(errno, 0);
2805
2806	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
2807	    "got value %#x != expected %#x", lookup_me_fromtracee,
2808	    magic_fromtracee);
2809
2810	printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
2811	    child, getpid());
2812	ATF_REQUIRE
2813	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
2814	    != -1);
2815
2816	printf("Before resuming the child process where it left off and "
2817	    "without signal to be sent\n");
2818	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2819
2820	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2821	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2822
2823	validate_status_exited(status, exitval);
2824
2825	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2826	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2827}
2828
2829ATF_TC(read_d_write_d_handshake2);
2830ATF_TC_HEAD(read_d_write_d_handshake2, tc)
2831{
2832	atf_tc_set_md_var(tc, "descr",
2833	    "Verify PT_WRITE_D with PT_READ_D handshake");
2834}
2835
2836ATF_TC_BODY(read_d_write_d_handshake2, tc)
2837{
2838	const int exitval = 5;
2839	const int sigval = SIGSTOP;
2840	pid_t child, wpid;
2841	int lookup_me_fromtracee = 0;
2842	const int magic_fromtracee = (int)random();
2843	int lookup_me_totracee = 0;
2844	const int magic_totracee = (int)random();
2845#if defined(TWAIT_HAVE_STATUS)
2846	int status;
2847#endif
2848
2849	printf("Before forking process PID=%d\n", getpid());
2850	ATF_REQUIRE((child = fork()) != -1);
2851	if (child == 0) {
2852		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2853		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2854
2855		lookup_me_fromtracee = magic_fromtracee;
2856
2857		printf("Before raising %s from child\n", strsignal(sigval));
2858		FORKEE_ASSERT(raise(sigval) == 0);
2859
2860		FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee);
2861
2862		printf("Before exiting of the child process\n");
2863		_exit(exitval);
2864	}
2865	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2866
2867	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2868	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2869
2870	validate_status_stopped(status, sigval);
2871
2872	printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n",
2873	    child, getpid());
2874	ATF_REQUIRE
2875	    (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee)
2876	    != -1);
2877
2878	printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n",
2879	    child, getpid());
2880	errno = 0;
2881	lookup_me_fromtracee =
2882	    ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0);
2883	ATF_REQUIRE_EQ(errno, 0);
2884
2885	ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee,
2886	    "got value %#x != expected %#x", lookup_me_fromtracee,
2887	    magic_fromtracee);
2888
2889	printf("Before resuming the child process where it left off and "
2890	    "without signal to be sent\n");
2891	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2892
2893	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2894	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2895
2896	validate_status_exited(status, exitval);
2897
2898	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2899	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2900}
2901
2902/* These dummy functions are used to be copied with ptrace(2) calls */
2903static int __used
2904dummy_fn1(int a, int b, int c, int d)
2905{
2906
2907	a *= 1;
2908	b += 2;
2909	c -= 3;
2910	d /= 4;
2911
2912	return a + b * c - d;
2913}
2914
2915static int __used
2916dummy_fn2(int a, int b, int c, int d)
2917{
2918
2919	a *= 4;
2920	b += 3;
2921	c -= 2;
2922	d /= 1;
2923
2924	return a + b * c - d;
2925}
2926
2927static int __used
2928dummy_fn3(int a, int b, int c, int d)
2929{
2930
2931	a *= 10;
2932	b += 20;
2933	c -= 30;
2934	d /= 40;
2935
2936	return a + b * c - d;
2937}
2938
2939static int __used
2940dummy_fn4(int a, int b, int c, int d)
2941{
2942
2943	a *= 40;
2944	b += 30;
2945	c -= 20;
2946	d /= 10;
2947
2948	return a + b * c - d;
2949}
2950
2951ATF_TC(io_read_i1);
2952ATF_TC_HEAD(io_read_i1, tc)
2953{
2954	atf_tc_set_md_var(tc, "descr",
2955	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)");
2956}
2957
2958ATF_TC_BODY(io_read_i1, tc)
2959{
2960	const int exitval = 5;
2961	const int sigval = SIGSTOP;
2962	pid_t child, wpid;
2963	uint8_t lookup_me = 0;
2964	uint8_t magic;
2965	memcpy(&magic, dummy_fn1, sizeof(magic));
2966	struct ptrace_io_desc io = {
2967		.piod_op = PIOD_READ_I,
2968		.piod_offs = dummy_fn1,
2969		.piod_addr = &lookup_me,
2970		.piod_len = sizeof(lookup_me)
2971	};
2972#if defined(TWAIT_HAVE_STATUS)
2973	int status;
2974#endif
2975
2976	printf("Before forking process PID=%d\n", getpid());
2977	ATF_REQUIRE((child = fork()) != -1);
2978	if (child == 0) {
2979		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
2980		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2981
2982		printf("Before raising %s from child\n", strsignal(sigval));
2983		FORKEE_ASSERT(raise(sigval) == 0);
2984
2985		printf("Before exiting of the child process\n");
2986		_exit(exitval);
2987	}
2988	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2989
2990	printf("Before calling %s() for the child\n", TWAIT_FNAME);
2991	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2992
2993	validate_status_stopped(status, sigval);
2994
2995	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
2996	    child, getpid());
2997	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
2998
2999	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3000	    "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic);
3001
3002	printf("Before resuming the child process where it left off and "
3003	    "without signal to be sent\n");
3004	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3005
3006	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3007	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3008
3009	validate_status_exited(status, exitval);
3010
3011	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3012	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3013}
3014
3015ATF_TC(io_read_i2);
3016ATF_TC_HEAD(io_read_i2, tc)
3017{
3018	atf_tc_set_md_var(tc, "descr",
3019	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)");
3020}
3021
3022ATF_TC_BODY(io_read_i2, tc)
3023{
3024	const int exitval = 5;
3025	const int sigval = SIGSTOP;
3026	pid_t child, wpid;
3027	uint16_t lookup_me = 0;
3028	uint16_t magic;
3029	memcpy(&magic, dummy_fn1, sizeof(magic));
3030	struct ptrace_io_desc io = {
3031		.piod_op = PIOD_READ_I,
3032		.piod_offs = dummy_fn1,
3033		.piod_addr = &lookup_me,
3034		.piod_len = sizeof(lookup_me)
3035	};
3036#if defined(TWAIT_HAVE_STATUS)
3037	int status;
3038#endif
3039
3040	printf("Before forking process PID=%d\n", getpid());
3041	ATF_REQUIRE((child = fork()) != -1);
3042	if (child == 0) {
3043		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3044		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3045
3046		printf("Before raising %s from child\n", strsignal(sigval));
3047		FORKEE_ASSERT(raise(sigval) == 0);
3048
3049		printf("Before exiting of the child process\n");
3050		_exit(exitval);
3051	}
3052	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3053
3054	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3055	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3056
3057	validate_status_stopped(status, sigval);
3058
3059	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3060	    child, getpid());
3061	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3062
3063	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3064	    "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic);
3065
3066	printf("Before resuming the child process where it left off and "
3067	    "without signal to be sent\n");
3068	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3069
3070	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3071	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3072
3073	validate_status_exited(status, exitval);
3074
3075	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3076	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3077}
3078
3079ATF_TC(io_read_i3);
3080ATF_TC_HEAD(io_read_i3, tc)
3081{
3082	atf_tc_set_md_var(tc, "descr",
3083	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)");
3084}
3085
3086ATF_TC_BODY(io_read_i3, tc)
3087{
3088	const int exitval = 5;
3089	const int sigval = SIGSTOP;
3090	pid_t child, wpid;
3091	uint32_t lookup_me = 0;
3092	uint32_t magic;
3093	memcpy(&magic, dummy_fn1, sizeof(magic));
3094	struct ptrace_io_desc io = {
3095		.piod_op = PIOD_READ_I,
3096		.piod_offs = dummy_fn1,
3097		.piod_addr = &lookup_me,
3098		.piod_len = sizeof(lookup_me)
3099	};
3100#if defined(TWAIT_HAVE_STATUS)
3101	int status;
3102#endif
3103
3104	printf("Before forking process PID=%d\n", getpid());
3105	ATF_REQUIRE((child = fork()) != -1);
3106	if (child == 0) {
3107		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3108		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3109
3110		printf("Before raising %s from child\n", strsignal(sigval));
3111		FORKEE_ASSERT(raise(sigval) == 0);
3112
3113		printf("Before exiting of the child process\n");
3114		_exit(exitval);
3115	}
3116	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3117
3118	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3119	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3120
3121	validate_status_stopped(status, sigval);
3122
3123	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3124	    child, getpid());
3125	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3126
3127	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3128	    "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic);
3129
3130	printf("Before resuming the child process where it left off and "
3131	    "without signal to be sent\n");
3132	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3133
3134	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3135	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3136
3137	validate_status_exited(status, exitval);
3138
3139	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3140	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3141}
3142
3143ATF_TC(io_read_i4);
3144ATF_TC_HEAD(io_read_i4, tc)
3145{
3146	atf_tc_set_md_var(tc, "descr",
3147	    "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)");
3148}
3149
3150ATF_TC_BODY(io_read_i4, tc)
3151{
3152	const int exitval = 5;
3153	const int sigval = SIGSTOP;
3154	pid_t child, wpid;
3155	uint64_t lookup_me = 0;
3156	uint64_t magic;
3157	memcpy(&magic, dummy_fn1, sizeof(magic));
3158	struct ptrace_io_desc io = {
3159		.piod_op = PIOD_READ_I,
3160		.piod_offs = dummy_fn1,
3161		.piod_addr = &lookup_me,
3162		.piod_len = sizeof(lookup_me)
3163	};
3164#if defined(TWAIT_HAVE_STATUS)
3165	int status;
3166#endif
3167
3168	printf("Before forking process PID=%d\n", getpid());
3169	ATF_REQUIRE((child = fork()) != -1);
3170	if (child == 0) {
3171		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3172		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3173
3174		printf("Before raising %s from child\n", strsignal(sigval));
3175		FORKEE_ASSERT(raise(sigval) == 0);
3176
3177		printf("Before exiting of the child process\n");
3178		_exit(exitval);
3179	}
3180	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3181
3182	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3183	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3184
3185	validate_status_stopped(status, sigval);
3186
3187	printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3188	    child, getpid());
3189	ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
3190
3191	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3192	    "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic);
3193
3194	printf("Before resuming the child process where it left off and "
3195	    "without signal to be sent\n");
3196	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3197
3198	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3199	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3200
3201	validate_status_exited(status, exitval);
3202
3203	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3204	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3205}
3206
3207ATF_TC(read_i1);
3208ATF_TC_HEAD(read_i1, tc)
3209{
3210	atf_tc_set_md_var(tc, "descr",
3211	    "Verify PT_READ_I called once");
3212}
3213
3214ATF_TC_BODY(read_i1, tc)
3215{
3216	const int exitval = 5;
3217	const int sigval = SIGSTOP;
3218	pid_t child, wpid;
3219	int lookup_me = 0;
3220	int magic;
3221	memcpy(&magic, dummy_fn1, sizeof(magic));
3222#if defined(TWAIT_HAVE_STATUS)
3223	int status;
3224#endif
3225
3226	printf("Before forking process PID=%d\n", getpid());
3227	ATF_REQUIRE((child = fork()) != -1);
3228	if (child == 0) {
3229		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3230		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3231
3232		printf("Before raising %s from child\n", strsignal(sigval));
3233		FORKEE_ASSERT(raise(sigval) == 0);
3234
3235		printf("Before exiting of the child process\n");
3236		_exit(exitval);
3237	}
3238	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3239
3240	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3241	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3242
3243	validate_status_stopped(status, sigval);
3244
3245	printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n",
3246	    child, getpid());
3247	errno = 0;
3248	lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0);
3249	ATF_REQUIRE_EQ(errno, 0);
3250
3251	ATF_REQUIRE_EQ_MSG(lookup_me, magic,
3252	    "got value %#x != expected %#x", lookup_me, magic);
3253
3254	printf("Before resuming the child process where it left off and "
3255	    "without signal to be sent\n");
3256	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3257
3258	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3259	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3260
3261	validate_status_exited(status, exitval);
3262
3263	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3264	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3265}
3266
3267ATF_TC(read_i2);
3268ATF_TC_HEAD(read_i2, tc)
3269{
3270	atf_tc_set_md_var(tc, "descr",
3271	    "Verify PT_READ_I called twice");
3272}
3273
3274ATF_TC_BODY(read_i2, tc)
3275{
3276	const int exitval = 5;
3277	const int sigval = SIGSTOP;
3278	pid_t child, wpid;
3279	int lookup_me1 = 0;
3280	int lookup_me2 = 0;
3281	int magic1;
3282	int magic2;
3283	memcpy(&magic1, dummy_fn1, sizeof(magic1));
3284	memcpy(&magic2, dummy_fn2, sizeof(magic2));
3285#if defined(TWAIT_HAVE_STATUS)
3286	int status;
3287#endif
3288
3289	printf("Before forking process PID=%d\n", getpid());
3290	ATF_REQUIRE((child = fork()) != -1);
3291	if (child == 0) {
3292		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3293		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3294
3295		printf("Before raising %s from child\n", strsignal(sigval));
3296		FORKEE_ASSERT(raise(sigval) == 0);
3297
3298		printf("Before exiting of the child process\n");
3299		_exit(exitval);
3300	}
3301	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3302
3303	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3304	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3305
3306	validate_status_stopped(status, sigval);
3307
3308	printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3309	    child, getpid());
3310	errno = 0;
3311	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3312	ATF_REQUIRE_EQ(errno, 0);
3313
3314	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3315	    "got value %#x != expected %#x", lookup_me1, magic1);
3316
3317	printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3318	    child, getpid());
3319	errno = 0;
3320	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3321	ATF_REQUIRE_EQ(errno, 0);
3322
3323	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3324	    "got value %#x != expected %#x", lookup_me2, magic2);
3325
3326	printf("Before resuming the child process where it left off and "
3327	    "without signal to be sent\n");
3328	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3329
3330	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3331	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3332
3333	validate_status_exited(status, exitval);
3334
3335	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3336	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3337}
3338
3339ATF_TC(read_i3);
3340ATF_TC_HEAD(read_i3, tc)
3341{
3342	atf_tc_set_md_var(tc, "descr",
3343	    "Verify PT_READ_I called three times");
3344}
3345
3346ATF_TC_BODY(read_i3, tc)
3347{
3348	const int exitval = 5;
3349	const int sigval = SIGSTOP;
3350	pid_t child, wpid;
3351	int lookup_me1 = 0;
3352	int lookup_me2 = 0;
3353	int lookup_me3 = 0;
3354	int magic1;
3355	int magic2;
3356	int magic3;
3357	memcpy(&magic1, dummy_fn1, sizeof(magic1));
3358	memcpy(&magic2, dummy_fn2, sizeof(magic2));
3359	memcpy(&magic3, dummy_fn3, sizeof(magic3));
3360#if defined(TWAIT_HAVE_STATUS)
3361	int status;
3362#endif
3363
3364	printf("Before forking process PID=%d\n", getpid());
3365	ATF_REQUIRE((child = fork()) != -1);
3366	if (child == 0) {
3367		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3368		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3369
3370		printf("Before raising %s from child\n", strsignal(sigval));
3371		FORKEE_ASSERT(raise(sigval) == 0);
3372
3373		printf("Before exiting of the child process\n");
3374		_exit(exitval);
3375	}
3376	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3377
3378	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3379	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3380
3381	validate_status_stopped(status, sigval);
3382
3383	printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3384	    child, getpid());
3385	errno = 0;
3386	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3387	ATF_REQUIRE_EQ(errno, 0);
3388
3389	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3390	    "got value %#x != expected %#x", lookup_me1, magic1);
3391
3392	printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3393	    child, getpid());
3394	errno = 0;
3395	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3396	ATF_REQUIRE_EQ(errno, 0);
3397
3398	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3399	    "got value %#x != expected %#x", lookup_me2, magic2);
3400
3401	printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
3402	    child, getpid());
3403	errno = 0;
3404	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
3405	ATF_REQUIRE_EQ(errno, 0);
3406
3407	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
3408	    "got value %#x != expected %#x", lookup_me3, magic3);
3409
3410	printf("Before resuming the child process where it left off and "
3411	    "without signal to be sent\n");
3412	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3413
3414	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3415	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3416
3417	validate_status_exited(status, exitval);
3418
3419	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3420	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3421}
3422
3423ATF_TC(read_i4);
3424ATF_TC_HEAD(read_i4, tc)
3425{
3426	atf_tc_set_md_var(tc, "descr",
3427	    "Verify PT_READ_I called four times");
3428}
3429
3430ATF_TC_BODY(read_i4, tc)
3431{
3432	const int exitval = 5;
3433	const int sigval = SIGSTOP;
3434	pid_t child, wpid;
3435	int lookup_me1 = 0;
3436	int lookup_me2 = 0;
3437	int lookup_me3 = 0;
3438	int lookup_me4 = 0;
3439	int magic1;
3440	int magic2;
3441	int magic3;
3442	int magic4;
3443	memcpy(&magic1, dummy_fn1, sizeof(magic1));
3444	memcpy(&magic2, dummy_fn2, sizeof(magic2));
3445	memcpy(&magic3, dummy_fn3, sizeof(magic3));
3446	memcpy(&magic4, dummy_fn4, sizeof(magic4));
3447#if defined(TWAIT_HAVE_STATUS)
3448	int status;
3449#endif
3450
3451	printf("Before forking process PID=%d\n", getpid());
3452	ATF_REQUIRE((child = fork()) != -1);
3453	if (child == 0) {
3454		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3455		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3456
3457		printf("Before raising %s from child\n", strsignal(sigval));
3458		FORKEE_ASSERT(raise(sigval) == 0);
3459
3460		printf("Before exiting of the child process\n");
3461		_exit(exitval);
3462	}
3463	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3464
3465	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3466	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3467
3468	validate_status_stopped(status, sigval);
3469
3470	printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n",
3471	    child, getpid());
3472	errno = 0;
3473	lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0);
3474	ATF_REQUIRE_EQ(errno, 0);
3475
3476	ATF_REQUIRE_EQ_MSG(lookup_me1, magic1,
3477	    "got value %#x != expected %#x", lookup_me1, magic1);
3478
3479	printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n",
3480	    child, getpid());
3481	errno = 0;
3482	lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0);
3483	ATF_REQUIRE_EQ(errno, 0);
3484
3485	ATF_REQUIRE_EQ_MSG(lookup_me2, magic2,
3486	    "got value %#x != expected %#x", lookup_me2, magic2);
3487
3488	printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n",
3489	    child, getpid());
3490	errno = 0;
3491	lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0);
3492	ATF_REQUIRE_EQ(errno, 0);
3493
3494	ATF_REQUIRE_EQ_MSG(lookup_me3, magic3,
3495	    "got value %#x != expected %#x", lookup_me3, magic3);
3496
3497	printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n",
3498	    child, getpid());
3499	errno = 0;
3500	lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0);
3501	ATF_REQUIRE_EQ(errno, 0);
3502
3503	ATF_REQUIRE_EQ_MSG(lookup_me4, magic4,
3504	    "got value %#x != expected %#x", lookup_me4, magic4);
3505
3506	printf("Before resuming the child process where it left off and "
3507	    "without signal to be sent\n");
3508	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3509
3510	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3511	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3512
3513	validate_status_exited(status, exitval);
3514
3515	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3516	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3517}
3518
3519#if defined(HAVE_GPREGS)
3520ATF_TC(regs1);
3521ATF_TC_HEAD(regs1, tc)
3522{
3523	atf_tc_set_md_var(tc, "descr",
3524	    "Verify plain PT_GETREGS call without further steps");
3525}
3526
3527ATF_TC_BODY(regs1, tc)
3528{
3529	const int exitval = 5;
3530	const int sigval = SIGSTOP;
3531	pid_t child, wpid;
3532#if defined(TWAIT_HAVE_STATUS)
3533	int status;
3534#endif
3535	struct reg r;
3536
3537	printf("Before forking process PID=%d\n", getpid());
3538	ATF_REQUIRE((child = fork()) != -1);
3539	if (child == 0) {
3540		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3541		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3542
3543		printf("Before raising %s from child\n", strsignal(sigval));
3544		FORKEE_ASSERT(raise(sigval) == 0);
3545
3546		printf("Before exiting of the child process\n");
3547		_exit(exitval);
3548	}
3549	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3550
3551	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3552	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3553
3554	validate_status_stopped(status, sigval);
3555
3556	printf("Call GETREGS for the child process\n");
3557	ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
3558
3559	printf("Before resuming the child process where it left off and "
3560	    "without signal to be sent\n");
3561	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3562
3563	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3564	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3565
3566	validate_status_exited(status, exitval);
3567
3568	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3569	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3570}
3571#endif
3572
3573#if defined(HAVE_GPREGS)
3574ATF_TC(regs2);
3575ATF_TC_HEAD(regs2, tc)
3576{
3577	atf_tc_set_md_var(tc, "descr",
3578	    "Verify plain PT_GETREGS call and retrieve PC");
3579}
3580
3581ATF_TC_BODY(regs2, tc)
3582{
3583	const int exitval = 5;
3584	const int sigval = SIGSTOP;
3585	pid_t child, wpid;
3586#if defined(TWAIT_HAVE_STATUS)
3587	int status;
3588#endif
3589	struct reg r;
3590
3591	printf("Before forking process PID=%d\n", getpid());
3592	ATF_REQUIRE((child = fork()) != -1);
3593	if (child == 0) {
3594		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3595		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3596
3597		printf("Before raising %s from child\n", strsignal(sigval));
3598		FORKEE_ASSERT(raise(sigval) == 0);
3599
3600		printf("Before exiting of the child process\n");
3601		_exit(exitval);
3602	}
3603	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3604
3605	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3606	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3607
3608	validate_status_stopped(status, sigval);
3609
3610	printf("Call GETREGS for the child process\n");
3611	ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
3612
3613	printf("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
3614
3615	printf("Before resuming the child process where it left off and "
3616	    "without signal to be sent\n");
3617	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3618
3619	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3620	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3621
3622	validate_status_exited(status, exitval);
3623
3624	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3625	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3626}
3627#endif
3628
3629#if defined(HAVE_GPREGS)
3630ATF_TC(regs3);
3631ATF_TC_HEAD(regs3, tc)
3632{
3633	atf_tc_set_md_var(tc, "descr",
3634	    "Verify plain PT_GETREGS call and retrieve SP");
3635}
3636
3637ATF_TC_BODY(regs3, tc)
3638{
3639	const int exitval = 5;
3640	const int sigval = SIGSTOP;
3641	pid_t child, wpid;
3642#if defined(TWAIT_HAVE_STATUS)
3643	int status;
3644#endif
3645	struct reg r;
3646
3647	printf("Before forking process PID=%d\n", getpid());
3648	ATF_REQUIRE((child = fork()) != -1);
3649	if (child == 0) {
3650		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3651		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3652
3653		printf("Before raising %s from child\n", strsignal(sigval));
3654		FORKEE_ASSERT(raise(sigval) == 0);
3655
3656		printf("Before exiting of the child process\n");
3657		_exit(exitval);
3658	}
3659	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3660
3661	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3662	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3663
3664	validate_status_stopped(status, sigval);
3665
3666	printf("Call GETREGS for the child process\n");
3667	ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
3668
3669	printf("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
3670
3671	printf("Before resuming the child process where it left off and "
3672	    "without signal to be sent\n");
3673	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3674
3675	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3676	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3677
3678	validate_status_exited(status, exitval);
3679
3680	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3681	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3682}
3683#endif
3684
3685#if defined(HAVE_GPREGS)
3686ATF_TC(regs4);
3687ATF_TC_HEAD(regs4, tc)
3688{
3689	atf_tc_set_md_var(tc, "descr",
3690	    "Verify plain PT_GETREGS call and retrieve INTRV");
3691}
3692
3693ATF_TC_BODY(regs4, tc)
3694{
3695	const int exitval = 5;
3696	const int sigval = SIGSTOP;
3697	pid_t child, wpid;
3698#if defined(TWAIT_HAVE_STATUS)
3699	int status;
3700#endif
3701	struct reg r;
3702
3703	printf("Before forking process PID=%d\n", getpid());
3704	ATF_REQUIRE((child = fork()) != -1);
3705	if (child == 0) {
3706		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3707		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3708
3709		printf("Before raising %s from child\n", strsignal(sigval));
3710		FORKEE_ASSERT(raise(sigval) == 0);
3711
3712		printf("Before exiting of the child process\n");
3713		_exit(exitval);
3714	}
3715	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3716
3717	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3718	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3719
3720	validate_status_stopped(status, sigval);
3721
3722	printf("Call GETREGS for the child process\n");
3723	ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
3724
3725	printf("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
3726
3727	printf("Before resuming the child process where it left off and "
3728	    "without signal to be sent\n");
3729	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3730
3731	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3732	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3733
3734	validate_status_exited(status, exitval);
3735
3736	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3737	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3738}
3739#endif
3740
3741#if defined(HAVE_GPREGS)
3742ATF_TC(regs5);
3743ATF_TC_HEAD(regs5, tc)
3744{
3745	atf_tc_set_md_var(tc, "descr",
3746	    "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
3747}
3748
3749ATF_TC_BODY(regs5, tc)
3750{
3751	const int exitval = 5;
3752	const int sigval = SIGSTOP;
3753	pid_t child, wpid;
3754#if defined(TWAIT_HAVE_STATUS)
3755	int status;
3756#endif
3757	struct reg r;
3758
3759	printf("Before forking process PID=%d\n", getpid());
3760	ATF_REQUIRE((child = fork()) != -1);
3761	if (child == 0) {
3762		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3763		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3764
3765		printf("Before raising %s from child\n", strsignal(sigval));
3766		FORKEE_ASSERT(raise(sigval) == 0);
3767
3768		printf("Before exiting of the child process\n");
3769		_exit(exitval);
3770	}
3771	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3772
3773	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3774	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3775
3776	validate_status_stopped(status, sigval);
3777
3778	printf("Call GETREGS for the child process\n");
3779	ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
3780
3781	printf("Call SETREGS for the child process (without changed regs)\n");
3782	ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
3783
3784	printf("Before resuming the child process where it left off and "
3785	    "without signal to be sent\n");
3786	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3787
3788	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3789	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3790
3791	validate_status_exited(status, exitval);
3792
3793	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3794	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3795}
3796#endif
3797
3798#if defined(HAVE_FPREGS)
3799ATF_TC(fpregs1);
3800ATF_TC_HEAD(fpregs1, tc)
3801{
3802	atf_tc_set_md_var(tc, "descr",
3803	    "Verify plain PT_GETFPREGS call without further steps");
3804}
3805
3806ATF_TC_BODY(fpregs1, tc)
3807{
3808	const int exitval = 5;
3809	const int sigval = SIGSTOP;
3810	pid_t child, wpid;
3811#if defined(TWAIT_HAVE_STATUS)
3812	int status;
3813#endif
3814	struct fpreg r;
3815
3816	printf("Before forking process PID=%d\n", getpid());
3817	ATF_REQUIRE((child = fork()) != -1);
3818	if (child == 0) {
3819		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3820		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3821
3822		printf("Before raising %s from child\n", strsignal(sigval));
3823		FORKEE_ASSERT(raise(sigval) == 0);
3824
3825		printf("Before exiting of the child process\n");
3826		_exit(exitval);
3827	}
3828	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3829
3830	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3831	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3832
3833	validate_status_stopped(status, sigval);
3834
3835	printf("Call GETFPREGS for the child process\n");
3836	ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
3837
3838	printf("Before resuming the child process where it left off and "
3839	    "without signal to be sent\n");
3840	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3841
3842	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3843	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3844
3845	validate_status_exited(status, exitval);
3846
3847	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3848	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3849}
3850#endif
3851
3852#if defined(HAVE_FPREGS)
3853ATF_TC(fpregs2);
3854ATF_TC_HEAD(fpregs2, tc)
3855{
3856	atf_tc_set_md_var(tc, "descr",
3857	    "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing "
3858	    "regs");
3859}
3860
3861ATF_TC_BODY(fpregs2, tc)
3862{
3863	const int exitval = 5;
3864	const int sigval = SIGSTOP;
3865	pid_t child, wpid;
3866#if defined(TWAIT_HAVE_STATUS)
3867	int status;
3868#endif
3869	struct fpreg r;
3870
3871	printf("Before forking process PID=%d\n", getpid());
3872	ATF_REQUIRE((child = fork()) != -1);
3873	if (child == 0) {
3874		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3875		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3876
3877		printf("Before raising %s from child\n", strsignal(sigval));
3878		FORKEE_ASSERT(raise(sigval) == 0);
3879
3880		printf("Before exiting of the child process\n");
3881		_exit(exitval);
3882	}
3883	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3884
3885	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3886	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3887
3888	validate_status_stopped(status, sigval);
3889
3890	printf("Call GETFPREGS for the child process\n");
3891	ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1);
3892
3893	printf("Call SETFPREGS for the child (without changed regs)\n");
3894	ATF_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1);
3895
3896	printf("Before resuming the child process where it left off and "
3897	    "without signal to be sent\n");
3898	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3899
3900	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3901	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3902
3903	validate_status_exited(status, exitval);
3904
3905	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3906	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3907}
3908#endif
3909
3910#if defined(PT_STEP)
3911ATF_TC(step1);
3912ATF_TC_HEAD(step1, tc)
3913{
3914	atf_tc_set_md_var(tc, "descr",
3915	    "Verify single PT_STEP call");
3916}
3917
3918ATF_TC_BODY(step1, tc)
3919{
3920	const int exitval = 5;
3921	const int sigval = SIGSTOP;
3922	pid_t child, wpid;
3923#if defined(TWAIT_HAVE_STATUS)
3924	int status;
3925#endif
3926	int happy;
3927
3928	printf("Before forking process PID=%d\n", getpid());
3929	ATF_REQUIRE((child = fork()) != -1);
3930	if (child == 0) {
3931		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3932		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3933
3934		happy = check_happy(100);
3935
3936		printf("Before raising %s from child\n", strsignal(sigval));
3937		FORKEE_ASSERT(raise(sigval) == 0);
3938
3939		FORKEE_ASSERT_EQ(happy, check_happy(100));
3940
3941		printf("Before exiting of the child process\n");
3942		_exit(exitval);
3943	}
3944	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3945
3946	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3947	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3948
3949	validate_status_stopped(status, sigval);
3950
3951	printf("Before resuming the child process where it left off and "
3952	    "without signal to be sent (use PT_STEP)\n");
3953	ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
3954
3955	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3956	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3957
3958	validate_status_stopped(status, SIGTRAP);
3959
3960	printf("Before resuming the child process where it left off and "
3961	    "without signal to be sent\n");
3962	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3963
3964	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3965	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3966
3967	validate_status_exited(status, exitval);
3968
3969	printf("Before calling %s() for the child\n", TWAIT_FNAME);
3970	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3971}
3972#endif
3973
3974#if defined(PT_STEP)
3975ATF_TC(step2);
3976ATF_TC_HEAD(step2, tc)
3977{
3978	atf_tc_set_md_var(tc, "descr",
3979	    "Verify PT_STEP called twice");
3980}
3981
3982ATF_TC_BODY(step2, tc)
3983{
3984	const int exitval = 5;
3985	const int sigval = SIGSTOP;
3986	pid_t child, wpid;
3987#if defined(TWAIT_HAVE_STATUS)
3988	int status;
3989#endif
3990	int happy;
3991	int N = 2;
3992
3993	printf("Before forking process PID=%d\n", getpid());
3994	ATF_REQUIRE((child = fork()) != -1);
3995	if (child == 0) {
3996		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
3997		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3998
3999		happy = check_happy(999);
4000
4001		printf("Before raising %s from child\n", strsignal(sigval));
4002		FORKEE_ASSERT(raise(sigval) == 0);
4003
4004		FORKEE_ASSERT_EQ(happy, check_happy(999));
4005
4006		printf("Before exiting of the child process\n");
4007		_exit(exitval);
4008	}
4009	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4010
4011	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4012	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4013
4014	validate_status_stopped(status, sigval);
4015
4016	while (N --> 0) {
4017		printf("Before resuming the child process where it left off "
4018		    "and without signal to be sent (use PT_STEP)\n");
4019		ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4020
4021		printf("Before calling %s() for the child\n", TWAIT_FNAME);
4022		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4023		    child);
4024
4025		validate_status_stopped(status, SIGTRAP);
4026	}
4027
4028	printf("Before resuming the child process where it left off and "
4029	    "without signal to be sent\n");
4030	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4031
4032	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4033	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4034
4035	validate_status_exited(status, exitval);
4036
4037	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4038	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4039}
4040#endif
4041
4042#if defined(PT_STEP)
4043ATF_TC(step3);
4044ATF_TC_HEAD(step3, tc)
4045{
4046	atf_tc_set_md_var(tc, "descr",
4047	    "Verify PT_STEP called three times");
4048}
4049
4050ATF_TC_BODY(step3, tc)
4051{
4052	const int exitval = 5;
4053	const int sigval = SIGSTOP;
4054	pid_t child, wpid;
4055#if defined(TWAIT_HAVE_STATUS)
4056	int status;
4057#endif
4058	int happy;
4059	int N = 3;
4060
4061	printf("Before forking process PID=%d\n", getpid());
4062	ATF_REQUIRE((child = fork()) != -1);
4063	if (child == 0) {
4064		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4065		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4066
4067		happy = check_happy(999);
4068
4069		printf("Before raising %s from child\n", strsignal(sigval));
4070		FORKEE_ASSERT(raise(sigval) == 0);
4071
4072		FORKEE_ASSERT_EQ(happy, check_happy(999));
4073
4074		printf("Before exiting of the child process\n");
4075		_exit(exitval);
4076	}
4077	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4078
4079	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4080	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4081
4082	validate_status_stopped(status, sigval);
4083
4084	while (N --> 0) {
4085		printf("Before resuming the child process where it left off "
4086		    "and without signal to be sent (use PT_STEP)\n");
4087		ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4088
4089		printf("Before calling %s() for the child\n", TWAIT_FNAME);
4090		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4091		    child);
4092
4093		validate_status_stopped(status, SIGTRAP);
4094	}
4095
4096	printf("Before resuming the child process where it left off and "
4097	    "without signal to be sent\n");
4098	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4099
4100	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4101	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4102
4103	validate_status_exited(status, exitval);
4104
4105	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4106	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4107}
4108#endif
4109
4110#if defined(PT_STEP)
4111ATF_TC(step4);
4112ATF_TC_HEAD(step4, tc)
4113{
4114	atf_tc_set_md_var(tc, "descr",
4115	    "Verify PT_STEP called four times");
4116}
4117
4118ATF_TC_BODY(step4, tc)
4119{
4120	const int exitval = 5;
4121	const int sigval = SIGSTOP;
4122	pid_t child, wpid;
4123#if defined(TWAIT_HAVE_STATUS)
4124	int status;
4125#endif
4126	int happy;
4127	int N = 4;
4128
4129	printf("Before forking process PID=%d\n", getpid());
4130	ATF_REQUIRE((child = fork()) != -1);
4131	if (child == 0) {
4132		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4133		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4134
4135		happy = check_happy(999);
4136
4137		printf("Before raising %s from child\n", strsignal(sigval));
4138		FORKEE_ASSERT(raise(sigval) == 0);
4139
4140		FORKEE_ASSERT_EQ(happy, check_happy(999));
4141
4142		printf("Before exiting of the child process\n");
4143		_exit(exitval);
4144	}
4145	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4146
4147	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4148	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4149
4150	validate_status_stopped(status, sigval);
4151
4152	while (N --> 0) {
4153		printf("Before resuming the child process where it left off "
4154		    "and without signal to be sent (use PT_STEP)\n");
4155		ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4156
4157		printf("Before calling %s() for the child\n", TWAIT_FNAME);
4158		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4159		    child);
4160
4161		validate_status_stopped(status, SIGTRAP);
4162	}
4163
4164	printf("Before resuming the child process where it left off and "
4165	    "without signal to be sent\n");
4166	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4167
4168	printf("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	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4174	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4175}
4176#endif
4177
4178ATF_TC(kill1);
4179ATF_TC_HEAD(kill1, tc)
4180{
4181	atf_tc_set_md_var(tc, "descr",
4182	    "Verify that PT_CONTINUE with SIGKILL terminates child");
4183}
4184
4185ATF_TC_BODY(kill1, tc)
4186{
4187	const int sigval = SIGSTOP, sigsent = SIGKILL;
4188	pid_t child, wpid;
4189#if defined(TWAIT_HAVE_STATUS)
4190	int status;
4191#endif
4192
4193	printf("Before forking process PID=%d\n", getpid());
4194	ATF_REQUIRE((child = fork()) != -1);
4195	if (child == 0) {
4196		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4197		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4198
4199		printf("Before raising %s from child\n", strsignal(sigval));
4200		FORKEE_ASSERT(raise(sigval) == 0);
4201
4202		/* NOTREACHED */
4203		FORKEE_ASSERTX(0 &&
4204		    "Child should be terminated by a signal from its parent");
4205	}
4206	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4207
4208	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4209	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4210
4211	validate_status_stopped(status, sigval);
4212
4213	printf("Before resuming the child process where it left off and "
4214	    "without signal to be sent\n");
4215	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
4216
4217	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4218	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4219
4220	validate_status_signaled(status, sigsent, 0);
4221
4222	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4223	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4224}
4225
4226ATF_TC(kill2);
4227ATF_TC_HEAD(kill2, tc)
4228{
4229	atf_tc_set_md_var(tc, "descr",
4230	    "Verify that PT_KILL terminates child");
4231}
4232
4233ATF_TC_BODY(kill2, tc)
4234{
4235	const int sigval = SIGSTOP;
4236	pid_t child, wpid;
4237#if defined(TWAIT_HAVE_STATUS)
4238	int status;
4239#endif
4240
4241	printf("Before forking process PID=%d\n", getpid());
4242	ATF_REQUIRE((child = fork()) != -1);
4243	if (child == 0) {
4244		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4245		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4246
4247		printf("Before raising %s from child\n", strsignal(sigval));
4248		FORKEE_ASSERT(raise(sigval) == 0);
4249
4250		/* NOTREACHED */
4251		FORKEE_ASSERTX(0 &&
4252		    "Child should be terminated by a signal from its parent");
4253	}
4254	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4255
4256	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4257	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4258
4259	validate_status_stopped(status, sigval);
4260
4261	printf("Before resuming the child process where it left off and "
4262	    "without signal to be sent\n");
4263	ATF_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
4264
4265	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4266	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4267
4268	validate_status_signaled(status, SIGKILL, 0);
4269
4270	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4271	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4272}
4273
4274ATF_TC(lwpinfo1);
4275ATF_TC_HEAD(lwpinfo1, tc)
4276{
4277	atf_tc_set_md_var(tc, "descr",
4278	    "Verify basic LWPINFO call for single thread (PT_TRACE_ME)");
4279}
4280
4281ATF_TC_BODY(lwpinfo1, tc)
4282{
4283	const int exitval = 5;
4284	const int sigval = SIGSTOP;
4285	pid_t child, wpid;
4286#if defined(TWAIT_HAVE_STATUS)
4287	int status;
4288#endif
4289	struct ptrace_lwpinfo info = {0, 0};
4290
4291	printf("Before forking process PID=%d\n", getpid());
4292	ATF_REQUIRE((child = fork()) != -1);
4293	if (child == 0) {
4294		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4295		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4296
4297		printf("Before raising %s from child\n", strsignal(sigval));
4298		FORKEE_ASSERT(raise(sigval) == 0);
4299
4300		printf("Before exiting of the child process\n");
4301		_exit(exitval);
4302	}
4303	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4304
4305	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4306	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4307
4308	validate_status_stopped(status, sigval);
4309
4310	printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4311	ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
4312
4313	printf("Assert that there exists a thread\n");
4314	ATF_REQUIRE(info.pl_lwpid > 0);
4315
4316	printf("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n",
4317	    info.pl_lwpid);
4318	ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL,
4319	    "Received event %d != expected event %d",
4320	    info.pl_event, PL_EVENT_SIGNAL);
4321
4322	printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4323	ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1);
4324
4325	printf("Assert that there are no more lwp threads in child\n");
4326	ATF_REQUIRE_EQ(info.pl_lwpid, 0);
4327
4328	printf("Before resuming the child process where it left off and "
4329	    "without signal to be sent\n");
4330	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4331
4332	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4333	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4334
4335	validate_status_exited(status, exitval);
4336
4337	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4338	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4339}
4340
4341#if defined(TWAIT_HAVE_PID)
4342ATF_TC(lwpinfo2);
4343ATF_TC_HEAD(lwpinfo2, tc)
4344{
4345	atf_tc_set_md_var(tc, "descr",
4346	    "Verify basic LWPINFO call for single thread (PT_ATTACH from "
4347	    "tracer)");
4348}
4349
4350ATF_TC_BODY(lwpinfo2, tc)
4351{
4352	struct msg_fds parent_tracee, parent_tracer;
4353	const int exitval_tracee = 5;
4354	const int exitval_tracer = 10;
4355	pid_t tracee, tracer, wpid;
4356	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
4357#if defined(TWAIT_HAVE_STATUS)
4358	int status;
4359#endif
4360	struct ptrace_lwpinfo info = {0, 0};
4361
4362	printf("Spawn tracee\n");
4363	ATF_REQUIRE(msg_open(&parent_tracee) == 0);
4364	ATF_REQUIRE(msg_open(&parent_tracer) == 0);
4365	tracee = atf_utils_fork();
4366	if (tracee == 0) {
4367
4368		/* Wait for message from the parent */
4369		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
4370		CHILD_FROM_PARENT("tracee exit", parent_tracee, msg);
4371
4372		_exit(exitval_tracee);
4373	}
4374	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
4375
4376	printf("Spawn debugger\n");
4377	tracer = atf_utils_fork();
4378	if (tracer == 0) {
4379		/* No IPC to communicate with the child */
4380		printf("Before calling PT_ATTACH from tracee %d\n", getpid());
4381		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
4382
4383		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
4384		FORKEE_REQUIRE_SUCCESS(
4385		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4386
4387		forkee_status_stopped(status, SIGSTOP);
4388
4389		printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4390		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
4391		    != -1);
4392
4393		printf("Assert that there exists a thread\n");
4394		FORKEE_ASSERTX(info.pl_lwpid > 0);
4395
4396		printf("Assert that lwp thread %d received event "
4397		    "PL_EVENT_SIGNAL\n", info.pl_lwpid);
4398		FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL);
4399
4400		printf("Before calling ptrace(2) with PT_LWPINFO for child\n");
4401		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info))
4402		    != -1);
4403
4404		printf("Assert that there are no more lwp threads in child\n");
4405		FORKEE_ASSERTX(info.pl_lwpid == 0);
4406
4407		/* Resume tracee with PT_CONTINUE */
4408		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
4409
4410		/* Inform parent that tracer has attached to tracee */
4411		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
4412		/* Wait for parent */
4413		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
4414
4415		/* Wait for tracee and assert that it exited */
4416		FORKEE_REQUIRE_SUCCESS(
4417		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4418
4419		forkee_status_exited(status, exitval_tracee);
4420
4421		printf("Before exiting of the tracer process\n");
4422		_exit(exitval_tracer);
4423	}
4424
4425	printf("Wait for the tracer to attach to the tracee\n");
4426	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
4427
4428	printf("Resume the tracee and let it exit\n");
4429	PARENT_TO_CHILD("tracee exit", parent_tracee, msg);
4430
4431	printf("Detect that tracee is zombie\n");
4432	await_zombie(tracee);
4433
4434	printf("Assert that there is no status about tracee - "
4435	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
4436	TWAIT_REQUIRE_SUCCESS(
4437	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
4438
4439	printf("Resume the tracer and let it detect exited tracee\n");
4440	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
4441
4442	printf("Wait for tracer to finish its job and exit - calling %s()\n",
4443	    TWAIT_FNAME);
4444	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
4445	    tracer);
4446
4447	validate_status_exited(status, exitval_tracer);
4448
4449	printf("Wait for tracee to finish its job and exit - calling %s()\n",
4450	    TWAIT_FNAME);
4451	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
4452	    tracee);
4453
4454	validate_status_exited(status, exitval_tracee);
4455
4456	msg_close(&parent_tracer);
4457	msg_close(&parent_tracee);
4458}
4459#endif
4460
4461ATF_TC(siginfo1);
4462ATF_TC_HEAD(siginfo1, tc)
4463{
4464	atf_tc_set_md_var(tc, "descr",
4465	    "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee");
4466}
4467
4468ATF_TC_BODY(siginfo1, tc)
4469{
4470	const int exitval = 5;
4471	const int sigval = SIGTRAP;
4472	pid_t child, wpid;
4473#if defined(TWAIT_HAVE_STATUS)
4474	int status;
4475#endif
4476	struct ptrace_siginfo info;
4477	memset(&info, 0, sizeof(info));
4478
4479	printf("Before forking process PID=%d\n", getpid());
4480	ATF_REQUIRE((child = fork()) != -1);
4481	if (child == 0) {
4482		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4483		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4484
4485		printf("Before raising %s from child\n", strsignal(sigval));
4486		FORKEE_ASSERT(raise(sigval) == 0);
4487
4488		printf("Before exiting of the child process\n");
4489		_exit(exitval);
4490	}
4491	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4492
4493	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4494	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4495
4496	validate_status_stopped(status, sigval);
4497
4498	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4499	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4500
4501	printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
4502	printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4503	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4504	    info.psi_siginfo.si_errno);
4505
4506	printf("Before resuming the child process where it left off and "
4507	    "without signal to be sent\n");
4508	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4509
4510	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4511	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4512
4513	validate_status_exited(status, exitval);
4514
4515	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4516	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4517}
4518
4519ATF_TC(siginfo2);
4520ATF_TC_HEAD(siginfo2, tc)
4521{
4522	atf_tc_set_md_var(tc, "descr",
4523	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without "
4524	    "modification of SIGINT from tracee");
4525}
4526
4527static int siginfo2_caught = 0;
4528
4529static void
4530siginfo2_sighandler(int sig)
4531{
4532	FORKEE_ASSERT_EQ(sig, SIGINT);
4533
4534	++siginfo2_caught;
4535}
4536
4537ATF_TC_BODY(siginfo2, tc)
4538{
4539	const int exitval = 5;
4540	const int sigval = SIGINT;
4541	pid_t child, wpid;
4542	struct sigaction sa;
4543#if defined(TWAIT_HAVE_STATUS)
4544	int status;
4545#endif
4546	struct ptrace_siginfo info;
4547	memset(&info, 0, sizeof(info));
4548
4549	printf("Before forking process PID=%d\n", getpid());
4550	ATF_REQUIRE((child = fork()) != -1);
4551	if (child == 0) {
4552		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4553		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4554
4555		sa.sa_handler = siginfo2_sighandler;
4556		sa.sa_flags = SA_SIGINFO;
4557		sigemptyset(&sa.sa_mask);
4558
4559		FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
4560
4561		printf("Before raising %s from child\n", strsignal(sigval));
4562		FORKEE_ASSERT(raise(sigval) == 0);
4563
4564		FORKEE_ASSERT_EQ(siginfo2_caught, 1);
4565
4566		printf("Before exiting of the child process\n");
4567		_exit(exitval);
4568	}
4569	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4570
4571	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4572	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4573
4574	validate_status_stopped(status, sigval);
4575
4576	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4577	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4578
4579	printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
4580	printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4581	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4582	    info.psi_siginfo.si_errno);
4583
4584	printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
4585	ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
4586
4587	printf("Before resuming the child process where it left off and "
4588	    "without signal to be sent\n");
4589	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1);
4590
4591	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4592	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4593
4594	validate_status_exited(status, exitval);
4595
4596	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4597	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4598}
4599
4600ATF_TC(siginfo3);
4601ATF_TC_HEAD(siginfo3, tc)
4602{
4603	atf_tc_set_md_var(tc, "descr",
4604	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with "
4605	    "setting signal to new value");
4606}
4607
4608static int siginfo3_caught = 0;
4609
4610static void
4611siginfo3_sigaction(int sig, siginfo_t *info, void *ctx)
4612{
4613	FORKEE_ASSERT_EQ(sig, SIGTRAP);
4614
4615	FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);
4616	FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);
4617
4618	++siginfo3_caught;
4619}
4620
4621ATF_TC_BODY(siginfo3, tc)
4622{
4623	const int exitval = 5;
4624	const int sigval = SIGINT;
4625	const int sigfaked = SIGTRAP;
4626	const int sicodefaked = TRAP_BRKPT;
4627	pid_t child, wpid;
4628	struct sigaction sa;
4629#if defined(TWAIT_HAVE_STATUS)
4630	int status;
4631#endif
4632	struct ptrace_siginfo info;
4633	memset(&info, 0, sizeof(info));
4634
4635	printf("Before forking process PID=%d\n", getpid());
4636	ATF_REQUIRE((child = fork()) != -1);
4637	if (child == 0) {
4638		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4639		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4640
4641		sa.sa_sigaction = siginfo3_sigaction;
4642		sa.sa_flags = SA_SIGINFO;
4643		sigemptyset(&sa.sa_mask);
4644
4645		FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1);
4646
4647		printf("Before raising %s from child\n", strsignal(sigval));
4648		FORKEE_ASSERT(raise(sigval) == 0);
4649
4650		FORKEE_ASSERT_EQ(siginfo3_caught, 1);
4651
4652		printf("Before exiting of the child process\n");
4653		_exit(exitval);
4654	}
4655	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4656
4657	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4658	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4659
4660	validate_status_stopped(status, sigval);
4661
4662	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4663	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4664
4665	printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
4666	printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4667	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4668	    info.psi_siginfo.si_errno);
4669
4670	printf("Before setting new faked signal to signo=%d si_code=%d\n",
4671	    sigfaked, sicodefaked);
4672	info.psi_siginfo.si_signo = sigfaked;
4673	info.psi_siginfo.si_code = sicodefaked;
4674
4675	printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
4676	ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
4677
4678	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4679	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4680
4681	printf("Before checking siginfo_t\n");
4682	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
4683	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
4684
4685	printf("Before resuming the child process where it left off and "
4686	    "without signal to be sent\n");
4687	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1);
4688
4689	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4690	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4691
4692	validate_status_exited(status, exitval);
4693
4694	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4695	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4696}
4697
4698ATF_TC(siginfo4);
4699ATF_TC_HEAD(siginfo4, tc)
4700{
4701	atf_tc_set_md_var(tc, "descr",
4702	    "Detect SIGTRAP TRAP_EXEC from tracee");
4703}
4704
4705ATF_TC_BODY(siginfo4, tc)
4706{
4707	const int sigval = SIGTRAP;
4708	pid_t child, wpid;
4709#if defined(TWAIT_HAVE_STATUS)
4710	int status;
4711#endif
4712
4713	struct ptrace_siginfo info;
4714	memset(&info, 0, sizeof(info));
4715
4716	printf("Before forking process PID=%d\n", getpid());
4717	ATF_REQUIRE((child = fork()) != -1);
4718	if (child == 0) {
4719		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4720		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4721
4722		printf("Before calling execve(2) from child\n");
4723		execlp("/bin/echo", "/bin/echo", NULL);
4724
4725		FORKEE_ASSERT(0 && "Not reached");
4726	}
4727	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4728
4729	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4730	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4731
4732	validate_status_stopped(status, sigval);
4733
4734	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4735	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4736
4737	printf("Signal traced to lwpid=%d\n", info.psi_lwpid);
4738	printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4739	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4740	    info.psi_siginfo.si_errno);
4741
4742	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4743	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
4744
4745	printf("Before resuming the child process where it left off and "
4746	    "without signal to be sent\n");
4747	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4748
4749	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4750	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4751
4752	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4753	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4754}
4755
4756#if defined(TWAIT_HAVE_PID)
4757ATF_TC(siginfo5);
4758ATF_TC_HEAD(siginfo5, tc)
4759{
4760	atf_tc_set_md_var(tc, "descr",
4761	    "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
4762	    "set to PTRACE_FORK and reports correct signal information");
4763}
4764
4765ATF_TC_BODY(siginfo5, tc)
4766{
4767	const int exitval = 5;
4768	const int exitval2 = 15;
4769	const int sigval = SIGSTOP;
4770	pid_t child, child2, wpid;
4771#if defined(TWAIT_HAVE_STATUS)
4772	int status;
4773#endif
4774	ptrace_state_t state;
4775	const int slen = sizeof(state);
4776	ptrace_event_t event;
4777	const int elen = sizeof(event);
4778	struct ptrace_siginfo info;
4779
4780	memset(&info, 0, sizeof(info));
4781
4782	printf("Before forking process PID=%d\n", getpid());
4783	ATF_REQUIRE((child = fork()) != -1);
4784	if (child == 0) {
4785		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4786		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4787
4788		printf("Before raising %s from child\n", strsignal(sigval));
4789		FORKEE_ASSERT(raise(sigval) == 0);
4790
4791		FORKEE_ASSERT((child2 = fork()) != 1);
4792
4793		if (child2 == 0)
4794			_exit(exitval2);
4795
4796		FORKEE_REQUIRE_SUCCESS
4797		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
4798
4799		forkee_status_exited(status, exitval2);
4800
4801		printf("Before exiting of the child process\n");
4802		_exit(exitval);
4803	}
4804	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4805
4806	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4807	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4808
4809	validate_status_stopped(status, sigval);
4810
4811	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4812	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4813
4814	printf("Before checking siginfo_t\n");
4815	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4816	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4817
4818	printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
4819	event.pe_set_event = PTRACE_FORK;
4820	ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
4821
4822	printf("Before resuming the child process where it left off and "
4823	    "without signal to be sent\n");
4824	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4825
4826	printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
4827	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4828
4829	validate_status_stopped(status, SIGTRAP);
4830
4831	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4832	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4833
4834	printf("Before checking siginfo_t\n");
4835	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4836	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
4837
4838	ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4839	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
4840
4841	child2 = state.pe_other_pid;
4842	printf("Reported PTRACE_FORK event with forkee %d\n", child2);
4843
4844	printf("Before calling %s() for the forkee %d of the child %d\n",
4845	    TWAIT_FNAME, child2, child);
4846	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
4847	    child2);
4848
4849	validate_status_stopped(status, SIGTRAP);
4850
4851	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4852	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4853
4854	printf("Before checking siginfo_t\n");
4855	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4856	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD);
4857
4858	ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
4859	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
4860	ATF_REQUIRE_EQ(state.pe_other_pid, child);
4861
4862	printf("Before resuming the forkee process where it left off and "
4863	    "without signal to be sent\n");
4864	ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
4865
4866	printf("Before resuming the child process where it left off and "
4867	    "without signal to be sent\n");
4868	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4869
4870	printf("Before calling %s() for the forkee - expected exited\n",
4871	    TWAIT_FNAME);
4872	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
4873	    child2);
4874
4875	validate_status_exited(status, exitval2);
4876
4877	printf("Before calling %s() for the forkee - expected no process\n",
4878	    TWAIT_FNAME);
4879	TWAIT_REQUIRE_FAILURE(ECHILD,
4880	    wpid = TWAIT_GENERIC(child2, &status, 0));
4881
4882	printf("Before calling %s() for the child - expected stopped "
4883	    "SIGCHLD\n", TWAIT_FNAME);
4884	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4885
4886	validate_status_stopped(status, SIGCHLD);
4887
4888	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4889	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4890
4891	printf("Before checking siginfo_t\n");
4892	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD);
4893	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED);
4894
4895	printf("Before resuming the child process where it left off and "
4896	    "without signal to be sent\n");
4897	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4898
4899	printf("Before calling %s() for the child - expected exited\n",
4900	    TWAIT_FNAME);
4901	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4902
4903	validate_status_exited(status, exitval);
4904
4905	printf("Before calling %s() for the child - expected no process\n",
4906	    TWAIT_FNAME);
4907	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4908}
4909#endif
4910
4911#if defined(PT_STEP)
4912ATF_TC(siginfo6);
4913ATF_TC_HEAD(siginfo6, tc)
4914{
4915	atf_tc_set_md_var(tc, "descr",
4916	    "Verify single PT_STEP call with signal information check");
4917}
4918
4919ATF_TC_BODY(siginfo6, tc)
4920{
4921	const int exitval = 5;
4922	const int sigval = SIGSTOP;
4923	pid_t child, wpid;
4924#if defined(TWAIT_HAVE_STATUS)
4925	int status;
4926#endif
4927	int happy;
4928	struct ptrace_siginfo info;
4929
4930	memset(&info, 0, sizeof(info));
4931
4932	printf("Before forking process PID=%d\n", getpid());
4933	ATF_REQUIRE((child = fork()) != -1);
4934	if (child == 0) {
4935		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
4936		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4937
4938		happy = check_happy(100);
4939
4940		printf("Before raising %s from child\n", strsignal(sigval));
4941		FORKEE_ASSERT(raise(sigval) == 0);
4942
4943		FORKEE_ASSERT_EQ(happy, check_happy(100));
4944
4945		printf("Before exiting of the child process\n");
4946		_exit(exitval);
4947	}
4948	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4949
4950	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4951	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4952
4953	validate_status_stopped(status, sigval);
4954
4955	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4956	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4957
4958	printf("Before checking siginfo_t\n");
4959	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4960	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4961
4962	printf("Before resuming the child process where it left off and "
4963	    "without signal to be sent (use PT_STEP)\n");
4964	ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1);
4965
4966	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4967	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4968
4969	validate_status_stopped(status, SIGTRAP);
4970
4971	printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4972	ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4973
4974	printf("Before checking siginfo_t\n");
4975	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4976	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE);
4977
4978	printf("Before resuming the child process where it left off and "
4979	    "without signal to be sent\n");
4980	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4981
4982	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4983	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4984
4985	validate_status_exited(status, exitval);
4986
4987	printf("Before calling %s() for the child\n", TWAIT_FNAME);
4988	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4989}
4990#endif
4991
4992ATF_TP_ADD_TCS(tp)
4993{
4994	setvbuf(stdout, NULL, _IONBF, 0);
4995	setvbuf(stderr, NULL, _IONBF, 0);
4996	ATF_TP_ADD_TC(tp, traceme1);
4997	ATF_TP_ADD_TC(tp, traceme2);
4998	ATF_TP_ADD_TC(tp, traceme3);
4999	ATF_TP_ADD_TC(tp, traceme4);
5000
5001	ATF_TP_ADD_TC_HAVE_PID(tp, attach1);
5002	ATF_TP_ADD_TC_HAVE_PID(tp, attach2);
5003	ATF_TP_ADD_TC(tp, attach3);
5004	ATF_TP_ADD_TC(tp, attach4);
5005	ATF_TP_ADD_TC_HAVE_PID(tp, attach5);
5006	ATF_TP_ADD_TC_HAVE_PID(tp, attach6);
5007	ATF_TP_ADD_TC_HAVE_PID(tp, attach7);
5008
5009	ATF_TP_ADD_TC(tp, eventmask1);
5010	ATF_TP_ADD_TC(tp, eventmask2);
5011
5012	ATF_TP_ADD_TC_HAVE_PID(tp, fork1);
5013	ATF_TP_ADD_TC(tp, fork2);
5014
5015	ATF_TP_ADD_TC_HAVE_PID(tp, vfork1);
5016	ATF_TP_ADD_TC(tp, vfork2);
5017
5018	ATF_TP_ADD_TC(tp, io_read_d1);
5019	ATF_TP_ADD_TC(tp, io_read_d2);
5020	ATF_TP_ADD_TC(tp, io_read_d3);
5021	ATF_TP_ADD_TC(tp, io_read_d4);
5022
5023	ATF_TP_ADD_TC(tp, io_write_d1);
5024	ATF_TP_ADD_TC(tp, io_write_d2);
5025	ATF_TP_ADD_TC(tp, io_write_d3);
5026	ATF_TP_ADD_TC(tp, io_write_d4);
5027
5028	ATF_TP_ADD_TC(tp, read_d1);
5029	ATF_TP_ADD_TC(tp, read_d2);
5030	ATF_TP_ADD_TC(tp, read_d3);
5031	ATF_TP_ADD_TC(tp, read_d4);
5032
5033	ATF_TP_ADD_TC(tp, write_d1);
5034	ATF_TP_ADD_TC(tp, write_d2);
5035	ATF_TP_ADD_TC(tp, write_d3);
5036	ATF_TP_ADD_TC(tp, write_d4);
5037
5038	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1);
5039	ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2);
5040
5041	ATF_TP_ADD_TC(tp, read_d_write_d_handshake1);
5042	ATF_TP_ADD_TC(tp, read_d_write_d_handshake2);
5043
5044	ATF_TP_ADD_TC(tp, io_read_i1);
5045	ATF_TP_ADD_TC(tp, io_read_i2);
5046	ATF_TP_ADD_TC(tp, io_read_i3);
5047	ATF_TP_ADD_TC(tp, io_read_i4);
5048
5049	ATF_TP_ADD_TC(tp, read_i1);
5050	ATF_TP_ADD_TC(tp, read_i2);
5051	ATF_TP_ADD_TC(tp, read_i3);
5052	ATF_TP_ADD_TC(tp, read_i4);
5053
5054	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
5055	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2);
5056	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3);
5057	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4);
5058	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5);
5059
5060	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1);
5061	ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2);
5062
5063	ATF_TP_ADD_TC_PT_STEP(tp, step1);
5064	ATF_TP_ADD_TC_PT_STEP(tp, step2);
5065	ATF_TP_ADD_TC_PT_STEP(tp, step3);
5066	ATF_TP_ADD_TC_PT_STEP(tp, step4);
5067
5068	ATF_TP_ADD_TC(tp, kill1);
5069	ATF_TP_ADD_TC(tp, kill2);
5070
5071	ATF_TP_ADD_TC(tp, lwpinfo1);
5072	ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2);
5073
5074	ATF_TP_ADD_TC(tp, siginfo1);
5075	ATF_TP_ADD_TC(tp, siginfo2);
5076	ATF_TP_ADD_TC(tp, siginfo3);
5077	ATF_TP_ADD_TC(tp, siginfo4);
5078	ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5);
5079	ATF_TP_ADD_TC_PT_STEP(tp, siginfo6);
5080
5081	return atf_no_error();
5082}
5083