Home | History | Annotate | Line # | Download | only in sys
t_ptrace_signal_wait.h revision 1.5
      1 /*	$NetBSD: t_ptrace_signal_wait.h,v 1.5 2021/03/19 00:44:09 simonb Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2016, 2017, 2018, 2019, 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 traceme_raise(int sigval)
     32 {
     33 	const int exitval = 5;
     34 	pid_t child, wpid;
     35 #if defined(TWAIT_HAVE_STATUS)
     36 	int status;
     37 #endif
     38 
     39 	ptrace_state_t state, zero_state;
     40 	const int slen = sizeof(state);
     41 	struct ptrace_siginfo info;
     42 	memset(&zero_state, 0, sizeof(zero_state));
     43 	memset(&info, 0, sizeof(info));
     44 
     45 	DPRINTF("Before forking process PID=%d\n", getpid());
     46 	SYSCALL_REQUIRE((child = fork()) != -1);
     47 	if (child == 0) {
     48 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
     49 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
     50 
     51 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
     52 		FORKEE_ASSERT(raise(sigval) == 0);
     53 
     54 		switch (sigval) {
     55 		case SIGKILL:
     56 			/* NOTREACHED */
     57 			FORKEE_ASSERTX(0 && "This shall not be reached");
     58 			__unreachable();
     59 		default:
     60 			DPRINTF("Before exiting of the child process\n");
     61 			_exit(exitval);
     62 		}
     63 	}
     64 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
     65 
     66 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
     67 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
     68 
     69 	switch (sigval) {
     70 	case SIGKILL:
     71 		validate_status_signaled(status, sigval, 0);
     72 		SYSCALL_REQUIRE(
     73 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) == -1);
     74 
     75 		break;
     76 	default:
     77 		validate_status_stopped(status, sigval);
     78 
     79 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
     80 			"child\n");
     81 		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
     82 			sizeof(info)) != -1);
     83 
     84 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
     85 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
     86 			"si_errno=%#x\n",
     87 			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
     88 			info.psi_siginfo.si_errno);
     89 
     90 		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
     91 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
     92 
     93 		DPRINTF("Assert that PT_GET_PROCESS_STATE returns non-error\n");
     94 		SYSCALL_REQUIRE(
     95 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
     96 		ATF_REQUIRE(memcmp(&state, &zero_state, slen) == 0);
     97 
     98 		DPRINTF("Before resuming the child process where it left off "
     99 		    "and without signal to be sent\n");
    100 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    101 
    102 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    103 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    104 		    child);
    105 		break;
    106 	}
    107 
    108 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    109 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    110 }
    111 
    112 #define TRACEME_RAISE(test, sig)					\
    113 ATF_TC(test);								\
    114 ATF_TC_HEAD(test, tc)							\
    115 {									\
    116 	atf_tc_set_md_var(tc, "descr",					\
    117 	    "Verify " #sig " followed by _exit(2) in a child");		\
    118 }									\
    119 									\
    120 ATF_TC_BODY(test, tc)							\
    121 {									\
    122 									\
    123 	traceme_raise(sig);						\
    124 }
    125 
    126 TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
    127 TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
    128 TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
    129 TRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
    130 TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
    131 TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */
    132 TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */
    133 TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */
    134 TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */
    135 TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */
    136 
    137 /// ----------------------------------------------------------------------------
    138 
    139 static void
    140 traceme_raisesignal_ignored(int sigignored)
    141 {
    142 	const int exitval = 5;
    143 	const int sigval = SIGSTOP;
    144 	pid_t child, wpid;
    145 	struct sigaction sa;
    146 #if defined(TWAIT_HAVE_STATUS)
    147 	int status;
    148 #endif
    149 	struct ptrace_siginfo info;
    150 
    151 	memset(&info, 0, sizeof(info));
    152 
    153 	DPRINTF("Before forking process PID=%d\n", getpid());
    154 	SYSCALL_REQUIRE((child = fork()) != -1);
    155 	if (child == 0) {
    156 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    157 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    158 
    159 		memset(&sa, 0, sizeof(sa));
    160 		sa.sa_handler = SIG_IGN;
    161 		sigemptyset(&sa.sa_mask);
    162 		FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1);
    163 
    164 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    165 		FORKEE_ASSERT(raise(sigval) == 0);
    166 
    167 		DPRINTF("Before raising %s from child\n",
    168 		    strsignal(sigignored));
    169 		FORKEE_ASSERT(raise(sigignored) == 0);
    170 
    171 		DPRINTF("Before exiting of the child process\n");
    172 		_exit(exitval);
    173 	}
    174 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    175 
    176 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    177 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    178 
    179 	validate_status_stopped(status, sigval);
    180 
    181 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    182 	SYSCALL_REQUIRE(
    183 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    184 
    185 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    186 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    187 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    188 	    info.psi_siginfo.si_errno);
    189 
    190 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    191 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    192 
    193 	DPRINTF("Before resuming the child process where it left off and "
    194 	    "without signal to be sent\n");
    195 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    196 
    197 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    198 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    199 
    200 	validate_status_stopped(status, sigignored);
    201 
    202 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    203 	SYSCALL_REQUIRE(
    204 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    205 
    206 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    207 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    208 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    209 	    info.psi_siginfo.si_errno);
    210 
    211 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored);
    212 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    213 
    214 	DPRINTF("Before resuming the child process where it left off and "
    215 	    "without signal to be sent\n");
    216 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    217 
    218 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    219 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    220 
    221 	validate_status_exited(status, exitval);
    222 
    223 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    224 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    225 }
    226 
    227 #define TRACEME_RAISESIGNAL_IGNORED(test, sig)				\
    228 ATF_TC(test);								\
    229 ATF_TC_HEAD(test, tc)							\
    230 {									\
    231 	atf_tc_set_md_var(tc, "descr",					\
    232 	    "Verify that ignoring (with SIG_IGN) " #sig " in tracee "	\
    233 	    "does not stop tracer from catching this raised signal");	\
    234 }									\
    235 									\
    236 ATF_TC_BODY(test, tc)							\
    237 {									\
    238 									\
    239 	traceme_raisesignal_ignored(sig);				\
    240 }
    241 
    242 // A signal handler for SIGKILL and SIGSTOP cannot be ignored.
    243 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */
    244 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP)  /* hangup */
    245 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */
    246 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */
    247 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */
    248 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */
    249 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */
    250 TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */
    251 
    252 /// ----------------------------------------------------------------------------
    253 
    254 static void
    255 traceme_raisesignal_masked(int sigmasked)
    256 {
    257 	const int exitval = 5;
    258 	const int sigval = SIGSTOP;
    259 	pid_t child, wpid;
    260 #if defined(TWAIT_HAVE_STATUS)
    261 	int status;
    262 #endif
    263 	sigset_t intmask;
    264 	struct ptrace_siginfo info;
    265 
    266 	memset(&info, 0, sizeof(info));
    267 
    268 	DPRINTF("Before forking process PID=%d\n", getpid());
    269 	SYSCALL_REQUIRE((child = fork()) != -1);
    270 	if (child == 0) {
    271 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    272 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    273 
    274 		sigemptyset(&intmask);
    275 		sigaddset(&intmask, sigmasked);
    276 		sigprocmask(SIG_BLOCK, &intmask, NULL);
    277 
    278 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    279 		FORKEE_ASSERT(raise(sigval) == 0);
    280 
    281 		DPRINTF("Before raising %s breakpoint from child\n",
    282 		    strsignal(sigmasked));
    283 		FORKEE_ASSERT(raise(sigmasked) == 0);
    284 
    285 		DPRINTF("Before exiting of the child process\n");
    286 		_exit(exitval);
    287 	}
    288 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    289 
    290 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    291 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    292 
    293 	validate_status_stopped(status, sigval);
    294 
    295 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    296 	SYSCALL_REQUIRE(
    297 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    298 
    299 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    300 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    301 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    302 	    info.psi_siginfo.si_errno);
    303 
    304 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    305 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    306 
    307 	DPRINTF("Before resuming the child process where it left off and "
    308 	    "without signal to be sent\n");
    309 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    310 
    311 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    312 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    313 
    314 	validate_status_exited(status, exitval);
    315 
    316 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    317 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    318 }
    319 
    320 #define TRACEME_RAISESIGNAL_MASKED(test, sig)				\
    321 ATF_TC(test);								\
    322 ATF_TC_HEAD(test, tc)							\
    323 {									\
    324 	atf_tc_set_md_var(tc, "descr",					\
    325 	    "Verify that masking (with SIG_BLOCK) " #sig " in tracee "	\
    326 	    "stops tracer from catching this raised signal");		\
    327 }									\
    328 									\
    329 ATF_TC_BODY(test, tc)							\
    330 {									\
    331 									\
    332 	traceme_raisesignal_masked(sig);				\
    333 }
    334 
    335 // A signal handler for SIGKILL and SIGSTOP cannot be masked.
    336 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */
    337 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP)  /* hangup */
    338 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */
    339 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */
    340 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */
    341 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */
    342 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */
    343 TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */
    344 
    345 /// ----------------------------------------------------------------------------
    346 
    347 static void
    348 traceme_crash(int sig)
    349 {
    350 	pid_t child, wpid;
    351 #if defined(TWAIT_HAVE_STATUS)
    352 	int status;
    353 #endif
    354 	struct ptrace_siginfo info;
    355 
    356 #ifndef PTRACE_ILLEGAL_ASM
    357 	if (sig == SIGILL)
    358 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
    359 #endif
    360 
    361 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
    362 		atf_tc_skip("FP exceptions are not supported");
    363 
    364 	memset(&info, 0, sizeof(info));
    365 
    366 	DPRINTF("Before forking process PID=%d\n", getpid());
    367 	SYSCALL_REQUIRE((child = fork()) != -1);
    368 	if (child == 0) {
    369 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    370 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    371 
    372 		DPRINTF("Before executing a trap\n");
    373 		switch (sig) {
    374 		case SIGTRAP:
    375 			trigger_trap();
    376 			break;
    377 		case SIGSEGV:
    378 			trigger_segv();
    379 			break;
    380 		case SIGILL:
    381 			trigger_ill();
    382 			break;
    383 		case SIGFPE:
    384 			trigger_fpe();
    385 			break;
    386 		case SIGBUS:
    387 			trigger_bus();
    388 			break;
    389 		default:
    390 			/* NOTREACHED */
    391 			FORKEE_ASSERTX(0 && "This shall not be reached");
    392 		}
    393 
    394 		/* NOTREACHED */
    395 		FORKEE_ASSERTX(0 && "This shall not be reached");
    396 	}
    397 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    398 
    399 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    400 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    401 
    402 	validate_status_stopped(status, sig);
    403 
    404 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    405 	SYSCALL_REQUIRE(
    406 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    407 
    408 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    409 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    410 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    411 	    info.psi_siginfo.si_errno);
    412 
    413 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
    414 	switch (sig) {
    415 	case SIGTRAP:
    416 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
    417 		break;
    418 	case SIGSEGV:
    419 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
    420 		break;
    421 	case SIGILL:
    422 		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
    423 		            info.psi_siginfo.si_code <= ILL_BADSTK);
    424 		break;
    425 	case SIGFPE:
    426 // XXXQEMU	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
    427 		break;
    428 	case SIGBUS:
    429 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
    430 		break;
    431 	}
    432 
    433 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
    434 
    435 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    436 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    437 
    438 	validate_status_signaled(status, SIGKILL, 0);
    439 
    440 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    441 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    442 }
    443 
    444 #define TRACEME_CRASH(test, sig)					\
    445 ATF_TC(test);								\
    446 ATF_TC_HEAD(test, tc)							\
    447 {									\
    448 	atf_tc_set_md_var(tc, "descr",					\
    449 	    "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \
    450 }									\
    451 									\
    452 ATF_TC_BODY(test, tc)							\
    453 {									\
    454 									\
    455 	traceme_crash(sig);						\
    456 }
    457 
    458 TRACEME_CRASH(traceme_crash_trap, SIGTRAP)
    459 TRACEME_CRASH(traceme_crash_segv, SIGSEGV)
    460 TRACEME_CRASH(traceme_crash_ill, SIGILL)
    461 TRACEME_CRASH(traceme_crash_fpe, SIGFPE)
    462 TRACEME_CRASH(traceme_crash_bus, SIGBUS)
    463 
    464 /// ----------------------------------------------------------------------------
    465 
    466 static void
    467 traceme_signalmasked_crash(int sig)
    468 {
    469 	const int sigval = SIGSTOP;
    470 	pid_t child, wpid;
    471 #if defined(TWAIT_HAVE_STATUS)
    472 	int status;
    473 #endif
    474 	struct ptrace_siginfo info;
    475 	sigset_t intmask;
    476 	struct kinfo_proc2 kp;
    477 	size_t len = sizeof(kp);
    478 
    479 	int name[6];
    480 	const size_t namelen = __arraycount(name);
    481 	ki_sigset_t kp_sigmask;
    482 
    483 #ifndef PTRACE_ILLEGAL_ASM
    484 	if (sig == SIGILL)
    485 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
    486 #endif
    487 
    488 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
    489 		atf_tc_skip("FP exceptions are not supported");
    490 
    491 	memset(&info, 0, sizeof(info));
    492 
    493 	DPRINTF("Before forking process PID=%d\n", getpid());
    494 	SYSCALL_REQUIRE((child = fork()) != -1);
    495 	if (child == 0) {
    496 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    497 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    498 
    499 		sigemptyset(&intmask);
    500 		sigaddset(&intmask, sig);
    501 		sigprocmask(SIG_BLOCK, &intmask, NULL);
    502 
    503 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    504 		FORKEE_ASSERT(raise(sigval) == 0);
    505 
    506 		DPRINTF("Before executing a trap\n");
    507 		switch (sig) {
    508 		case SIGTRAP:
    509 			trigger_trap();
    510 			break;
    511 		case SIGSEGV:
    512 			trigger_segv();
    513 			break;
    514 		case SIGILL:
    515 			trigger_ill();
    516 			break;
    517 		case SIGFPE:
    518 			trigger_fpe();
    519 			break;
    520 		case SIGBUS:
    521 			trigger_bus();
    522 			break;
    523 		default:
    524 			/* NOTREACHED */
    525 			FORKEE_ASSERTX(0 && "This shall not be reached");
    526 		}
    527 
    528 		/* NOTREACHED */
    529 		FORKEE_ASSERTX(0 && "This shall not be reached");
    530 	}
    531 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    532 
    533 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    534 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    535 
    536 	validate_status_stopped(status, sigval);
    537 
    538 	name[0] = CTL_KERN,
    539 	name[1] = KERN_PROC2,
    540 	name[2] = KERN_PROC_PID;
    541 	name[3] = child;
    542 	name[4] = sizeof(kp);
    543 	name[5] = 1;
    544 
    545 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
    546 
    547 	kp_sigmask = kp.p_sigmask;
    548 
    549 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    550 	SYSCALL_REQUIRE(
    551 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    552 
    553 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    554 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    555 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    556 	    info.psi_siginfo.si_errno);
    557 
    558 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    559 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    560 
    561 	DPRINTF("Before resuming the child process where it left off and "
    562 	    "without signal to be sent\n");
    563 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    564 
    565 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    566 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    567 
    568 	validate_status_stopped(status, sig);
    569 
    570 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    571 	SYSCALL_REQUIRE(
    572 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    573 
    574 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    575 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    576 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    577 	    info.psi_siginfo.si_errno);
    578 
    579 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
    580 
    581 	DPRINTF("kp_sigmask="
    582 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
    583 	    kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2],
    584 	    kp_sigmask.__bits[3]);
    585 
    586 	DPRINTF("kp.p_sigmask="
    587 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
    588 	    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
    589 	    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
    590 
    591 	ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask)));
    592 
    593 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
    594 	switch (sig) {
    595 	case SIGTRAP:
    596 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
    597 		break;
    598 	case SIGSEGV:
    599 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
    600 		break;
    601 	case SIGILL:
    602 		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
    603 		            info.psi_siginfo.si_code <= ILL_BADSTK);
    604 		break;
    605 	case SIGFPE:
    606 // XXXQEMU	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
    607 		break;
    608 	case SIGBUS:
    609 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
    610 		break;
    611 	}
    612 
    613 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
    614 
    615 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    616 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    617 
    618 	validate_status_signaled(status, SIGKILL, 0);
    619 
    620 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    621 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    622 }
    623 
    624 #define TRACEME_SIGNALMASKED_CRASH(test, sig)				\
    625 ATF_TC(test);								\
    626 ATF_TC_HEAD(test, tc)							\
    627 {									\
    628 	atf_tc_set_md_var(tc, "descr",					\
    629 	    "Verify masked crash signal " #sig " in a child after "	\
    630 	    "PT_TRACE_ME is delivered to its tracer");			\
    631 }									\
    632 									\
    633 ATF_TC_BODY(test, tc)							\
    634 {									\
    635 									\
    636 	traceme_signalmasked_crash(sig);				\
    637 }
    638 
    639 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP)
    640 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV)
    641 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL)
    642 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE)
    643 TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS)
    644 
    645 /// ----------------------------------------------------------------------------
    646 
    647 static void
    648 traceme_signalignored_crash(int sig)
    649 {
    650 	const int sigval = SIGSTOP;
    651 	pid_t child, wpid;
    652 #if defined(TWAIT_HAVE_STATUS)
    653 	int status;
    654 #endif
    655 	struct sigaction sa;
    656 	struct ptrace_siginfo info;
    657 	struct kinfo_proc2 kp;
    658 	size_t len = sizeof(kp);
    659 
    660 	int name[6];
    661 	const size_t namelen = __arraycount(name);
    662 	ki_sigset_t kp_sigignore;
    663 
    664 #ifndef PTRACE_ILLEGAL_ASM
    665 	if (sig == SIGILL)
    666 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
    667 #endif
    668 
    669 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
    670 		atf_tc_skip("FP exceptions are not supported");
    671 
    672 	memset(&info, 0, sizeof(info));
    673 
    674 	DPRINTF("Before forking process PID=%d\n", getpid());
    675 	SYSCALL_REQUIRE((child = fork()) != -1);
    676 	if (child == 0) {
    677 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    678 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    679 
    680 		memset(&sa, 0, sizeof(sa));
    681 		sa.sa_handler = SIG_IGN;
    682 		sigemptyset(&sa.sa_mask);
    683 
    684 		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
    685 
    686 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    687 		FORKEE_ASSERT(raise(sigval) == 0);
    688 
    689 		DPRINTF("Before executing a trap\n");
    690 		switch (sig) {
    691 		case SIGTRAP:
    692 			trigger_trap();
    693 			break;
    694 		case SIGSEGV:
    695 			trigger_segv();
    696 			break;
    697 		case SIGILL:
    698 			trigger_ill();
    699 			break;
    700 		case SIGFPE:
    701 			trigger_fpe();
    702 			break;
    703 		case SIGBUS:
    704 			trigger_bus();
    705 			break;
    706 		default:
    707 			/* NOTREACHED */
    708 			FORKEE_ASSERTX(0 && "This shall not be reached");
    709 		}
    710 
    711 		/* NOTREACHED */
    712 		FORKEE_ASSERTX(0 && "This shall not be reached");
    713 	}
    714 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    715 
    716 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    717 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    718 
    719 	validate_status_stopped(status, sigval);
    720 
    721 	name[0] = CTL_KERN,
    722 	name[1] = KERN_PROC2,
    723 	name[2] = KERN_PROC_PID;
    724 	name[3] = child;
    725 	name[4] = sizeof(kp);
    726 	name[5] = 1;
    727 
    728 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
    729 
    730 	kp_sigignore = kp.p_sigignore;
    731 
    732 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    733 	SYSCALL_REQUIRE(
    734 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    735 
    736 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    737 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    738 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    739 	    info.psi_siginfo.si_errno);
    740 
    741 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    742 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    743 
    744 	DPRINTF("Before resuming the child process where it left off and "
    745 	    "without signal to be sent\n");
    746 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    747 
    748 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    749 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    750 
    751 	validate_status_stopped(status, sig);
    752 
    753 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    754 	SYSCALL_REQUIRE(
    755 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    756 
    757 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    758 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    759 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    760 	    info.psi_siginfo.si_errno);
    761 
    762 	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
    763 
    764 	DPRINTF("kp_sigignore="
    765 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
    766 	    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
    767 	    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
    768 
    769 	DPRINTF("kp.p_sigignore="
    770 	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
    771 	    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
    772 	    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
    773 
    774 	ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore)));
    775 
    776 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
    777 	switch (sig) {
    778 	case SIGTRAP:
    779 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
    780 		break;
    781 	case SIGSEGV:
    782 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
    783 		break;
    784 	case SIGILL:
    785 		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
    786 		            info.psi_siginfo.si_code <= ILL_BADSTK);
    787 		break;
    788 	case SIGFPE:
    789 // XXXQEMU	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
    790 		break;
    791 	case SIGBUS:
    792 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
    793 		break;
    794 	}
    795 
    796 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
    797 
    798 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    799 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    800 
    801 	validate_status_signaled(status, SIGKILL, 0);
    802 
    803 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    804 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    805 }
    806 
    807 #define TRACEME_SIGNALIGNORED_CRASH(test, sig)				\
    808 ATF_TC(test);								\
    809 ATF_TC_HEAD(test, tc)							\
    810 {									\
    811 	atf_tc_set_md_var(tc, "descr",					\
    812 	    "Verify ignored crash signal " #sig " in a child after "	\
    813 	    "PT_TRACE_ME is delivered to its tracer"); 			\
    814 }									\
    815 									\
    816 ATF_TC_BODY(test, tc)							\
    817 {									\
    818 									\
    819 	traceme_signalignored_crash(sig);				\
    820 }
    821 
    822 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP)
    823 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV)
    824 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL)
    825 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE)
    826 TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS)
    827 
    828 /// ----------------------------------------------------------------------------
    829 
    830 static void
    831 traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught)
    832 {
    833 	const int exitval = 5;
    834 	const int sigval = SIGSTOP;
    835 	pid_t child, wpid;
    836 	struct sigaction sa;
    837 #if defined(TWAIT_HAVE_STATUS)
    838 	int status;
    839 #endif
    840 	struct ptrace_siginfo info;
    841 
    842 	memset(&info, 0, sizeof(info));
    843 
    844 	DPRINTF("Before forking process PID=%d\n", getpid());
    845 	SYSCALL_REQUIRE((child = fork()) != -1);
    846 	if (child == 0) {
    847 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    848 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    849 
    850 		sa.sa_handler = sah;
    851 		sa.sa_flags = SA_SIGINFO;
    852 		sigemptyset(&sa.sa_mask);
    853 
    854 		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
    855 
    856 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    857 		FORKEE_ASSERT(raise(sigval) == 0);
    858 
    859 		FORKEE_ASSERT_EQ(*traceme_caught, 1);
    860 
    861 		DPRINTF("Before exiting of the child process\n");
    862 		_exit(exitval);
    863 	}
    864 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    865 
    866 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    867 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    868 
    869 	validate_status_stopped(status, sigval);
    870 
    871 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    872 	SYSCALL_REQUIRE(
    873 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    874 
    875 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    876 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    877 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    878 	    info.psi_siginfo.si_errno);
    879 
    880 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    881 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    882 
    883 	DPRINTF("Before resuming the child process where it left off and with "
    884 	    "signal %s to be sent\n", strsignal(sigsent));
    885 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
    886 
    887 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    888 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    889 
    890 	validate_status_exited(status, exitval);
    891 
    892 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
    893 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    894 }
    895 
    896 #define TRACEME_SENDSIGNAL_HANDLE(test, sig)				\
    897 ATF_TC(test);								\
    898 ATF_TC_HEAD(test, tc)							\
    899 {									\
    900 	atf_tc_set_md_var(tc, "descr",					\
    901 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
    902 	    "handled correctly and caught by a signal handler");	\
    903 }									\
    904 									\
    905 static int test##_caught = 0;						\
    906 									\
    907 static void								\
    908 test##_sighandler(int arg)						\
    909 {									\
    910 	FORKEE_ASSERT_EQ(arg, sig);					\
    911 									\
    912 	++ test##_caught;						\
    913 }									\
    914 									\
    915 ATF_TC_BODY(test, tc)							\
    916 {									\
    917 									\
    918 	traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \
    919 }
    920 
    921 // A signal handler for SIGKILL and SIGSTOP cannot be registered.
    922 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */
    923 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP)  /* hangup */
    924 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */
    925 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */
    926 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */
    927 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */
    928 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */
    929 TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */
    930 
    931 /// ----------------------------------------------------------------------------
    932 
    933 static void
    934 traceme_sendsignal_masked(int sigsent)
    935 {
    936 	const int exitval = 5;
    937 	const int sigval = SIGSTOP;
    938 	pid_t child, wpid;
    939 	sigset_t set;
    940 #if defined(TWAIT_HAVE_STATUS)
    941 	int status;
    942 #endif
    943 	struct ptrace_siginfo info;
    944 
    945 	memset(&info, 0, sizeof(info));
    946 
    947 	DPRINTF("Before forking process PID=%d\n", getpid());
    948 	SYSCALL_REQUIRE((child = fork()) != -1);
    949 	if (child == 0) {
    950 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    951 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    952 
    953 		sigemptyset(&set);
    954 		sigaddset(&set, sigsent);
    955 		FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
    956 
    957 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    958 		FORKEE_ASSERT(raise(sigval) == 0);
    959 
    960 		_exit(exitval);
    961 	}
    962 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    963 
    964 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    965 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    966 
    967 	validate_status_stopped(status, sigval);
    968 
    969 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    970 	SYSCALL_REQUIRE(
    971 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    972 
    973 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    974 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    975 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    976 	    info.psi_siginfo.si_errno);
    977 
    978 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    979 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    980 
    981 	DPRINTF("Before resuming the child process where it left off and with "
    982 	    "signal %s to be sent\n", strsignal(sigsent));
    983 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
    984 
    985 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    986 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    987 
    988 	validate_status_exited(status, exitval);
    989 
    990 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
    991 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    992 }
    993 
    994 #define TRACEME_SENDSIGNAL_MASKED(test, sig)				\
    995 ATF_TC(test);								\
    996 ATF_TC_HEAD(test, tc)							\
    997 {									\
    998 	atf_tc_set_md_var(tc, "descr",					\
    999 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
   1000 	    "handled correctly and the signal is masked by SIG_BLOCK");	\
   1001 }									\
   1002 									\
   1003 ATF_TC_BODY(test, tc)							\
   1004 {									\
   1005 									\
   1006 	traceme_sendsignal_masked(sig);					\
   1007 }
   1008 
   1009 // A signal handler for SIGKILL and SIGSTOP cannot be masked.
   1010 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */
   1011 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP)  /* hangup */
   1012 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */
   1013 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */
   1014 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */
   1015 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */
   1016 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */
   1017 TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */
   1018 
   1019 /// ----------------------------------------------------------------------------
   1020 
   1021 static void
   1022 traceme_sendsignal_ignored(int sigsent)
   1023 {
   1024 	const int exitval = 5;
   1025 	const int sigval = SIGSTOP;
   1026 	pid_t child, wpid;
   1027 	struct sigaction sa;
   1028 #if defined(TWAIT_HAVE_STATUS)
   1029 	int status;
   1030 #endif
   1031 	struct ptrace_siginfo info;
   1032 
   1033 	memset(&info, 0, sizeof(info));
   1034 
   1035 	DPRINTF("Before forking process PID=%d\n", getpid());
   1036 	SYSCALL_REQUIRE((child = fork()) != -1);
   1037 	if (child == 0) {
   1038 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1039 
   1040 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1041 
   1042 		memset(&sa, 0, sizeof(sa));
   1043 		sa.sa_handler = SIG_IGN;
   1044 		sigemptyset(&sa.sa_mask);
   1045 		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
   1046 
   1047 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1048 		FORKEE_ASSERT(raise(sigval) == 0);
   1049 
   1050 		_exit(exitval);
   1051 	}
   1052 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1053 
   1054 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1055 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1056 
   1057 	validate_status_stopped(status, sigval);
   1058 
   1059 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
   1060 	SYSCALL_REQUIRE(
   1061 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
   1062 
   1063 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1064 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
   1065 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
   1066 	    info.psi_siginfo.si_errno);
   1067 
   1068 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
   1069 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
   1070 
   1071 	DPRINTF("Before resuming the child process where it left off and with "
   1072 	    "signal %s to be sent\n", strsignal(sigsent));
   1073 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
   1074 
   1075 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1076 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1077 
   1078 	validate_status_exited(status, exitval);
   1079 
   1080 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
   1081 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1082 }
   1083 
   1084 #define TRACEME_SENDSIGNAL_IGNORED(test, sig)				\
   1085 ATF_TC(test);								\
   1086 ATF_TC_HEAD(test, tc)							\
   1087 {									\
   1088 	atf_tc_set_md_var(tc, "descr",					\
   1089 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
   1090 	    "handled correctly and the signal is masked by SIG_IGN");	\
   1091 }									\
   1092 									\
   1093 ATF_TC_BODY(test, tc)							\
   1094 {									\
   1095 									\
   1096 	traceme_sendsignal_ignored(sig);				\
   1097 }
   1098 
   1099 // A signal handler for SIGKILL and SIGSTOP cannot be ignored.
   1100 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */
   1101 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP)  /* hangup */
   1102 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */
   1103 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */
   1104 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */
   1105 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */
   1106 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */
   1107 TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */
   1108 
   1109 /// ----------------------------------------------------------------------------
   1110 
   1111 static void
   1112 traceme_sendsignal_simple(int sigsent)
   1113 {
   1114 	const int sigval = SIGSTOP;
   1115 	int exitval = 0;
   1116 	pid_t child, wpid;
   1117 #if defined(TWAIT_HAVE_STATUS)
   1118 	int status;
   1119 	int expect_core;
   1120 
   1121 	switch (sigsent) {
   1122 	case SIGABRT:
   1123 	case SIGTRAP:
   1124 	case SIGBUS:
   1125 	case SIGILL:
   1126 	case SIGFPE:
   1127 	case SIGSEGV:
   1128 		expect_core = 1;
   1129 		break;
   1130 	default:
   1131 		expect_core = 0;
   1132 		break;
   1133 	}
   1134 #endif
   1135 	struct ptrace_siginfo info;
   1136 
   1137 	memset(&info, 0, sizeof(info));
   1138 
   1139 	DPRINTF("Before forking process PID=%d\n", getpid());
   1140 	SYSCALL_REQUIRE((child = fork()) != -1);
   1141 	if (child == 0) {
   1142 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1143 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1144 
   1145 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1146 		FORKEE_ASSERT(raise(sigval) == 0);
   1147 
   1148 		switch (sigsent) {
   1149 		case SIGCONT:
   1150 		case SIGSTOP:
   1151 			_exit(exitval);
   1152 		default:
   1153 			/* NOTREACHED */
   1154 			FORKEE_ASSERTX(0 && "This shall not be reached");
   1155 		}
   1156 	}
   1157 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1158 
   1159 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1160 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1161 
   1162 	validate_status_stopped(status, sigval);
   1163 
   1164 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
   1165 	SYSCALL_REQUIRE(
   1166 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
   1167 
   1168 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1169 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
   1170 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
   1171 	    info.psi_siginfo.si_errno);
   1172 
   1173 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
   1174 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
   1175 
   1176 	DPRINTF("Before resuming the child process where it left off and with "
   1177 	    "signal %s to be sent\n", strsignal(sigsent));
   1178 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
   1179 
   1180 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1181 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1182 
   1183 	switch (sigsent) {
   1184 	case SIGSTOP:
   1185 		validate_status_stopped(status, sigsent);
   1186 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
   1187 		    "child\n");
   1188 		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
   1189 		    sizeof(info)) != -1);
   1190 
   1191 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1192 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1193 		    "si_errno=%#x\n",
   1194 		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
   1195 		    info.psi_siginfo.si_errno);
   1196 
   1197 		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
   1198 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
   1199 
   1200 		DPRINTF("Before resuming the child process where it left off "
   1201 		    "and with signal %s to be sent\n", strsignal(sigsent));
   1202 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1203 
   1204 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1205 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
   1206 		    child);
   1207 		/* FALLTHROUGH */
   1208 	case SIGCONT:
   1209 		validate_status_exited(status, exitval);
   1210 		break;
   1211 	default:
   1212 		validate_status_signaled(status, sigsent, expect_core);
   1213 		break;
   1214 	}
   1215 
   1216 	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
   1217 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1218 }
   1219 
   1220 #define TRACEME_SENDSIGNAL_SIMPLE(test, sig)				\
   1221 ATF_TC(test);								\
   1222 ATF_TC_HEAD(test, tc)							\
   1223 {									\
   1224 	atf_tc_set_md_var(tc, "descr",					\
   1225 	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
   1226 	    "handled correctly in a child without a signal handler");	\
   1227 }									\
   1228 									\
   1229 ATF_TC_BODY(test, tc)							\
   1230 {									\
   1231 									\
   1232 	traceme_sendsignal_simple(sig);					\
   1233 }
   1234 
   1235 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/
   1236 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/
   1237 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */
   1238 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP)  /* hangup */
   1239 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */
   1240 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */
   1241 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */
   1242 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */
   1243 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */
   1244 TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */
   1245 
   1246 /// ----------------------------------------------------------------------------
   1247 
   1248 static void
   1249 traceme_vfork_raise(int sigval)
   1250 {
   1251 	const int exitval = 5, exitval_watcher = 10;
   1252 	pid_t child, parent, watcher, wpid;
   1253 	int rv;
   1254 #if defined(TWAIT_HAVE_STATUS)
   1255 	int status;
   1256 
   1257 	/* volatile workarounds GCC -Werror=clobbered */
   1258 	volatile int expect_core;
   1259 
   1260 	switch (sigval) {
   1261 	case SIGABRT:
   1262 	case SIGTRAP:
   1263 	case SIGBUS:
   1264 	case SIGILL:
   1265 	case SIGFPE:
   1266 	case SIGSEGV:
   1267 		expect_core = 1;
   1268 		break;
   1269 	default:
   1270 		expect_core = 0;
   1271 		break;
   1272 	}
   1273 #endif
   1274 
   1275 	/*
   1276 	 * Spawn a dedicated thread to watch for a stopped child and emit
   1277 	 * the SIGKILL signal to it.
   1278 	 *
   1279 	 * vfork(2) might clobber watcher, this means that it's safer and
   1280 	 * simpler to reparent this process to initproc and forget about it.
   1281 	 */
   1282 	if (sigval == SIGSTOP) {
   1283 		parent = getpid();
   1284 
   1285 		watcher = fork();
   1286 		ATF_REQUIRE(watcher != 1);
   1287 		if (watcher == 0) {
   1288 			/* Double fork(2) trick to reparent to initproc */
   1289 			watcher = fork();
   1290 			FORKEE_ASSERT_NEQ(watcher, -1);
   1291 			if (watcher != 0)
   1292 				_exit(exitval_watcher);
   1293 
   1294 			child = await_stopped_child(parent);
   1295 
   1296 			errno = 0;
   1297 			rv = kill(child, SIGKILL);
   1298 			FORKEE_ASSERT_EQ(rv, 0);
   1299 			FORKEE_ASSERT_EQ(errno, 0);
   1300 
   1301 			/* This exit value will be collected by initproc */
   1302 			_exit(0);
   1303 		}
   1304 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1305 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
   1306 		    watcher);
   1307 
   1308 		validate_status_exited(status, exitval_watcher);
   1309 
   1310 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1311 		TWAIT_REQUIRE_FAILURE(ECHILD,
   1312 		    wpid = TWAIT_GENERIC(watcher, &status, 0));
   1313 	}
   1314 
   1315 	DPRINTF("Before forking process PID=%d\n", getpid());
   1316 	SYSCALL_REQUIRE((child = vfork()) != -1);
   1317 	if (child == 0) {
   1318 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1319 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1320 
   1321 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1322 		FORKEE_ASSERT(raise(sigval) == 0);
   1323 
   1324 		switch (sigval) {
   1325 		case SIGSTOP:
   1326 		case SIGKILL:
   1327 		case SIGABRT:
   1328 		case SIGHUP:
   1329 		case SIGTRAP:
   1330 		case SIGBUS:
   1331 		case SIGILL:
   1332 		case SIGFPE:
   1333 		case SIGSEGV:
   1334 			/* NOTREACHED */
   1335 			FORKEE_ASSERTX(0 && "This shall not be reached");
   1336 			__unreachable();
   1337 		default:
   1338 			DPRINTF("Before exiting of the child process\n");
   1339 			_exit(exitval);
   1340 		}
   1341 	}
   1342 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1343 
   1344 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1345 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1346 
   1347 	switch (sigval) {
   1348 	case SIGKILL:
   1349 	case SIGABRT:
   1350 	case SIGHUP:
   1351 	case SIGTRAP:
   1352 	case SIGBUS:
   1353 	case SIGILL:
   1354 	case SIGFPE:
   1355 	case SIGSEGV:
   1356 		validate_status_signaled(status, sigval, expect_core);
   1357 		break;
   1358 	case SIGSTOP:
   1359 		validate_status_signaled(status, SIGKILL, 0);
   1360 		break;
   1361 	case SIGCONT:
   1362 	case SIGTSTP:
   1363 	case SIGTTIN:
   1364 	case SIGTTOU:
   1365 		validate_status_exited(status, exitval);
   1366 		break;
   1367 	default:
   1368 		/* NOTREACHED */
   1369 		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
   1370 		break;
   1371 	}
   1372 
   1373 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1374 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1375 }
   1376 
   1377 #define TRACEME_VFORK_RAISE(test, sig)					\
   1378 ATF_TC(test);								\
   1379 ATF_TC_HEAD(test, tc)							\
   1380 {									\
   1381 	atf_tc_set_md_var(tc, "descr",					\
   1382 	    "Verify PT_TRACE_ME followed by raise of " #sig " in a "	\
   1383 	    "vfork(2)ed child");					\
   1384 }									\
   1385 									\
   1386 ATF_TC_BODY(test, tc)							\
   1387 {									\
   1388 									\
   1389 	traceme_vfork_raise(sig);					\
   1390 }
   1391 
   1392 TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
   1393 TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
   1394 TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
   1395 TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
   1396 TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
   1397 TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
   1398 TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
   1399 TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
   1400 TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */
   1401 TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */
   1402 TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */
   1403 TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */
   1404 TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */
   1405 
   1406 /// ----------------------------------------------------------------------------
   1407 
   1408 static void
   1409 traceme_vfork_crash(int sig)
   1410 {
   1411 	pid_t child, wpid;
   1412 #if defined(TWAIT_HAVE_STATUS)
   1413 	int status;
   1414 #endif
   1415 
   1416 #ifndef PTRACE_ILLEGAL_ASM
   1417 	if (sig == SIGILL)
   1418 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
   1419 #endif
   1420 
   1421 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
   1422 		atf_tc_skip("FP exceptions are not supported");
   1423 
   1424 	DPRINTF("Before forking process PID=%d\n", getpid());
   1425 	SYSCALL_REQUIRE((child = vfork()) != -1);
   1426 	if (child == 0) {
   1427 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1428 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1429 
   1430 		DPRINTF("Before executing a trap\n");
   1431 		switch (sig) {
   1432 		case SIGTRAP:
   1433 			trigger_trap();
   1434 			break;
   1435 		case SIGSEGV:
   1436 			trigger_segv();
   1437 			break;
   1438 		case SIGILL:
   1439 			trigger_ill();
   1440 			break;
   1441 		case SIGFPE:
   1442 			trigger_fpe();
   1443 			break;
   1444 		case SIGBUS:
   1445 			trigger_bus();
   1446 			break;
   1447 		default:
   1448 			/* NOTREACHED */
   1449 			FORKEE_ASSERTX(0 && "This shall not be reached");
   1450 		}
   1451 
   1452 		/* NOTREACHED */
   1453 		FORKEE_ASSERTX(0 && "This shall not be reached");
   1454 	}
   1455 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1456 
   1457 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1458 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1459 
   1460 	validate_status_signaled(status, sig, 1);
   1461 
   1462 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1463 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1464 }
   1465 
   1466 #define TRACEME_VFORK_CRASH(test, sig)					\
   1467 ATF_TC(test);								\
   1468 ATF_TC_HEAD(test, tc)							\
   1469 {									\
   1470 	atf_tc_set_md_var(tc, "descr",					\
   1471 	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
   1472 	    "vfork(2)ed child");					\
   1473 }									\
   1474 									\
   1475 ATF_TC_BODY(test, tc)							\
   1476 {									\
   1477 									\
   1478 	traceme_vfork_crash(sig);					\
   1479 }
   1480 
   1481 TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP)
   1482 TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV)
   1483 TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL)
   1484 TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE)
   1485 TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS)
   1486 
   1487 /// ----------------------------------------------------------------------------
   1488 
   1489 static void
   1490 traceme_vfork_signalmasked_crash(int sig)
   1491 {
   1492 	pid_t child, wpid;
   1493 #if defined(TWAIT_HAVE_STATUS)
   1494 	int status;
   1495 #endif
   1496 	sigset_t intmask;
   1497 
   1498 #ifndef PTRACE_ILLEGAL_ASM
   1499 	if (sig == SIGILL)
   1500 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
   1501 #endif
   1502 
   1503 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
   1504 		atf_tc_skip("FP exceptions are not supported");
   1505 
   1506 	DPRINTF("Before forking process PID=%d\n", getpid());
   1507 	SYSCALL_REQUIRE((child = vfork()) != -1);
   1508 	if (child == 0) {
   1509 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1510 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1511 
   1512 		sigemptyset(&intmask);
   1513 		sigaddset(&intmask, sig);
   1514 		sigprocmask(SIG_BLOCK, &intmask, NULL);
   1515 
   1516 		DPRINTF("Before executing a trap\n");
   1517 		switch (sig) {
   1518 		case SIGTRAP:
   1519 			trigger_trap();
   1520 			break;
   1521 		case SIGSEGV:
   1522 			trigger_segv();
   1523 			break;
   1524 		case SIGILL:
   1525 			trigger_ill();
   1526 			break;
   1527 		case SIGFPE:
   1528 			trigger_fpe();
   1529 			break;
   1530 		case SIGBUS:
   1531 			trigger_bus();
   1532 			break;
   1533 		default:
   1534 			/* NOTREACHED */
   1535 			FORKEE_ASSERTX(0 && "This shall not be reached");
   1536 		}
   1537 
   1538 		/* NOTREACHED */
   1539 		FORKEE_ASSERTX(0 && "This shall not be reached");
   1540 	}
   1541 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1542 
   1543 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1544 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1545 
   1546 	validate_status_signaled(status, sig, 1);
   1547 
   1548 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1549 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1550 }
   1551 
   1552 #define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig)			\
   1553 ATF_TC(test);								\
   1554 ATF_TC_HEAD(test, tc)							\
   1555 {									\
   1556 	atf_tc_set_md_var(tc, "descr",					\
   1557 	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
   1558 	    "vfork(2)ed child with a masked signal");			\
   1559 }									\
   1560 									\
   1561 ATF_TC_BODY(test, tc)							\
   1562 {									\
   1563 									\
   1564 	traceme_vfork_signalmasked_crash(sig);				\
   1565 }
   1566 
   1567 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP)
   1568 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV)
   1569 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL)
   1570 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE)
   1571 TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS)
   1572 
   1573 /// ----------------------------------------------------------------------------
   1574 
   1575 static void
   1576 traceme_vfork_signalignored_crash(int sig)
   1577 {
   1578 	pid_t child, wpid;
   1579 #if defined(TWAIT_HAVE_STATUS)
   1580 	int status;
   1581 #endif
   1582 	struct sigaction sa;
   1583 
   1584 #ifndef PTRACE_ILLEGAL_ASM
   1585 	if (sig == SIGILL)
   1586 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
   1587 #endif
   1588 
   1589 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
   1590 		atf_tc_skip("FP exceptions are not supported");
   1591 
   1592 	DPRINTF("Before forking process PID=%d\n", getpid());
   1593 	SYSCALL_REQUIRE((child = vfork()) != -1);
   1594 	if (child == 0) {
   1595 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1596 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1597 
   1598 		memset(&sa, 0, sizeof(sa));
   1599 		sa.sa_handler = SIG_IGN;
   1600 		sigemptyset(&sa.sa_mask);
   1601 
   1602 		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
   1603 
   1604 		DPRINTF("Before executing a trap\n");
   1605 		switch (sig) {
   1606 		case SIGTRAP:
   1607 			trigger_trap();
   1608 			break;
   1609 		case SIGSEGV:
   1610 			trigger_segv();
   1611 			break;
   1612 		case SIGILL:
   1613 			trigger_ill();
   1614 			break;
   1615 		case SIGFPE:
   1616 			trigger_fpe();
   1617 			break;
   1618 		case SIGBUS:
   1619 			trigger_bus();
   1620 			break;
   1621 		default:
   1622 			/* NOTREACHED */
   1623 			FORKEE_ASSERTX(0 && "This shall not be reached");
   1624 		}
   1625 
   1626 		/* NOTREACHED */
   1627 		FORKEE_ASSERTX(0 && "This shall not be reached");
   1628 	}
   1629 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1630 
   1631 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1632 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1633 
   1634 	validate_status_signaled(status, sig, 1);
   1635 
   1636 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1637 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1638 }
   1639 
   1640 #define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig)			\
   1641 ATF_TC(test);								\
   1642 ATF_TC_HEAD(test, tc)							\
   1643 {									\
   1644 	atf_tc_set_md_var(tc, "descr",					\
   1645 	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
   1646 	    "vfork(2)ed child with ignored signal");			\
   1647 }									\
   1648 									\
   1649 ATF_TC_BODY(test, tc)							\
   1650 {									\
   1651 									\
   1652 	traceme_vfork_signalignored_crash(sig);				\
   1653 }
   1654 
   1655 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,
   1656     SIGTRAP)
   1657 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv,
   1658     SIGSEGV)
   1659 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill,
   1660     SIGILL)
   1661 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe,
   1662     SIGFPE)
   1663 TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus,
   1664     SIGBUS)
   1665 
   1666 /// ----------------------------------------------------------------------------
   1667 
   1668 #if defined(TWAIT_HAVE_PID)
   1669 static void
   1670 unrelated_tracer_sees_crash(int sig, bool masked, bool ignored)
   1671 {
   1672 	const int sigval = SIGSTOP;
   1673 	struct msg_fds parent_tracee, parent_tracer;
   1674 	const int exitval = 10;
   1675 	pid_t tracee, tracer, wpid;
   1676 	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
   1677 #if defined(TWAIT_HAVE_STATUS)
   1678 	int status;
   1679 #endif
   1680 	struct sigaction sa;
   1681 	struct ptrace_siginfo info;
   1682 	sigset_t intmask;
   1683 	struct kinfo_proc2 kp;
   1684 	size_t len = sizeof(kp);
   1685 
   1686 	int name[6];
   1687 	const size_t namelen = __arraycount(name);
   1688 	ki_sigset_t kp_sigmask;
   1689 	ki_sigset_t kp_sigignore;
   1690 
   1691 #ifndef PTRACE_ILLEGAL_ASM
   1692 	if (sig == SIGILL)
   1693 		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
   1694 #endif
   1695 
   1696 	if (sig == SIGFPE && !are_fpu_exceptions_supported())
   1697 		atf_tc_skip("FP exceptions are not supported");
   1698 
   1699 	memset(&info, 0, sizeof(info));
   1700 
   1701 	DPRINTF("Spawn tracee\n");
   1702 	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
   1703 	tracee = atf_utils_fork();
   1704 	if (tracee == 0) {
   1705 		// Wait for parent to let us crash
   1706 		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
   1707 
   1708 		if (masked) {
   1709 			sigemptyset(&intmask);
   1710 			sigaddset(&intmask, sig);
   1711 			sigprocmask(SIG_BLOCK, &intmask, NULL);
   1712 		}
   1713 
   1714 		if (ignored) {
   1715 			memset(&sa, 0, sizeof(sa));
   1716 			sa.sa_handler = SIG_IGN;
   1717 			sigemptyset(&sa.sa_mask);
   1718 			FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
   1719 		}
   1720 
   1721 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1722 		FORKEE_ASSERT(raise(sigval) == 0);
   1723 
   1724 		DPRINTF("Before executing a trap\n");
   1725 		switch (sig) {
   1726 		case SIGTRAP:
   1727 			trigger_trap();
   1728 			break;
   1729 		case SIGSEGV:
   1730 			trigger_segv();
   1731 			break;
   1732 		case SIGILL:
   1733 			trigger_ill();
   1734 			break;
   1735 		case SIGFPE:
   1736 			trigger_fpe();
   1737 			break;
   1738 		case SIGBUS:
   1739 			trigger_bus();
   1740 			break;
   1741 		default:
   1742 			/* NOTREACHED */
   1743 			FORKEE_ASSERTX(0 && "This shall not be reached");
   1744 		}
   1745 
   1746 		/* NOTREACHED */
   1747 		FORKEE_ASSERTX(0 && "This shall not be reached");
   1748 	}
   1749 
   1750 	DPRINTF("Spawn debugger\n");
   1751 	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
   1752 	tracer = atf_utils_fork();
   1753 	if (tracer == 0) {
   1754 		/* Fork again and drop parent to reattach to PID 1 */
   1755 		tracer = atf_utils_fork();
   1756 		if (tracer != 0)
   1757 			_exit(exitval);
   1758 
   1759 		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
   1760 		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
   1761 
   1762 		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
   1763 		FORKEE_REQUIRE_SUCCESS(
   1764 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1765 
   1766 		forkee_status_stopped(status, SIGSTOP);
   1767 
   1768 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
   1769 		    "traced process\n");
   1770 		SYSCALL_REQUIRE(
   1771 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
   1772 
   1773 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1774 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1775 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
   1776 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
   1777 
   1778 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
   1779 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
   1780 
   1781 		/* Resume tracee with PT_CONTINUE */
   1782 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
   1783 
   1784 		/* Inform parent that tracer has attached to tracee */
   1785 		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
   1786 
   1787 		/* Wait for parent to tell use that tracee should have exited */
   1788 		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
   1789 
   1790 		/* Wait for tracee and assert that it exited */
   1791 		FORKEE_REQUIRE_SUCCESS(
   1792 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1793 
   1794 		forkee_status_stopped(status, sigval);
   1795 
   1796 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
   1797 		    "traced process\n");
   1798 		SYSCALL_REQUIRE(
   1799 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
   1800 
   1801 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1802 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1803 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
   1804 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
   1805 
   1806 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
   1807 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
   1808 
   1809 		name[0] = CTL_KERN,
   1810 		name[1] = KERN_PROC2,
   1811 		name[2] = KERN_PROC_PID;
   1812 		name[3] = tracee;
   1813 		name[4] = sizeof(kp);
   1814 		name[5] = 1;
   1815 
   1816 		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1817 
   1818 		if (masked)
   1819 			kp_sigmask = kp.p_sigmask;
   1820 
   1821 		if (ignored)
   1822 			kp_sigignore = kp.p_sigignore;
   1823 
   1824 		/* Resume tracee with PT_CONTINUE */
   1825 		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
   1826 
   1827 		/* Wait for tracee and assert that it exited */
   1828 		FORKEE_REQUIRE_SUCCESS(
   1829 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1830 
   1831 		forkee_status_stopped(status, sig);
   1832 
   1833 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
   1834 		    "traced process\n");
   1835 		SYSCALL_REQUIRE(
   1836 		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
   1837 
   1838 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1839 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
   1840 		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
   1841 		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
   1842 
   1843 		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig);
   1844 
   1845 		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
   1846 
   1847 		if (masked) {
   1848 			DPRINTF("kp_sigmask="
   1849 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1850 			    PRIx32 "\n",
   1851 			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
   1852 			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
   1853 
   1854 			DPRINTF("kp.p_sigmask="
   1855 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1856 			    PRIx32 "\n",
   1857 			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
   1858 			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
   1859 
   1860 			FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask,
   1861 			    sizeof(kp_sigmask)));
   1862 		}
   1863 
   1864 		if (ignored) {
   1865 			DPRINTF("kp_sigignore="
   1866 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1867 			    PRIx32 "\n",
   1868 			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
   1869 			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
   1870 
   1871 			DPRINTF("kp.p_sigignore="
   1872 			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
   1873 			    PRIx32 "\n",
   1874 			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
   1875 			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
   1876 
   1877 			FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore,
   1878 			    sizeof(kp_sigignore)));
   1879 		}
   1880 
   1881 		switch (sig) {
   1882 		case SIGTRAP:
   1883 			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
   1884 			break;
   1885 		case SIGSEGV:
   1886 			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
   1887 			break;
   1888 		case SIGILL:
   1889 			FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC &&
   1890 			            info.psi_siginfo.si_code <= ILL_BADSTK);
   1891 			break;
   1892 		case SIGFPE:
   1893 // XXXQEMU		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_FLTDIV);
   1894 			break;
   1895 		case SIGBUS:
   1896 			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
   1897 			break;
   1898 		}
   1899 
   1900 		FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1);
   1901 		DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME);
   1902 		FORKEE_REQUIRE_SUCCESS(
   1903 		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1904 
   1905 		forkee_status_signaled(status, SIGKILL, 0);
   1906 
   1907 		/* Inform parent that tracer is exiting normally */
   1908 		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
   1909 
   1910 		DPRINTF("Before exiting of the tracer process\n");
   1911 		_exit(0 /* collect by initproc */);
   1912 	}
   1913 
   1914 	DPRINTF("Wait for the tracer process (direct child) to exit "
   1915 	    "calling %s()\n", TWAIT_FNAME);
   1916 	TWAIT_REQUIRE_SUCCESS(
   1917 	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
   1918 
   1919 	validate_status_exited(status, exitval);
   1920 
   1921 	DPRINTF("Wait for the non-exited tracee process with %s()\n",
   1922 	    TWAIT_FNAME);
   1923 	TWAIT_REQUIRE_SUCCESS(
   1924 	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
   1925 
   1926 	DPRINTF("Wait for the tracer to attach to the tracee\n");
   1927 	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
   1928 
   1929 	DPRINTF("Resume the tracee and let it crash\n");
   1930 	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
   1931 
   1932 	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
   1933 	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
   1934 
   1935 	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
   1936 	    TWAIT_FNAME);
   1937 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
   1938 
   1939 	validate_status_signaled(status, SIGKILL, 0);
   1940 
   1941 	DPRINTF("Await normal exit of tracer\n");
   1942 	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
   1943 
   1944 	msg_close(&parent_tracer);
   1945 	msg_close(&parent_tracee);
   1946 }
   1947 
   1948 #define UNRELATED_TRACER_SEES_CRASH(test, sig)				\
   1949 ATF_TC(test);								\
   1950 ATF_TC_HEAD(test, tc)							\
   1951 {									\
   1952 	atf_tc_set_md_var(tc, "descr",					\
   1953 	    "Assert that an unrelated tracer sees crash signal from "	\
   1954 	    "the debuggee");						\
   1955 }									\
   1956 									\
   1957 ATF_TC_BODY(test, tc)							\
   1958 {									\
   1959 									\
   1960 	unrelated_tracer_sees_crash(sig, false, false);			\
   1961 }
   1962 
   1963 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP)
   1964 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV)
   1965 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL)
   1966 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE)
   1967 UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS)
   1968 
   1969 #define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig)		\
   1970 ATF_TC(test);								\
   1971 ATF_TC_HEAD(test, tc)							\
   1972 {									\
   1973 	atf_tc_set_md_var(tc, "descr",					\
   1974 	    "Assert that an unrelated tracer sees crash signal from "	\
   1975 	    "the debuggee with masked signal");				\
   1976 }									\
   1977 									\
   1978 ATF_TC_BODY(test, tc)							\
   1979 {									\
   1980 									\
   1981 	unrelated_tracer_sees_crash(sig, true, false);			\
   1982 }
   1983 
   1984 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
   1985     unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP)
   1986 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
   1987     unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV)
   1988 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
   1989     unrelated_tracer_sees_signalmasked_crash_ill, SIGILL)
   1990 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
   1991     unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE)
   1992 UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
   1993     unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS)
   1994 
   1995 #define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig)		\
   1996 ATF_TC(test);								\
   1997 ATF_TC_HEAD(test, tc)							\
   1998 {									\
   1999 	atf_tc_set_md_var(tc, "descr",					\
   2000 	    "Assert that an unrelated tracer sees crash signal from "	\
   2001 	    "the debuggee with signal ignored");			\
   2002 }									\
   2003 									\
   2004 ATF_TC_BODY(test, tc)							\
   2005 {									\
   2006 									\
   2007 	unrelated_tracer_sees_crash(sig, false, true);			\
   2008 }
   2009 
   2010 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
   2011     unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP)
   2012 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
   2013     unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV)
   2014 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
   2015     unrelated_tracer_sees_signalignored_crash_ill, SIGILL)
   2016 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
   2017     unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE)
   2018 UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
   2019     unrelated_tracer_sees_signalignored_crash_bus, SIGBUS)
   2020 #endif
   2021 
   2022 /// ----------------------------------------------------------------------------
   2023 
   2024 ATF_TC(signal_mask_unrelated);
   2025 ATF_TC_HEAD(signal_mask_unrelated, tc)
   2026 {
   2027 	atf_tc_set_md_var(tc, "descr",
   2028 	    "Verify that masking single unrelated signal does not stop tracer "
   2029 	    "from catching other signals");
   2030 }
   2031 
   2032 ATF_TC_BODY(signal_mask_unrelated, tc)
   2033 {
   2034 	const int exitval = 5;
   2035 	const int sigval = SIGSTOP;
   2036 	const int sigmasked = SIGTRAP;
   2037 	const int signotmasked = SIGINT;
   2038 	pid_t child, wpid;
   2039 #if defined(TWAIT_HAVE_STATUS)
   2040 	int status;
   2041 #endif
   2042 	sigset_t intmask;
   2043 
   2044 	DPRINTF("Before forking process PID=%d\n", getpid());
   2045 	SYSCALL_REQUIRE((child = fork()) != -1);
   2046 	if (child == 0) {
   2047 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   2048 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   2049 
   2050 		sigemptyset(&intmask);
   2051 		sigaddset(&intmask, sigmasked);
   2052 		sigprocmask(SIG_BLOCK, &intmask, NULL);
   2053 
   2054 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   2055 		FORKEE_ASSERT(raise(sigval) == 0);
   2056 
   2057 		DPRINTF("Before raising %s from child\n",
   2058 		    strsignal(signotmasked));
   2059 		FORKEE_ASSERT(raise(signotmasked) == 0);
   2060 
   2061 		DPRINTF("Before exiting of the child process\n");
   2062 		_exit(exitval);
   2063 	}
   2064 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   2065 
   2066 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2067 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2068 
   2069 	validate_status_stopped(status, sigval);
   2070 
   2071 	DPRINTF("Before resuming the child process where it left off and "
   2072 	    "without signal to be sent\n");
   2073 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   2074 
   2075 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2076 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2077 
   2078 	validate_status_stopped(status, signotmasked);
   2079 
   2080 	DPRINTF("Before resuming the child process where it left off and "
   2081 	    "without signal to be sent\n");
   2082 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   2083 
   2084 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2085 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2086 
   2087 	validate_status_exited(status, exitval);
   2088 
   2089 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2090 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   2091 }
   2092 
   2093 /// ----------------------------------------------------------------------------
   2094 
   2095 #define ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL() \
   2096 	ATF_TP_ADD_TC(tp, traceme_raise1); \
   2097 	ATF_TP_ADD_TC(tp, traceme_raise2); \
   2098 	ATF_TP_ADD_TC(tp, traceme_raise3); \
   2099 	ATF_TP_ADD_TC(tp, traceme_raise4); \
   2100 	ATF_TP_ADD_TC(tp, traceme_raise5); \
   2101 	ATF_TP_ADD_TC(tp, traceme_raise6); \
   2102 	ATF_TP_ADD_TC(tp, traceme_raise7); \
   2103 	ATF_TP_ADD_TC(tp, traceme_raise8); \
   2104 	ATF_TP_ADD_TC(tp, traceme_raise9); \
   2105 	ATF_TP_ADD_TC(tp, traceme_raise10); \
   2106 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); \
   2107 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); \
   2108 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); \
   2109 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); \
   2110 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); \
   2111 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); \
   2112 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); \
   2113 	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); \
   2114 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); \
   2115 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); \
   2116 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); \
   2117 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); \
   2118 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); \
   2119 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); \
   2120 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); \
   2121 	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); \
   2122 	ATF_TP_ADD_TC(tp, traceme_crash_trap); \
   2123 	ATF_TP_ADD_TC(tp, traceme_crash_segv); \
   2124 	ATF_TP_ADD_TC(tp, traceme_crash_ill); \
   2125 	ATF_TP_ADD_TC(tp, traceme_crash_fpe); \
   2126 	ATF_TP_ADD_TC(tp, traceme_crash_bus); \
   2127 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); \
   2128 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); \
   2129 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); \
   2130 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); \
   2131 	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); \
   2132 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); \
   2133 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); \
   2134 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); \
   2135 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); \
   2136 	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); \
   2137 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); \
   2138 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); \
   2139 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); \
   2140 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); \
   2141 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); \
   2142 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); \
   2143 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); \
   2144 	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); \
   2145 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); \
   2146 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); \
   2147 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); \
   2148 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); \
   2149 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); \
   2150 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); \
   2151 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); \
   2152 	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); \
   2153 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); \
   2154 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); \
   2155 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); \
   2156 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); \
   2157 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); \
   2158 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); \
   2159 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); \
   2160 	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); \
   2161 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); \
   2162 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); \
   2163 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); \
   2164 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); \
   2165 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); \
   2166 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); \
   2167 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); \
   2168 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); \
   2169 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); \
   2170 	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); \
   2171 	ATF_TP_ADD_TC(tp, traceme_vfork_raise1); \
   2172 	ATF_TP_ADD_TC(tp, traceme_vfork_raise2); \
   2173 	ATF_TP_ADD_TC(tp, traceme_vfork_raise3); \
   2174 	ATF_TP_ADD_TC(tp, traceme_vfork_raise4); \
   2175 	ATF_TP_ADD_TC(tp, traceme_vfork_raise5); \
   2176 	ATF_TP_ADD_TC(tp, traceme_vfork_raise6); \
   2177 	ATF_TP_ADD_TC(tp, traceme_vfork_raise7); \
   2178 	ATF_TP_ADD_TC(tp, traceme_vfork_raise8); \
   2179 	ATF_TP_ADD_TC(tp, traceme_vfork_raise9); \
   2180 	ATF_TP_ADD_TC(tp, traceme_vfork_raise10); \
   2181 	ATF_TP_ADD_TC(tp, traceme_vfork_raise11); \
   2182 	ATF_TP_ADD_TC(tp, traceme_vfork_raise12); \
   2183 	ATF_TP_ADD_TC(tp, traceme_vfork_raise13); \
   2184 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); \
   2185 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); \
   2186 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); \
   2187 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); \
   2188 	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); \
   2189 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); \
   2190 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); \
   2191 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); \
   2192 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); \
   2193 	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); \
   2194 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); \
   2195 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); \
   2196 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); \
   2197 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); \
   2198 	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); \
   2199 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); \
   2200 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); \
   2201 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); \
   2202 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); \
   2203 	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); \
   2204 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2205 	    unrelated_tracer_sees_signalmasked_crash_trap); \
   2206 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2207 	    unrelated_tracer_sees_signalmasked_crash_segv); \
   2208 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2209 	    unrelated_tracer_sees_signalmasked_crash_ill); \
   2210 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2211 	    unrelated_tracer_sees_signalmasked_crash_fpe); \
   2212 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2213 	    unrelated_tracer_sees_signalmasked_crash_bus); \
   2214 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2215 	    unrelated_tracer_sees_signalignored_crash_trap); \
   2216 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2217 	    unrelated_tracer_sees_signalignored_crash_segv); \
   2218 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2219 	    unrelated_tracer_sees_signalignored_crash_ill); \
   2220 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2221 	    unrelated_tracer_sees_signalignored_crash_fpe); \
   2222 	ATF_TP_ADD_TC_HAVE_PID(tp, \
   2223 	    unrelated_tracer_sees_signalignored_crash_bus); \
   2224 	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
   2225