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