Home | History | Annotate | Line # | Download | only in sys
t_ptrace_fork_wait.h revision 1.7
      1 /*	$NetBSD: t_ptrace_fork_wait.h,v 1.7 2020/06/09 00:28:57 kamil Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2016, 2017, 2018, 2020 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 
     30 static void
     31 fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork,
     32     bool trackvforkdone, bool newpgrp)
     33 {
     34 	const int exitval = 5;
     35 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
     36 	const int sigval = SIGSTOP;
     37 	pid_t child, child2 = 0, wpid;
     38 #if defined(TWAIT_HAVE_STATUS)
     39 	int status;
     40 #endif
     41 	sigset_t set;
     42 	ptrace_state_t state;
     43 	const int slen = sizeof(state);
     44 	ptrace_event_t event;
     45 	const int elen = sizeof(event);
     46 
     47 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
     48 
     49 	if (newpgrp)
     50 		atf_tc_skip("kernel panic (pg_jobc going negative)");
     51 
     52 	DPRINTF("Before forking process PID=%d\n", getpid());
     53 	SYSCALL_REQUIRE((child = fork()) != -1);
     54 	if (child == 0) {
     55 		if (newpgrp) {
     56 			DPRINTF("Before entering new process group");
     57 			setpgid(0, 0);
     58 		}
     59 
     60 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
     61 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
     62 
     63 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
     64 		FORKEE_ASSERT(raise(sigval) == 0);
     65 
     66 		if (strcmp(fn, "spawn") == 0) {
     67 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
     68 			    arg[0], NULL, NULL, arg, NULL), 0);
     69 		} else {
     70 			if (strcmp(fn, "fork") == 0) {
     71 				FORKEE_ASSERT((child2 = fork()) != -1);
     72 			} else if (strcmp(fn, "vfork") == 0) {
     73 				FORKEE_ASSERT((child2 = vfork()) != -1);
     74 			}
     75 
     76 			if (child2 == 0)
     77 				_exit(exitval2);
     78 		}
     79 		FORKEE_REQUIRE_SUCCESS
     80 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
     81 
     82 		forkee_status_exited(status, exitval2);
     83 
     84 		DPRINTF("Before exiting of the child process\n");
     85 		_exit(exitval);
     86 	}
     87 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
     88 
     89 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
     90 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
     91 
     92 	validate_status_stopped(status, sigval);
     93 
     94 	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
     95 	    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
     96 	    trackfork ? "|PTRACE_FORK" : "",
     97 	    trackvfork ? "|PTRACE_VFORK" : "",
     98 	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
     99 	event.pe_set_event = 0;
    100 	if (trackspawn)
    101 		event.pe_set_event |= PTRACE_POSIX_SPAWN;
    102 	if (trackfork)
    103 		event.pe_set_event |= PTRACE_FORK;
    104 	if (trackvfork)
    105 		event.pe_set_event |= PTRACE_VFORK;
    106 	if (trackvforkdone)
    107 		event.pe_set_event |= PTRACE_VFORK_DONE;
    108 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
    109 
    110 	/*
    111 	 * Ignore interception of the SIGCHLD signals.
    112 	 *
    113 	 * SIGCHLD once blocked is discarded by the kernel as it has the
    114 	 * SA_IGNORE property. During the fork(2) operation all signals can be
    115 	 * shortly blocked and missed (unless there is a registered signal
    116 	 * handler in the traced child). This leads to a race in this test if
    117 	 * there would be an intention to catch SIGCHLD.
    118 	 */
    119 	sigemptyset(&set);
    120 	sigaddset(&set, SIGCHLD);
    121 	SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1);
    122 
    123 	DPRINTF("Before resuming the child process where it left off and "
    124 	    "without signal to be sent\n");
    125 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    126 
    127 #if defined(TWAIT_HAVE_PID)
    128 	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    129 	    (trackfork && strcmp(fn, "fork") == 0) ||
    130 	    (trackvfork && strcmp(fn, "vfork") == 0)) {
    131 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
    132 		    child);
    133 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    134 		    child);
    135 
    136 		validate_status_stopped(status, SIGTRAP);
    137 
    138 		SYSCALL_REQUIRE(
    139 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    140 		if (trackspawn && strcmp(fn, "spawn") == 0) {
    141 			ATF_REQUIRE_EQ(
    142 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
    143 			       PTRACE_POSIX_SPAWN);
    144 		}
    145 		if (trackfork && strcmp(fn, "fork") == 0) {
    146 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    147 			       PTRACE_FORK);
    148 		}
    149 		if (trackvfork && strcmp(fn, "vfork") == 0) {
    150 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    151 			       PTRACE_VFORK);
    152 		}
    153 
    154 		child2 = state.pe_other_pid;
    155 		DPRINTF("Reported ptrace event with forkee %d\n", child2);
    156 
    157 		DPRINTF("Before calling %s() for the forkee %d of the child "
    158 		    "%d\n", TWAIT_FNAME, child2, child);
    159 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
    160 		    child2);
    161 
    162 		validate_status_stopped(status, SIGTRAP);
    163 
    164 		SYSCALL_REQUIRE(
    165 		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
    166 		if (trackspawn && strcmp(fn, "spawn") == 0) {
    167 			ATF_REQUIRE_EQ(
    168 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
    169 			       PTRACE_POSIX_SPAWN);
    170 		}
    171 		if (trackfork && strcmp(fn, "fork") == 0) {
    172 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    173 			       PTRACE_FORK);
    174 		}
    175 		if (trackvfork && strcmp(fn, "vfork") == 0) {
    176 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    177 			       PTRACE_VFORK);
    178 		}
    179 
    180 		ATF_REQUIRE_EQ(state.pe_other_pid, child);
    181 
    182 		DPRINTF("Before resuming the forkee process where it left off "
    183 		    "and without signal to be sent\n");
    184 		SYSCALL_REQUIRE(
    185 		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
    186 
    187 		DPRINTF("Before resuming the child process where it left off "
    188 		    "and without signal to be sent\n");
    189 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    190 	}
    191 #endif
    192 
    193 	if (trackvforkdone && strcmp(fn, "vfork") == 0) {
    194 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
    195 		    child);
    196 		TWAIT_REQUIRE_SUCCESS(
    197 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
    198 
    199 		validate_status_stopped(status, SIGTRAP);
    200 
    201 		SYSCALL_REQUIRE(
    202 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    203 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
    204 
    205 		child2 = state.pe_other_pid;
    206 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
    207 		    child2);
    208 
    209 		DPRINTF("Before resuming the child process where it left off "
    210 		    "and without signal to be sent\n");
    211 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    212 	}
    213 
    214 #if defined(TWAIT_HAVE_PID)
    215 	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    216 	    (trackfork && strcmp(fn, "fork") == 0) ||
    217 	    (trackvfork && strcmp(fn, "vfork") == 0)) {
    218 		DPRINTF("Before calling %s() for the forkee - expected exited"
    219 		    "\n", TWAIT_FNAME);
    220 		TWAIT_REQUIRE_SUCCESS(
    221 		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    222 
    223 		validate_status_exited(status, exitval2);
    224 
    225 		DPRINTF("Before calling %s() for the forkee - expected no "
    226 		    "process\n", TWAIT_FNAME);
    227 		TWAIT_REQUIRE_FAILURE(ECHILD,
    228 		    wpid = TWAIT_GENERIC(child2, &status, 0));
    229 	}
    230 #endif
    231 
    232 	DPRINTF("Before calling %s() for the child - expected exited\n",
    233 	    TWAIT_FNAME);
    234 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    235 
    236 	validate_status_exited(status, exitval);
    237 
    238 	DPRINTF("Before calling %s() for the child - expected no process\n",
    239 	    TWAIT_FNAME);
    240 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    241 }
    242 
    243 #define FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp)	\
    244 ATF_TC(name);								\
    245 ATF_TC_HEAD(name, tc)							\
    246 {									\
    247 	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
    248 	    "called with 0%s%s%s%s in EVENT_MASK%s",			\
    249 	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
    250 	    tfork ? "|PTRACE_FORK" : "",				\
    251 	    tvfork ? "|PTRACE_VFORK" : "",				\
    252 	    tvforkdone ? "|PTRACE_VFORK_DONE" : "",			\
    253 	    newpgrp ? " and the traced processes call setpgrp(0,0)":"");\
    254 }									\
    255 									\
    256 ATF_TC_BODY(name, tc)							\
    257 {									\
    258 									\
    259 	fork_body(fun, tspawn, tfork, tvfork, tvforkdone, newpgrp);	\
    260 }
    261 
    262 #define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)		\
    263 	FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false)
    264 
    265 FORK_TEST(fork1, "fork", false, false, false, false)
    266 #if defined(TWAIT_HAVE_PID)
    267 FORK_TEST(fork2, "fork", false, true, false, false)
    268 FORK_TEST(fork3, "fork", false, false, true, false)
    269 FORK_TEST(fork4, "fork", false, true, true, false)
    270 #endif
    271 FORK_TEST(fork5, "fork", false, false, false, true)
    272 #if defined(TWAIT_HAVE_PID)
    273 FORK_TEST(fork6, "fork", false, true, false, true)
    274 FORK_TEST(fork7, "fork", false, false, true, true)
    275 FORK_TEST(fork8, "fork", false, true, true, true)
    276 #endif
    277 FORK_TEST(fork9, "fork", true, false, false, false)
    278 #if defined(TWAIT_HAVE_PID)
    279 FORK_TEST(fork10, "fork", true, true, false, false)
    280 FORK_TEST(fork11, "fork", true, false, true, false)
    281 FORK_TEST(fork12, "fork", true, true, true, false)
    282 #endif
    283 FORK_TEST(fork13, "fork", true, false, false, true)
    284 #if defined(TWAIT_HAVE_PID)
    285 FORK_TEST(fork14, "fork", true, true, false, true)
    286 FORK_TEST(fork15, "fork", true, false, true, true)
    287 FORK_TEST(fork16, "fork", true, true, true, true)
    288 #endif
    289 
    290 #if defined(TWAIT_HAVE_PID)
    291 FORK_TEST2(fork_setpgid, "fork", true, true, true, true, true)
    292 #endif
    293 
    294 FORK_TEST(vfork1, "vfork", false, false, false, false)
    295 #if defined(TWAIT_HAVE_PID)
    296 FORK_TEST(vfork2, "vfork", false, true, false, false)
    297 FORK_TEST(vfork3, "vfork", false, false, true, false)
    298 FORK_TEST(vfork4, "vfork", false, true, true, false)
    299 #endif
    300 FORK_TEST(vfork5, "vfork", false, false, false, true)
    301 #if defined(TWAIT_HAVE_PID)
    302 FORK_TEST(vfork6, "vfork", false, true, false, true)
    303 FORK_TEST(vfork7, "vfork", false, false, true, true)
    304 FORK_TEST(vfork8, "vfork", false, true, true, true)
    305 #endif
    306 FORK_TEST(vfork9, "vfork", true, false, false, false)
    307 #if defined(TWAIT_HAVE_PID)
    308 FORK_TEST(vfork10, "vfork", true, true, false, false)
    309 FORK_TEST(vfork11, "vfork", true, false, true, false)
    310 FORK_TEST(vfork12, "vfork", true, true, true, false)
    311 #endif
    312 FORK_TEST(vfork13, "vfork", true, false, false, true)
    313 #if defined(TWAIT_HAVE_PID)
    314 FORK_TEST(vfork14, "vfork", true, true, false, true)
    315 FORK_TEST(vfork15, "vfork", true, false, true, true)
    316 FORK_TEST(vfork16, "vfork", true, true, true, true)
    317 #endif
    318 
    319 #if defined(TWAIT_HAVE_PID)
    320 FORK_TEST2(vfork_setpgid, "vfork", true, true, true, true, true)
    321 #endif
    322 
    323 FORK_TEST(posix_spawn1, "spawn", false, false, false, false)
    324 FORK_TEST(posix_spawn2, "spawn", false, true, false, false)
    325 FORK_TEST(posix_spawn3, "spawn", false, false, true, false)
    326 FORK_TEST(posix_spawn4, "spawn", false, true, true, false)
    327 FORK_TEST(posix_spawn5, "spawn", false, false, false, true)
    328 FORK_TEST(posix_spawn6, "spawn", false, true, false, true)
    329 FORK_TEST(posix_spawn7, "spawn", false, false, true, true)
    330 FORK_TEST(posix_spawn8, "spawn", false, true, true, true)
    331 #if defined(TWAIT_HAVE_PID)
    332 FORK_TEST(posix_spawn9, "spawn", true, false, false, false)
    333 FORK_TEST(posix_spawn10, "spawn", true, true, false, false)
    334 FORK_TEST(posix_spawn11, "spawn", true, false, true, false)
    335 FORK_TEST(posix_spawn12, "spawn", true, true, true, false)
    336 FORK_TEST(posix_spawn13, "spawn", true, false, false, true)
    337 FORK_TEST(posix_spawn14, "spawn", true, true, false, true)
    338 FORK_TEST(posix_spawn15, "spawn", true, false, true, true)
    339 FORK_TEST(posix_spawn16, "spawn", true, true, true, true)
    340 #endif
    341 
    342 #if defined(TWAIT_HAVE_PID)
    343 FORK_TEST2(posix_spawn_setpgid, "spawn", true, true, true, true, true)
    344 #endif
    345 
    346 /// ----------------------------------------------------------------------------
    347 
    348 #if defined(TWAIT_HAVE_PID)
    349 static void
    350 unrelated_tracer_fork_body(const char *fn, bool trackspawn, bool trackfork,
    351     bool trackvfork, bool trackvforkdone, bool newpgrp)
    352 {
    353 	const int sigval = SIGSTOP;
    354 	struct msg_fds parent_tracee, parent_tracer;
    355 	const int exitval = 10;
    356 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
    357 	pid_t tracee, tracer, wpid;
    358 	pid_t tracee2 = 0;
    359 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
    360 #if defined(TWAIT_HAVE_STATUS)
    361 	int status;
    362 #endif
    363 
    364 	sigset_t set;
    365 	struct ptrace_siginfo info;
    366 	ptrace_state_t state;
    367 	const int slen = sizeof(state);
    368 	ptrace_event_t event;
    369 	const int elen = sizeof(event);
    370 
    371 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
    372 
    373 	if (newpgrp)
    374 		atf_tc_skip("kernel panic (pg_jobc going negative)");
    375 
    376 	DPRINTF("Spawn tracee\n");
    377 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
    378 	tracee = atf_utils_fork();
    379 	if (tracee == 0) {
    380 		if (newpgrp) {
    381 			DPRINTF("Before entering new process group");
    382 			setpgid(0, 0);
    383 		}
    384 
    385 		// Wait for parent to let us crash
    386 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
    387 
    388 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    389 		FORKEE_ASSERT(raise(sigval) == 0);
    390 
    391 		if (strcmp(fn, "spawn") == 0) {
    392 			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
    393 			    arg[0], NULL, NULL, arg, NULL), 0);
    394 		} else {
    395 			if (strcmp(fn, "fork") == 0) {
    396 				FORKEE_ASSERT((tracee2 = fork()) != -1);
    397 			} else if (strcmp(fn, "vfork") == 0) {
    398 				FORKEE_ASSERT((tracee2 = vfork()) != -1);
    399 			}
    400 
    401 			if (tracee2 == 0)
    402 				_exit(exitval2);
    403 		}
    404 		FORKEE_REQUIRE_SUCCESS
    405 		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
    406 
    407 		forkee_status_exited(status, exitval2);
    408 
    409 		DPRINTF("Before exiting of the child process\n");
    410 		_exit(exitval);
    411 	}
    412 
    413 	DPRINTF("Spawn debugger\n");
    414 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
    415 	tracer = atf_utils_fork();
    416 	if (tracer == 0) {
    417 		/* Fork again and drop parent to reattach to PID 1 */
    418 		tracer = atf_utils_fork();
    419 		if (tracer != 0)
    420 			_exit(exitval);
    421 
    422 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
    423 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
    424 
    425 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
    426 		FORKEE_REQUIRE_SUCCESS(
    427 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    428 
    429 		forkee_status_stopped(status, SIGSTOP);
    430 
    431 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
    432 		    "traced process\n");
    433 		SYSCALL_REQUIRE(
    434 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
    435 
    436 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    437 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    438 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
    439 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
    440 
    441 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
    442 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
    443 
    444 		/* Resume tracee with PT_CONTINUE */
    445 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    446 
    447 		/* Inform parent that tracer has attached to tracee */
    448 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
    449 
    450 		/* Wait for parent to tell use that tracee should have exited */
    451 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
    452 
    453 		/* Wait for tracee and assert that it exited */
    454 		FORKEE_REQUIRE_SUCCESS(
    455 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    456 
    457 		forkee_status_stopped(status, sigval);
    458 
    459 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
    460 		    "traced process\n");
    461 		SYSCALL_REQUIRE(
    462 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
    463 
    464 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    465 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    466 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
    467 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
    468 
    469 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
    470 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
    471 
    472 		DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
    473 		    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
    474 		    trackfork ? "|PTRACE_FORK" : "",
    475 		    trackvfork ? "|PTRACE_VFORK" : "",
    476 		    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", tracee);
    477 		event.pe_set_event = 0;
    478 		if (trackspawn)
    479 			event.pe_set_event |= PTRACE_POSIX_SPAWN;
    480 		if (trackfork)
    481 			event.pe_set_event |= PTRACE_FORK;
    482 		if (trackvfork)
    483 			event.pe_set_event |= PTRACE_VFORK;
    484 		if (trackvforkdone)
    485 			event.pe_set_event |= PTRACE_VFORK_DONE;
    486 		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen)
    487 		    != -1);
    488 
    489 		/*
    490 		 * Ignore interception of the SIGCHLD signals.
    491 		 *
    492 		 * SIGCHLD once blocked is discarded by the kernel as it has the
    493 		 * SA_IGNORE property. During the fork(2) operation all signals
    494 		 * can be shortly blocked and missed (unless there is a
    495 		 * registered signal handler in the traced child). This leads to
    496 		 * a race in this test if there would be an intention to catch
    497 		 * SIGCHLD.
    498 		 */
    499 		sigemptyset(&set);
    500 		sigaddset(&set, SIGCHLD);
    501 		SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, tracee, &set,
    502 		    sizeof(set)) != -1);
    503 
    504 		DPRINTF("Before resuming the child process where it left off "
    505 		    "and without signal to be sent\n");
    506 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    507 
    508 		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    509 		    (trackfork && strcmp(fn, "fork") == 0) ||
    510 		    (trackvfork && strcmp(fn, "vfork") == 0)) {
    511 			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
    512 			    tracee);
    513 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
    514 			    tracee);
    515 
    516 			validate_status_stopped(status, SIGTRAP);
    517 
    518 			SYSCALL_REQUIRE(
    519 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
    520 			if (trackspawn && strcmp(fn, "spawn") == 0) {
    521 				ATF_REQUIRE_EQ(
    522 				    state.pe_report_event & PTRACE_POSIX_SPAWN,
    523 				       PTRACE_POSIX_SPAWN);
    524 			}
    525 			if (trackfork && strcmp(fn, "fork") == 0) {
    526 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    527 				       PTRACE_FORK);
    528 			}
    529 			if (trackvfork && strcmp(fn, "vfork") == 0) {
    530 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    531 				       PTRACE_VFORK);
    532 			}
    533 
    534 			tracee2 = state.pe_other_pid;
    535 			DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
    536 
    537 			DPRINTF("Before calling %s() for the forkee %d of the tracee "
    538 			    "%d\n", TWAIT_FNAME, tracee2, tracee);
    539 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0),
    540 			    tracee2);
    541 
    542 			validate_status_stopped(status, SIGTRAP);
    543 
    544 			SYSCALL_REQUIRE(
    545 			    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
    546 			if (trackspawn && strcmp(fn, "spawn") == 0) {
    547 				ATF_REQUIRE_EQ(
    548 				    state.pe_report_event & PTRACE_POSIX_SPAWN,
    549 				       PTRACE_POSIX_SPAWN);
    550 			}
    551 			if (trackfork && strcmp(fn, "fork") == 0) {
    552 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
    553 				       PTRACE_FORK);
    554 			}
    555 			if (trackvfork && strcmp(fn, "vfork") == 0) {
    556 				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
    557 				       PTRACE_VFORK);
    558 			}
    559 
    560 			ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
    561 
    562 			DPRINTF("Before resuming the forkee process where it left off "
    563 			    "and without signal to be sent\n");
    564 			SYSCALL_REQUIRE(
    565 			    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
    566 
    567 			DPRINTF("Before resuming the tracee process where it left off "
    568 			    "and without signal to be sent\n");
    569 			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    570 		}
    571 
    572 		if (trackvforkdone && strcmp(fn, "vfork") == 0) {
    573 			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
    574 			    tracee);
    575 			TWAIT_REQUIRE_SUCCESS(
    576 			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    577 
    578 			validate_status_stopped(status, SIGTRAP);
    579 
    580 			SYSCALL_REQUIRE(
    581 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
    582 			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
    583 
    584 			tracee2 = state.pe_other_pid;
    585 			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
    586 			    tracee2);
    587 
    588 			DPRINTF("Before resuming the tracee process where it left off "
    589 			    "and without signal to be sent\n");
    590 			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
    591 		}
    592 
    593 
    594 		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
    595 		    (trackfork && strcmp(fn, "fork") == 0) ||
    596 		    (trackvfork && strcmp(fn, "vfork") == 0)) {
    597 			DPRINTF("Before calling %s() for the forkee - expected exited"
    598 			    "\n", TWAIT_FNAME);
    599 			TWAIT_REQUIRE_SUCCESS(
    600 			    wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
    601 
    602 			validate_status_exited(status, exitval2);
    603 
    604 			DPRINTF("Before calling %s() for the forkee - expected no "
    605 			    "process\n", TWAIT_FNAME);
    606 			TWAIT_REQUIRE_FAILURE(ECHILD,
    607 			    wpid = TWAIT_GENERIC(tracee2, &status, 0));
    608 		}
    609 
    610 		DPRINTF("Before calling %s() for the tracee - expected exited\n",
    611 		    TWAIT_FNAME);
    612 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    613 
    614 		validate_status_exited(status, exitval);
    615 
    616 		/* Inform parent that tracer is exiting normally */
    617 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
    618 
    619 		DPRINTF("Before exiting of the tracer process\n");
    620 		_exit(0 /* collect by initproc */);
    621 	}
    622 
    623 	DPRINTF("Wait for the tracer process (direct child) to exit "
    624 	    "calling %s()\n", TWAIT_FNAME);
    625 	TWAIT_REQUIRE_SUCCESS(
    626 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
    627 
    628 	validate_status_exited(status, exitval);
    629 
    630 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
    631 	    TWAIT_FNAME);
    632 	TWAIT_REQUIRE_SUCCESS(
    633 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
    634 
    635 	DPRINTF("Wait for the tracer to attach to the tracee\n");
    636 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
    637 
    638 	DPRINTF("Resume the tracee and let it crash\n");
    639 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
    640 
    641 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
    642 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
    643 
    644 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
    645 	    TWAIT_FNAME);
    646 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
    647 
    648 	validate_status_exited(status, exitval);
    649 
    650 	DPRINTF("Await normal exit of tracer\n");
    651 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
    652 
    653 	msg_close(&parent_tracer);
    654 	msg_close(&parent_tracee);
    655 }
    656 
    657 #define UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,newpgrp)\
    658 ATF_TC(name);								\
    659 ATF_TC_HEAD(name, tc)							\
    660 {									\
    661 	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
    662 	    "called with 0%s%s%s%s in EVENT_MASK%s",			\
    663 	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
    664 	    tfork ? "|PTRACE_FORK" : "",				\
    665 	    tvfork ? "|PTRACE_VFORK" : "",				\
    666 	    tvforkdone ? "|PTRACE_VFORK_DONE" : "",			\
    667 	    newpgrp ? " and the traced processes call setpgrp(0,0)":"");\
    668 }									\
    669 									\
    670 ATF_TC_BODY(name, tc)							\
    671 {									\
    672 									\
    673 	unrelated_tracer_fork_body(fun, tspawn, tfork, tvfork,		\
    674 	    tvforkdone, newpgrp);					\
    675 }
    676 
    677 #define UNRELATED_TRACER_FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)	\
    678 	UNRELATED_TRACER_FORK_TEST2(name,fun,tspawn,tfork,tvfork,tvforkdone,false)
    679 
    680 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork1, "fork", false, false, false, false)
    681 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork2, "fork", false, true, false, false)
    682 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork3, "fork", false, false, true, false)
    683 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork4, "fork", false, true, true, false)
    684 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork5, "fork", false, false, false, true)
    685 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork6, "fork", false, true, false, true)
    686 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork7, "fork", false, false, true, true)
    687 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork8, "fork", false, true, true, true)
    688 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork9, "fork", true, false, false, false)
    689 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork10, "fork", true, true, false, false)
    690 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork11, "fork", true, false, true, false)
    691 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork12, "fork", true, true, true, false)
    692 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork13, "fork", true, false, false, true)
    693 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork14, "fork", true, true, false, true)
    694 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork15, "fork", true, false, true, true)
    695 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork16, "fork", true, true, true, true)
    696 
    697 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_fork_setpgid, "fork", true, true, true, true, true)
    698 
    699 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork1, "vfork", false, false, false, false)
    700 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork2, "vfork", false, true, false, false)
    701 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork3, "vfork", false, false, true, false)
    702 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork4, "vfork", false, true, true, false)
    703 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork5, "vfork", false, false, false, true)
    704 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork6, "vfork", false, true, false, true)
    705 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork7, "vfork", false, false, true, true)
    706 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork8, "vfork", false, true, true, true)
    707 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork9, "vfork", true, false, false, false)
    708 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork10, "vfork", true, true, false, false)
    709 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork11, "vfork", true, false, true, false)
    710 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork12, "vfork", true, true, true, false)
    711 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork13, "vfork", true, false, false, true)
    712 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork14, "vfork", true, true, false, true)
    713 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork15, "vfork", true, false, true, true)
    714 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork16, "vfork", true, true, true, true)
    715 
    716 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_vfork_setpgid, "vfork", true, true, true, true, true)
    717 
    718 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn1, "spawn", false, false, false, false)
    719 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn2, "spawn", false, true, false, false)
    720 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn3, "spawn", false, false, true, false)
    721 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn4, "spawn", false, true, true, false)
    722 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn5, "spawn", false, false, false, true)
    723 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn6, "spawn", false, true, false, true)
    724 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn7, "spawn", false, false, true, true)
    725 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn8, "spawn", false, true, true, true)
    726 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn9, "spawn", true, false, false, false)
    727 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn10, "spawn", true, true, false, false)
    728 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn11, "spawn", true, false, true, false)
    729 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn12, "spawn", true, true, true, false)
    730 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn13, "spawn", true, false, false, true)
    731 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn14, "spawn", true, true, false, true)
    732 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn15, "spawn", true, false, true, true)
    733 UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn16, "spawn", true, true, true, true)
    734 
    735 UNRELATED_TRACER_FORK_TEST2(unrelated_tracer_posix_spawn_setpgid, "spawn", true, true, true, true, true)
    736 #endif
    737 
    738 /// ----------------------------------------------------------------------------
    739 
    740 #if defined(TWAIT_HAVE_PID)
    741 static void
    742 fork_detach_forker_body(const char *fn, bool kill_process)
    743 {
    744 	const int exitval = 5;
    745 	const int exitval2 = 0; /* Matches exit value from /bin/echo */
    746 	const int sigval = SIGSTOP;
    747 	pid_t child, child2 = 0, wpid;
    748 #if defined(TWAIT_HAVE_STATUS)
    749 	int status;
    750 #endif
    751 	ptrace_state_t state;
    752 	const int slen = sizeof(state);
    753 	ptrace_event_t event;
    754 	const int elen = sizeof(event);
    755 
    756 	int op;
    757 
    758 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
    759 
    760 	DPRINTF("Before forking process PID=%d\n", getpid());
    761 	SYSCALL_REQUIRE((child = fork()) != -1);
    762 	if (child == 0) {
    763 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    764 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    765 
    766 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    767 		FORKEE_ASSERT(raise(sigval) == 0);
    768 
    769 		if (strcmp(fn, "spawn") == 0) {
    770 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
    771 			    arg[0], NULL, NULL, arg, NULL), 0);
    772 		} else  {
    773 			if (strcmp(fn, "fork") == 0) {
    774 				FORKEE_ASSERT((child2 = fork()) != -1);
    775 			} else {
    776 				FORKEE_ASSERT((child2 = vfork()) != -1);
    777 			}
    778 
    779 			if (child2 == 0)
    780 				_exit(exitval2);
    781 		}
    782 
    783 		FORKEE_REQUIRE_SUCCESS
    784 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    785 
    786 		forkee_status_exited(status, exitval2);
    787 
    788 		DPRINTF("Before exiting of the child process\n");
    789 		_exit(exitval);
    790 	}
    791 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    792 
    793 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    794 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    795 
    796 	validate_status_stopped(status, sigval);
    797 
    798 	DPRINTF("Set EVENT_MASK for the child %d\n", child);
    799 	event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
    800 		| PTRACE_VFORK_DONE;
    801 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
    802 
    803 	DPRINTF("Before resuming the child process where it left off and "
    804 	    "without signal to be sent\n");
    805 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    806 
    807 	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
    808 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    809 
    810 	validate_status_stopped(status, SIGTRAP);
    811 
    812 	SYSCALL_REQUIRE(
    813 	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    814 
    815 	if (strcmp(fn, "spawn") == 0)
    816 		op = PTRACE_POSIX_SPAWN;
    817 	else if (strcmp(fn, "fork") == 0)
    818 		op = PTRACE_FORK;
    819 	else
    820 		op = PTRACE_VFORK;
    821 
    822 	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
    823 
    824 	child2 = state.pe_other_pid;
    825 	DPRINTF("Reported ptrace event with forkee %d\n", child2);
    826 
    827 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
    828 	    strcmp(fn, "vfork") == 0)
    829 		op = kill_process ? PT_KILL : PT_DETACH;
    830 	else
    831 		op = PT_CONTINUE;
    832 	SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
    833 
    834 	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
    835 	    TWAIT_FNAME, child2, child);
    836 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    837 
    838 	validate_status_stopped(status, SIGTRAP);
    839 
    840 	SYSCALL_REQUIRE(
    841 	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
    842 	if (strcmp(fn, "spawn") == 0)
    843 		op = PTRACE_POSIX_SPAWN;
    844 	else if (strcmp(fn, "fork") == 0)
    845 		op = PTRACE_FORK;
    846 	else
    847 		op = PTRACE_VFORK;
    848 
    849 	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
    850 	ATF_REQUIRE_EQ(state.pe_other_pid, child);
    851 
    852 	DPRINTF("Before resuming the forkee process where it left off "
    853 	    "and without signal to be sent\n");
    854  	SYSCALL_REQUIRE(
    855 	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
    856 
    857 	if (strcmp(fn, "vforkdone") == 0) {
    858 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
    859 		    child);
    860 		TWAIT_REQUIRE_SUCCESS(
    861 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
    862 
    863 		validate_status_stopped(status, SIGTRAP);
    864 
    865 		SYSCALL_REQUIRE(
    866 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    867 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
    868 
    869 		child2 = state.pe_other_pid;
    870 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
    871 		    child2);
    872 
    873 		op = kill_process ? PT_KILL : PT_DETACH;
    874 		DPRINTF("Before resuming the child process where it left off "
    875 		    "and without signal to be sent\n");
    876 		SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
    877 	}
    878 
    879 	DPRINTF("Before calling %s() for the forkee - expected exited\n",
    880 	    TWAIT_FNAME);
    881 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
    882 
    883 	validate_status_exited(status, exitval2);
    884 
    885 	DPRINTF("Before calling %s() for the forkee - expected no process\n",
    886 	    TWAIT_FNAME);
    887 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0));
    888 
    889 	DPRINTF("Before calling %s() for the forkee - expected exited\n",
    890 	    TWAIT_FNAME);
    891 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    892 
    893 	if (kill_process) {
    894 		validate_status_signaled(status, SIGKILL, 0);
    895 	} else {
    896 		validate_status_exited(status, exitval);
    897 	}
    898 
    899 	DPRINTF("Before calling %s() for the child - expected no process\n",
    900 	    TWAIT_FNAME);
    901 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    902 }
    903 
    904 #define FORK_DETACH_FORKER(name,event,kprocess)				\
    905 ATF_TC(name);								\
    906 ATF_TC_HEAD(name, tc)							\
    907 {									\
    908 	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
    909 	    kprocess ? "killed" : "detached");				\
    910 }									\
    911 									\
    912 ATF_TC_BODY(name, tc)							\
    913 {									\
    914 									\
    915 	fork_detach_forker_body(event, kprocess);			\
    916 }
    917 
    918 FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false)
    919 FORK_DETACH_FORKER(fork_detach_forker, "fork", false)
    920 FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false)
    921 FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false)
    922 
    923 FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true)
    924 FORK_DETACH_FORKER(fork_kill_forker, "fork", true)
    925 FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true)
    926 FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true)
    927 #endif
    928 
    929 /// ----------------------------------------------------------------------------
    930 
    931 #if defined(TWAIT_HAVE_PID)
    932 static void
    933 unrelated_tracer_fork_detach_forker_body(const char *fn, bool kill_process)
    934 {
    935 	const int sigval = SIGSTOP;
    936 	struct msg_fds parent_tracee, parent_tracer;
    937 	const int exitval = 10;
    938 	const int exitval2 = 0; /* This matched exit status from /bin/echo */
    939 	pid_t tracee, tracer, wpid;
    940 	pid_t tracee2 = 0;
    941 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
    942 #if defined(TWAIT_HAVE_STATUS)
    943 	int status;
    944 #endif
    945 	int op;
    946 
    947 	struct ptrace_siginfo info;
    948 	ptrace_state_t state;
    949 	const int slen = sizeof(state);
    950 	ptrace_event_t event;
    951 	const int elen = sizeof(event);
    952 
    953 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
    954 
    955 	DPRINTF("Spawn tracee\n");
    956 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
    957 	tracee = atf_utils_fork();
    958 	if (tracee == 0) {
    959 		// Wait for parent to let us crash
    960 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
    961 
    962 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    963 		FORKEE_ASSERT(raise(sigval) == 0);
    964 
    965 		if (strcmp(fn, "spawn") == 0) {
    966 			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
    967 			    arg[0], NULL, NULL, arg, NULL), 0);
    968 		} else  {
    969 			if (strcmp(fn, "fork") == 0) {
    970 				FORKEE_ASSERT((tracee2 = fork()) != -1);
    971 			} else {
    972 				FORKEE_ASSERT((tracee2 = vfork()) != -1);
    973 			}
    974 
    975 			if (tracee2 == 0)
    976 				_exit(exitval2);
    977 		}
    978 
    979 		FORKEE_REQUIRE_SUCCESS
    980 		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
    981 
    982 		forkee_status_exited(status, exitval2);
    983 
    984 		DPRINTF("Before exiting of the child process\n");
    985 		_exit(exitval);
    986 	}
    987 
    988 	DPRINTF("Spawn debugger\n");
    989 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
    990 	tracer = atf_utils_fork();
    991 	if (tracer == 0) {
    992 		/* Fork again and drop parent to reattach to PID 1 */
    993 		tracer = atf_utils_fork();
    994 		if (tracer != 0)
    995 			_exit(exitval);
    996 
    997 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
    998 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
    999 
   1000 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
   1001 		FORKEE_REQUIRE_SUCCESS(
   1002 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1003 
   1004 		forkee_status_stopped(status, SIGSTOP);
   1005 
   1006 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
   1007 		    "traced process\n");
   1008 		SYSCALL_REQUIRE(
   1009 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
   1010 
   1011 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1012 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1013 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
   1014 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
   1015 
   1016 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
   1017 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
   1018 
   1019 		/* Resume tracee with PT_CONTINUE */
   1020 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
   1021 
   1022 		/* Inform parent that tracer has attached to tracee */
   1023 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
   1024 
   1025 		/* Wait for parent to tell use that tracee should have exited */
   1026 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
   1027 
   1028 		/* Wait for tracee and assert that it exited */
   1029 		FORKEE_REQUIRE_SUCCESS(
   1030 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1031 
   1032 		forkee_status_stopped(status, sigval);
   1033 
   1034 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
   1035 		    "traced process\n");
   1036 		SYSCALL_REQUIRE(
   1037 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
   1038 
   1039 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1040 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1041 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
   1042 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
   1043 
   1044 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
   1045 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
   1046 
   1047 		DPRINTF("Set EVENT_MASK for the child %d\n", tracee);
   1048 		event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
   1049 			| PTRACE_VFORK_DONE;
   1050 		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) != -1);
   1051 
   1052 		DPRINTF("Before resuming the child process where it left off and "
   1053 		    "without signal to be sent\n");
   1054 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
   1055 
   1056 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, tracee);
   1057 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1058 
   1059 		validate_status_stopped(status, SIGTRAP);
   1060 
   1061 		SYSCALL_REQUIRE(
   1062 		    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
   1063 
   1064 		if (strcmp(fn, "spawn") == 0)
   1065 			op = PTRACE_POSIX_SPAWN;
   1066 		else if (strcmp(fn, "fork") == 0)
   1067 			op = PTRACE_FORK;
   1068 		else
   1069 			op = PTRACE_VFORK;
   1070 
   1071 		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
   1072 
   1073 		tracee2 = state.pe_other_pid;
   1074 		DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
   1075 		if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
   1076 		    strcmp(fn, "vfork") == 0)
   1077 			op = kill_process ? PT_KILL : PT_DETACH;
   1078 		else
   1079 			op = PT_CONTINUE;
   1080 		SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
   1081 
   1082 		DPRINTF("Before calling %s() for the forkee %d of the tracee %d\n",
   1083 		    TWAIT_FNAME, tracee2, tracee);
   1084 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
   1085 
   1086 		validate_status_stopped(status, SIGTRAP);
   1087 
   1088 		SYSCALL_REQUIRE(
   1089 		    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
   1090 		if (strcmp(fn, "spawn") == 0)
   1091 			op = PTRACE_POSIX_SPAWN;
   1092 		else if (strcmp(fn, "fork") == 0)
   1093 			op = PTRACE_FORK;
   1094 		else
   1095 			op = PTRACE_VFORK;
   1096 
   1097 		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
   1098 		ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
   1099 
   1100 		DPRINTF("Before resuming the forkee process where it left off "
   1101 		    "and without signal to be sent\n");
   1102 		SYSCALL_REQUIRE(
   1103 		    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
   1104 
   1105 		if (strcmp(fn, "vforkdone") == 0) {
   1106 			DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
   1107 			    tracee);
   1108 			TWAIT_REQUIRE_SUCCESS(
   1109 			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1110 
   1111 			validate_status_stopped(status, SIGTRAP);
   1112 
   1113 			SYSCALL_REQUIRE(
   1114 			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
   1115 			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
   1116 
   1117 			tracee2 = state.pe_other_pid;
   1118 			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
   1119 			    tracee2);
   1120 
   1121 			op = kill_process ? PT_KILL : PT_DETACH;
   1122 			DPRINTF("Before resuming the child process where it left off "
   1123 			    "and without signal to be sent\n");
   1124 			SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
   1125 		}
   1126 
   1127 		DPRINTF("Before calling %s() for the forkee - expected exited\n",
   1128 		    TWAIT_FNAME);
   1129 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
   1130 
   1131 		validate_status_exited(status, exitval2);
   1132 
   1133 		DPRINTF("Before calling %s() for the forkee - expected no process\n",
   1134 		    TWAIT_FNAME);
   1135 		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(tracee2, &status, 0));
   1136 
   1137 		if (kill_process) {
   1138 			DPRINTF("Before calling %s() for the forkee - expected signaled\n",
   1139 			    TWAIT_FNAME);
   1140 			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1141 
   1142 			validate_status_signaled(status, SIGKILL, 0);
   1143 		}
   1144 
   1145 		/* Inform parent that tracer is exiting normally */
   1146 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
   1147 
   1148 		DPRINTF("Before exiting of the tracer process\n");
   1149 		_exit(0 /* collect by initproc */);
   1150 	}
   1151 
   1152 	DPRINTF("Wait for the tracer process (direct child) to exit "
   1153 	    "calling %s()\n", TWAIT_FNAME);
   1154 	TWAIT_REQUIRE_SUCCESS(
   1155 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
   1156 
   1157 	validate_status_exited(status, exitval);
   1158 
   1159 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
   1160 	    TWAIT_FNAME);
   1161 	TWAIT_REQUIRE_SUCCESS(
   1162 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
   1163 
   1164 	DPRINTF("Wait for the tracer to attach to the tracee\n");
   1165 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
   1166 
   1167 	DPRINTF("Resume the tracee and let it crash\n");
   1168 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
   1169 
   1170 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
   1171 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
   1172 
   1173 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
   1174 	    TWAIT_FNAME);
   1175 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1176 
   1177 	if (kill_process) {
   1178 		validate_status_signaled(status, SIGKILL, 0);
   1179 	} else {
   1180 		validate_status_exited(status, exitval);
   1181 	}
   1182 
   1183 	DPRINTF("Await normal exit of tracer\n");
   1184 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
   1185 
   1186 	msg_close(&parent_tracer);
   1187 	msg_close(&parent_tracee);
   1188 }
   1189 
   1190 #define UNRELATED_TRACER_FORK_DETACH_FORKER(name,event,kprocess)	\
   1191 ATF_TC(name);								\
   1192 ATF_TC_HEAD(name, tc)							\
   1193 {									\
   1194 	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
   1195 	    kprocess ? "killed" : "detached");				\
   1196 }									\
   1197 									\
   1198 ATF_TC_BODY(name, tc)							\
   1199 {									\
   1200 									\
   1201 	unrelated_tracer_fork_detach_forker_body(event, kprocess);	\
   1202 }
   1203 
   1204 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_detach_spawner, "spawn", false)
   1205 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_detach_forker, "fork", false)
   1206 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforker, "vfork", false)
   1207 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforkerdone, "vforkdone", false)
   1208 
   1209 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_kill_spawner, "spawn", true)
   1210 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_kill_forker, "fork", true)
   1211 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforker, "vfork", true)
   1212 UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforkerdone, "vforkdone", true)
   1213 #endif
   1214 
   1215 /// ----------------------------------------------------------------------------
   1216 
   1217 static void
   1218 traceme_vfork_fork_body(pid_t (*fn)(void))
   1219 {
   1220 	const int exitval = 5;
   1221 	const int exitval2 = 15;
   1222 	pid_t child, child2 = 0, wpid;
   1223 #if defined(TWAIT_HAVE_STATUS)
   1224 	int status;
   1225 #endif
   1226 
   1227 	DPRINTF("Before forking process PID=%d\n", getpid());
   1228 	SYSCALL_REQUIRE((child = vfork()) != -1);
   1229 	if (child == 0) {
   1230 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1231 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1232 
   1233 		FORKEE_ASSERT((child2 = (fn)()) != -1);
   1234 
   1235 		if (child2 == 0)
   1236 			_exit(exitval2);
   1237 
   1238 		FORKEE_REQUIRE_SUCCESS
   1239 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
   1240 
   1241 		forkee_status_exited(status, exitval2);
   1242 
   1243 		DPRINTF("Before exiting of the child process\n");
   1244 		_exit(exitval);
   1245 	}
   1246 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1247 
   1248 	DPRINTF("Before calling %s() for the child - expected exited\n",
   1249 	    TWAIT_FNAME);
   1250 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1251 
   1252 	validate_status_exited(status, exitval);
   1253 
   1254 	DPRINTF("Before calling %s() for the child - expected no process\n",
   1255 	    TWAIT_FNAME);
   1256 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1257 }
   1258 
   1259 #define TRACEME_VFORK_FORK_TEST(name,fun)				\
   1260 ATF_TC(name);								\
   1261 ATF_TC_HEAD(name, tc)							\
   1262 {									\
   1263 	atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) "		\
   1264 	    "called from vfork(2)ed child");				\
   1265 }									\
   1266 									\
   1267 ATF_TC_BODY(name, tc)							\
   1268 {									\
   1269 									\
   1270 	traceme_vfork_fork_body(fun);					\
   1271 }
   1272 
   1273 TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork)
   1274 TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork)
   1275 
   1276 /// ----------------------------------------------------------------------------
   1277 
   1278 #if defined(TWAIT_HAVE_PID)
   1279 static void
   1280 fork2_body(const char *fn, bool masked, bool ignored)
   1281 {
   1282 	const int exitval = 5;
   1283 	const int exitval2 = 0; /* Match exit status from /bin/echo */
   1284 	const int sigval = SIGSTOP;
   1285 	pid_t child, child2 = 0, wpid;
   1286 #if defined(TWAIT_HAVE_STATUS)
   1287 	int status;
   1288 #endif
   1289 	ptrace_state_t state;
   1290 	const int slen = sizeof(state);
   1291 	ptrace_event_t event;
   1292 	const int elen = sizeof(event);
   1293 	struct sigaction sa;
   1294 	struct ptrace_siginfo info;
   1295 	sigset_t intmask;
   1296 	struct kinfo_proc2 kp;
   1297 	size_t len = sizeof(kp);
   1298 
   1299 	int name[6];
   1300 	const size_t namelen = __arraycount(name);
   1301 	sigset_t set;
   1302 	ki_sigset_t kp_sigmask;
   1303 	ki_sigset_t kp_sigignore;
   1304 
   1305 	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
   1306 
   1307 	DPRINTF("Before forking process PID=%d\n", getpid());
   1308 	SYSCALL_REQUIRE((child = fork()) != -1);
   1309 	if (child == 0) {
   1310 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1311 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1312 
   1313 		if (masked) {
   1314 			sigemptyset(&intmask);
   1315 			sigaddset(&intmask, SIGTRAP);
   1316 			sigprocmask(SIG_BLOCK, &intmask, NULL);
   1317 		}
   1318 
   1319 		if (ignored) {
   1320 			memset(&sa, 0, sizeof(sa));
   1321 			sa.sa_handler = SIG_IGN;
   1322 			sigemptyset(&sa.sa_mask);
   1323 			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
   1324 		}
   1325 
   1326 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1327 		FORKEE_ASSERT(raise(sigval) == 0);
   1328 
   1329 		if (strcmp(fn, "spawn") == 0) {
   1330 			FORKEE_ASSERT_EQ(posix_spawn(&child2,
   1331 			    arg[0], NULL, NULL, arg, NULL), 0);
   1332 		} else  {
   1333 			if (strcmp(fn, "fork") == 0) {
   1334 				FORKEE_ASSERT((child2 = fork()) != -1);
   1335 			} else {
   1336 				FORKEE_ASSERT((child2 = vfork()) != -1);
   1337 			}
   1338 			if (child2 == 0)
   1339 				_exit(exitval2);
   1340 		}
   1341 
   1342 		FORKEE_REQUIRE_SUCCESS
   1343 		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
   1344 
   1345 		forkee_status_exited(status, exitval2);
   1346 
   1347 		DPRINTF("Before exiting of the child process\n");
   1348 		_exit(exitval);
   1349 	}
   1350 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1351 
   1352 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1353 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1354 
   1355 	validate_status_stopped(status, sigval);
   1356 
   1357 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
   1358 	SYSCALL_REQUIRE(
   1359 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
   1360 
   1361 	DPRINTF("Before checking siginfo_t\n");
   1362 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
   1363 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
   1364 
   1365 	name[0] = CTL_KERN,
   1366 	name[1] = KERN_PROC2,
   1367 	name[2] = KERN_PROC_PID;
   1368 	name[3] = child;
   1369 	name[4] = sizeof(kp);
   1370 	name[5] = 1;
   1371 
   1372 	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1373 
   1374 	kp_sigmask = kp.p_sigmask;
   1375 	kp_sigignore = kp.p_sigignore;
   1376 
   1377 	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
   1378 	    strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "",
   1379 	    strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "",
   1380 	    strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "",
   1381 	    strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child);
   1382 	event.pe_set_event = 0;
   1383 	if (strcmp(fn, "spawn") == 0)
   1384 		event.pe_set_event |= PTRACE_POSIX_SPAWN;
   1385 	if (strcmp(fn, "fork") == 0)
   1386 		event.pe_set_event |= PTRACE_FORK;
   1387 	if (strcmp(fn, "vfork") == 0)
   1388 		event.pe_set_event |= PTRACE_VFORK;
   1389 	if (strcmp(fn, "vforkdone") == 0)
   1390 		event.pe_set_event |= PTRACE_VFORK_DONE;
   1391 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
   1392 
   1393 	/*
   1394 	 * Ignore interception of the SIGCHLD signals.
   1395 	 *
   1396 	 * SIGCHLD once blocked is discarded by the kernel as it has the
   1397 	 * SA_IGNORE property. During the fork(2) operation all signals can be
   1398 	 * shortly blocked and missed (unless there is a registered signal
   1399 	 * handler in the traced child). This leads to a race in this test if
   1400 	 * there would be an intention to catch SIGCHLD.
   1401 	 */
   1402 	sigemptyset(&set);
   1403 	sigaddset(&set, SIGCHLD);
   1404 	SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, child, &set, sizeof(set)) != -1);
   1405 
   1406 	DPRINTF("Before resuming the child process where it left off and "
   1407 	    "without signal to be sent\n");
   1408 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1409 
   1410 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
   1411 	    strcmp(fn, "vfork") == 0) {
   1412 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
   1413 		    child);
   1414 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
   1415 		    child);
   1416 
   1417 		validate_status_stopped(status, SIGTRAP);
   1418 
   1419 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1420 
   1421 		if (masked) {
   1422 			DPRINTF("kp_sigmask="
   1423 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1424 			    PRIx32 "\n",
   1425 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
   1426 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
   1427 
   1428 			DPRINTF("kp.p_sigmask="
   1429 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1430 			    PRIx32 "\n",
   1431 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
   1432 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
   1433 
   1434 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
   1435 			    SIGTRAP));
   1436 		}
   1437 
   1438 		if (ignored) {
   1439 			DPRINTF("kp_sigignore="
   1440 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1441 			    PRIx32 "\n",
   1442 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
   1443 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
   1444 
   1445 			DPRINTF("kp.p_sigignore="
   1446 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1447 			    PRIx32 "\n",
   1448 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
   1449 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
   1450 
   1451 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
   1452 			    SIGTRAP));
   1453 		}
   1454 
   1455 		SYSCALL_REQUIRE(
   1456 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
   1457 		if (strcmp(fn, "spawn") == 0) {
   1458 			ATF_REQUIRE_EQ(
   1459 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
   1460 			       PTRACE_POSIX_SPAWN);
   1461 		}
   1462 		if (strcmp(fn, "fork") == 0) {
   1463 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
   1464 			       PTRACE_FORK);
   1465 		}
   1466 		if (strcmp(fn, "vfork") == 0) {
   1467 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
   1468 			       PTRACE_VFORK);
   1469 		}
   1470 
   1471 		child2 = state.pe_other_pid;
   1472 		DPRINTF("Reported ptrace event with forkee %d\n", child2);
   1473 
   1474 		DPRINTF("Before calling %s() for the forkee %d of the child "
   1475 		    "%d\n", TWAIT_FNAME, child2, child);
   1476 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
   1477 		    child2);
   1478 
   1479 		validate_status_stopped(status, SIGTRAP);
   1480 
   1481 		name[3] = child2;
   1482 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1483 
   1484 		if (masked) {
   1485 			DPRINTF("kp_sigmask="
   1486 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1487 			    PRIx32 "\n",
   1488 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
   1489 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
   1490 
   1491 			DPRINTF("kp.p_sigmask="
   1492 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1493 			    PRIx32 "\n",
   1494 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
   1495 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
   1496 
   1497 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
   1498 			    SIGTRAP));
   1499 		}
   1500 
   1501 		if (ignored) {
   1502 			DPRINTF("kp_sigignore="
   1503 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1504 			    PRIx32 "\n",
   1505 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
   1506 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
   1507 
   1508 			DPRINTF("kp.p_sigignore="
   1509 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1510 			    PRIx32 "\n",
   1511 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
   1512 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
   1513 
   1514 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
   1515 			    SIGTRAP));
   1516 		}
   1517 
   1518 		SYSCALL_REQUIRE(
   1519 		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
   1520 		if (strcmp(fn, "spawn") == 0) {
   1521 			ATF_REQUIRE_EQ(
   1522 			    state.pe_report_event & PTRACE_POSIX_SPAWN,
   1523 			       PTRACE_POSIX_SPAWN);
   1524 		}
   1525 		if (strcmp(fn, "fork") == 0) {
   1526 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
   1527 			       PTRACE_FORK);
   1528 		}
   1529 		if (strcmp(fn, "vfork") == 0) {
   1530 			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
   1531 			       PTRACE_VFORK);
   1532 		}
   1533 
   1534 		ATF_REQUIRE_EQ(state.pe_other_pid, child);
   1535 
   1536 		DPRINTF("Before resuming the forkee process where it left off "
   1537 		    "and without signal to be sent\n");
   1538 		SYSCALL_REQUIRE(
   1539 		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
   1540 
   1541 		DPRINTF("Before resuming the child process where it left off "
   1542 		    "and without signal to be sent\n");
   1543 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1544 	}
   1545 
   1546 	if (strcmp(fn, "vforkdone") == 0) {
   1547 		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
   1548 		    child);
   1549 		TWAIT_REQUIRE_SUCCESS(
   1550 		    wpid = TWAIT_GENERIC(child, &status, 0), child);
   1551 
   1552 		validate_status_stopped(status, SIGTRAP);
   1553 
   1554 		name[3] = child;
   1555 		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1556 
   1557 		/*
   1558 		 * SIGCHLD is now pending in the signal queue and
   1559 		 * the kernel presents it to userland as a masked signal.
   1560 		 */
   1561 		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
   1562 
   1563 		if (masked) {
   1564 			DPRINTF("kp_sigmask="
   1565 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1566 			    PRIx32 "\n",
   1567 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
   1568 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
   1569 
   1570 			DPRINTF("kp.p_sigmask="
   1571 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1572 			    PRIx32 "\n",
   1573 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
   1574 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
   1575 
   1576 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask,
   1577 			    SIGTRAP));
   1578 		}
   1579 
   1580 		if (ignored) {
   1581 			DPRINTF("kp_sigignore="
   1582 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1583 			    PRIx32 "\n",
   1584 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
   1585 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
   1586 
   1587 			DPRINTF("kp.p_sigignore="
   1588 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1589 			    PRIx32 "\n",
   1590 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
   1591 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
   1592 
   1593 			ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore,
   1594 			    SIGTRAP));
   1595 		}
   1596 
   1597 		SYSCALL_REQUIRE(
   1598 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
   1599 		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
   1600 
   1601 		child2 = state.pe_other_pid;
   1602 		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
   1603 		    child2);
   1604 
   1605 		DPRINTF("Before resuming the child process where it left off "
   1606 		    "and without signal to be sent\n");
   1607 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1608 	}
   1609 
   1610 	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
   1611 	    strcmp(fn, "vfork") == 0) {
   1612 		DPRINTF("Before calling %s() for the forkee - expected exited"
   1613 		    "\n", TWAIT_FNAME);
   1614 		TWAIT_REQUIRE_SUCCESS(
   1615 		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
   1616 
   1617 		validate_status_exited(status, exitval2);
   1618 
   1619 		DPRINTF("Before calling %s() for the forkee - expected no "
   1620 		    "process\n", TWAIT_FNAME);
   1621 		TWAIT_REQUIRE_FAILURE(ECHILD,
   1622 		    wpid = TWAIT_GENERIC(child2, &status, 0));
   1623 	}
   1624 
   1625 	DPRINTF("Before calling %s() for the child - expected exited\n",
   1626 	    TWAIT_FNAME);
   1627 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1628 
   1629 	validate_status_exited(status, exitval);
   1630 
   1631 	DPRINTF("Before calling %s() for the child - expected no process\n",
   1632 	    TWAIT_FNAME);
   1633 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1634 }
   1635 
   1636 #define FORK2_TEST(name,fn,masked,ignored)				\
   1637 ATF_TC(name);								\
   1638 ATF_TC_HEAD(name, tc)							\
   1639 {									\
   1640 	atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught "	\
   1641 	    "regardless of signal %s%s", 				\
   1642 	    masked ? "masked" : "", ignored ? "ignored" : "");		\
   1643 }									\
   1644 									\
   1645 ATF_TC_BODY(name, tc)							\
   1646 {									\
   1647 									\
   1648 	fork2_body(fn, masked, ignored);				\
   1649 }
   1650 
   1651 FORK2_TEST(posix_spawn_signalmasked, "spawn", true, false)
   1652 FORK2_TEST(posix_spawn_signalignored, "spawn", false, true)
   1653 FORK2_TEST(fork_signalmasked, "fork", true, false)
   1654 FORK2_TEST(fork_signalignored, "fork", false, true)
   1655 FORK2_TEST(vfork_signalmasked, "vfork", true, false)
   1656 FORK2_TEST(vfork_signalignored, "vfork", false, true)
   1657 FORK2_TEST(vforkdone_signalmasked, "vforkdone", true, false)
   1658 FORK2_TEST(vforkdone_signalignored, "vforkdone", false, true)
   1659 #endif
   1660 
   1661 #define ATF_TP_ADD_TCS_PTRACE_WAIT_FORK() \
   1662 	ATF_TP_ADD_TC(tp, fork1); \
   1663 	ATF_TP_ADD_TC_HAVE_PID(tp, fork2); \
   1664 	ATF_TP_ADD_TC_HAVE_PID(tp, fork3); \
   1665 	ATF_TP_ADD_TC_HAVE_PID(tp, fork4); \
   1666 	ATF_TP_ADD_TC(tp, fork5); \
   1667 	ATF_TP_ADD_TC_HAVE_PID(tp, fork6); \
   1668 	ATF_TP_ADD_TC_HAVE_PID(tp, fork7); \
   1669 	ATF_TP_ADD_TC_HAVE_PID(tp, fork8); \
   1670 	ATF_TP_ADD_TC(tp, fork9); \
   1671 	ATF_TP_ADD_TC_HAVE_PID(tp, fork10); \
   1672 	ATF_TP_ADD_TC_HAVE_PID(tp, fork11); \
   1673 	ATF_TP_ADD_TC_HAVE_PID(tp, fork12); \
   1674 	ATF_TP_ADD_TC(tp, fork13); \
   1675 	ATF_TP_ADD_TC_HAVE_PID(tp, fork14); \
   1676 	ATF_TP_ADD_TC_HAVE_PID(tp, fork15); \
   1677 	ATF_TP_ADD_TC_HAVE_PID(tp, fork16); \
   1678 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_setpgid); \
   1679 	ATF_TP_ADD_TC(tp, vfork1); \
   1680 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); \
   1681 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); \
   1682 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); \
   1683 	ATF_TP_ADD_TC(tp, vfork5); \
   1684 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); \
   1685 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); \
   1686 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); \
   1687 	ATF_TP_ADD_TC(tp, vfork9); \
   1688 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork10); \
   1689 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork11); \
   1690 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork12); \
   1691 	ATF_TP_ADD_TC(tp, vfork13); \
   1692 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork14); \
   1693 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork15); \
   1694 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork16); \
   1695 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_setpgid); \
   1696 	ATF_TP_ADD_TC(tp, posix_spawn1); \
   1697 	ATF_TP_ADD_TC(tp, posix_spawn2); \
   1698 	ATF_TP_ADD_TC(tp, posix_spawn3); \
   1699 	ATF_TP_ADD_TC(tp, posix_spawn4); \
   1700 	ATF_TP_ADD_TC(tp, posix_spawn5); \
   1701 	ATF_TP_ADD_TC(tp, posix_spawn6); \
   1702 	ATF_TP_ADD_TC(tp, posix_spawn7); \
   1703 	ATF_TP_ADD_TC(tp, posix_spawn8); \
   1704 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9); \
   1705 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10); \
   1706 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11); \
   1707 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12); \
   1708 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13); \
   1709 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14); \
   1710 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); \
   1711 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); \
   1712 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_setpgid); \
   1713 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1); \
   1714 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2); \
   1715 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3); \
   1716 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4); \
   1717 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5); \
   1718 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6); \
   1719 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7); \
   1720 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8); \
   1721 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9); \
   1722 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10); \
   1723 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11); \
   1724 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12); \
   1725 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13); \
   1726 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14); \
   1727 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15); \
   1728 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16); \
   1729 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_setpgid); \
   1730 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1); \
   1731 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2); \
   1732 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3); \
   1733 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4); \
   1734 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5); \
   1735 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6); \
   1736 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7); \
   1737 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8); \
   1738 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9); \
   1739 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10); \
   1740 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11); \
   1741 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12); \
   1742 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13); \
   1743 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14); \
   1744 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15); \
   1745 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16); \
   1746 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_setpgid); \
   1747 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1); \
   1748 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2); \
   1749 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3); \
   1750 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4); \
   1751 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5); \
   1752 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6); \
   1753 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7); \
   1754 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8); \
   1755 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9); \
   1756 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10); \
   1757 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11); \
   1758 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12); \
   1759 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13); \
   1760 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14); \
   1761 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15); \
   1762 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16); \
   1763 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_setpgid); \
   1764 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); \
   1765 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); \
   1766 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); \
   1767 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); \
   1768 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); \
   1769 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); \
   1770 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); \
   1771 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone); \
   1772 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner); \
   1773 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker); \
   1774 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker); \
   1775 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone); \
   1776 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner); \
   1777 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker); \
   1778 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker); \
   1779 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone); \
   1780 	ATF_TP_ADD_TC(tp, traceme_vfork_fork); \
   1781 	ATF_TP_ADD_TC(tp, traceme_vfork_vfork); \
   1782 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalmasked); \
   1783 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_signalignored); \
   1784 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalmasked); \
   1785 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_signalignored); \
   1786 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalmasked); \
   1787 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_signalignored); \
   1788 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalmasked); \
   1789 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_signalignored);
   1790