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