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