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