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