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