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