Home | History | Annotate | Line # | Download | only in sys
t_ptrace_threads_wait.h revision 1.1
      1 /*	$NetBSD: t_ptrace_threads_wait.h,v 1.1 2020/05/05 00:50:39 kamil Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 
     30 #define TRACE_THREADS_NUM 100
     31 
     32 static volatile int done;
     33 pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER;
     34 
     35 static void *
     36 trace_threads_cb(void *arg __unused)
     37 {
     38 
     39 	pthread_mutex_lock(&trace_threads_mtx);
     40 	done++;
     41 	pthread_mutex_unlock(&trace_threads_mtx);
     42 
     43 	while (done < TRACE_THREADS_NUM)
     44 		sched_yield();
     45 
     46 	return NULL;
     47 }
     48 
     49 static void
     50 trace_threads(bool trace_create, bool trace_exit, bool masked)
     51 {
     52 	const int sigval = SIGSTOP;
     53 	pid_t child, wpid;
     54 #if defined(TWAIT_HAVE_STATUS)
     55 	int status;
     56 #endif
     57 	ptrace_state_t state;
     58 	const int slen = sizeof(state);
     59 	ptrace_event_t event;
     60 	const int elen = sizeof(event);
     61 	struct ptrace_siginfo info;
     62 
     63 	sigset_t intmask;
     64 
     65 	pthread_t t[TRACE_THREADS_NUM];
     66 	int rv;
     67 	size_t n;
     68 	lwpid_t lid;
     69 
     70 	/* Track created and exited threads */
     71 	struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}};
     72 
     73 	DPRINTF("Before forking process PID=%d\n", getpid());
     74 	SYSCALL_REQUIRE((child = fork()) != -1);
     75 	if (child == 0) {
     76 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
     77 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
     78 
     79 		if (masked) {
     80 			sigemptyset(&intmask);
     81 			sigaddset(&intmask, SIGTRAP);
     82 			sigprocmask(SIG_BLOCK, &intmask, NULL);
     83 		}
     84 
     85 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
     86 		FORKEE_ASSERT(raise(sigval) == 0);
     87 
     88 		for (n = 0; n < __arraycount(t); n++) {
     89 			rv = pthread_create(&t[n], NULL, trace_threads_cb,
     90 			    NULL);
     91 			FORKEE_ASSERT(rv == 0);
     92 		}
     93 
     94 		for (n = 0; n < __arraycount(t); n++) {
     95 			rv = pthread_join(t[n], NULL);
     96 			FORKEE_ASSERT(rv == 0);
     97 		}
     98 
     99 		/*
    100 		 * There is race between _exit() and pthread_join() detaching
    101 		 * a thread. For simplicity kill the process after detecting
    102 		 * LWP events.
    103 		 */
    104 		while (true)
    105 			continue;
    106 
    107 		FORKEE_ASSERT(0 && "Not reached");
    108 	}
    109 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    110 
    111 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    112 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    113 
    114 	validate_status_stopped(status, sigval);
    115 
    116 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    117 	SYSCALL_REQUIRE(
    118 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    119 
    120 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    121 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    122 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    123 	    info.psi_siginfo.si_errno);
    124 
    125 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    126 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    127 
    128 	DPRINTF("Set LWP event mask for the child %d\n", child);
    129 	memset(&event, 0, sizeof(event));
    130 	if (trace_create)
    131 		event.pe_set_event |= PTRACE_LWP_CREATE;
    132 	if (trace_exit)
    133 		event.pe_set_event |= PTRACE_LWP_EXIT;
    134 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
    135 
    136 	DPRINTF("Before resuming the child process where it left off and "
    137 	    "without signal to be sent\n");
    138 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    139 
    140 	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
    141 		DPRINTF("Before calling %s() for the child - expected stopped "
    142 		    "SIGTRAP\n", TWAIT_FNAME);
    143 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    144 		    child);
    145 
    146 		validate_status_stopped(status, SIGTRAP);
    147 
    148 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
    149 		    "child\n");
    150 		SYSCALL_REQUIRE(
    151 		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    152 
    153 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    154 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    155 		    "si_errno=%#x\n",
    156 		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    157 		    info.psi_siginfo.si_errno);
    158 
    159 		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
    160 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
    161 
    162 		SYSCALL_REQUIRE(
    163 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    164 
    165 		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
    166 		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
    167 
    168 		lid = state.pe_lwp;
    169 		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
    170 
    171 		*FIND_EVENT_COUNT(traced_lwps, lid) += 1;
    172 
    173 		DPRINTF("Before resuming the child process where it left off "
    174 		    "and without signal to be sent\n");
    175 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    176 	}
    177 
    178 	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
    179 		DPRINTF("Before calling %s() for the child - expected stopped "
    180 		    "SIGTRAP\n", TWAIT_FNAME);
    181 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    182 		    child);
    183 
    184 		validate_status_stopped(status, SIGTRAP);
    185 
    186 		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
    187 		    "child\n");
    188 		SYSCALL_REQUIRE(
    189 		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    190 
    191 		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    192 		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    193 		    "si_errno=%#x\n",
    194 		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    195 		    info.psi_siginfo.si_errno);
    196 
    197 		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
    198 		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
    199 
    200 		SYSCALL_REQUIRE(
    201 		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    202 
    203 		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
    204 		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
    205 
    206 		lid = state.pe_lwp;
    207 		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
    208 
    209 		if (trace_create) {
    210 			int *count = FIND_EVENT_COUNT(traced_lwps, lid);
    211 			ATF_REQUIRE_EQ(*count, 1);
    212 			*count = 0;
    213 		}
    214 
    215 		DPRINTF("Before resuming the child process where it left off "
    216 		    "and without signal to be sent\n");
    217 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    218 	}
    219 
    220 	kill(child, SIGKILL);
    221 
    222 	DPRINTF("Before calling %s() for the child - expected exited\n",
    223 	    TWAIT_FNAME);
    224 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    225 
    226 	validate_status_signaled(status, SIGKILL, 0);
    227 
    228 	DPRINTF("Before calling %s() for the child - expected no process\n",
    229 	    TWAIT_FNAME);
    230 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    231 }
    232 
    233 #define TRACE_THREADS(test, trace_create, trace_exit, mask)		\
    234 ATF_TC(test);								\
    235 ATF_TC_HEAD(test, tc)							\
    236 {									\
    237         atf_tc_set_md_var(tc, "descr",					\
    238             "Verify spawning threads with%s tracing LWP create and"	\
    239 	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
    240 	    trace_exit ? "" : "out");					\
    241 }									\
    242 									\
    243 ATF_TC_BODY(test, tc)							\
    244 {									\
    245 									\
    246         trace_threads(trace_create, trace_exit, mask);			\
    247 }
    248 
    249 TRACE_THREADS(trace_thread_nolwpevents, false, false, false)
    250 TRACE_THREADS(trace_thread_lwpexit, false, true, false)
    251 TRACE_THREADS(trace_thread_lwpcreate, true, false, false)
    252 TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false)
    253 
    254 TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true)
    255 TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true)
    256 TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true)
    257 
    258 /// ----------------------------------------------------------------------------
    259 
    260 static void *
    261 thread_and_exec_thread_cb(void *arg __unused)
    262 {
    263 
    264 	execlp("/bin/echo", "/bin/echo", NULL);
    265 
    266 	abort();
    267 }
    268 
    269 static void
    270 threads_and_exec(void)
    271 {
    272 	const int sigval = SIGSTOP;
    273 	pid_t child, wpid;
    274 #if defined(TWAIT_HAVE_STATUS)
    275 	int status;
    276 #endif
    277 	ptrace_state_t state;
    278 	const int slen = sizeof(state);
    279 	ptrace_event_t event;
    280 	const int elen = sizeof(event);
    281 	struct ptrace_siginfo info;
    282 
    283 	pthread_t t;
    284 	lwpid_t lid;
    285 
    286 	DPRINTF("Before forking process PID=%d\n", getpid());
    287 	SYSCALL_REQUIRE((child = fork()) != -1);
    288 	if (child == 0) {
    289 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    290 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    291 
    292 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    293 		FORKEE_ASSERT(raise(sigval) == 0);
    294 
    295 		FORKEE_ASSERT(pthread_create(&t, NULL,
    296 		    thread_and_exec_thread_cb, NULL) == 0);
    297 
    298 		for (;;)
    299 			continue;
    300 
    301 		FORKEE_ASSERT(0 && "Not reached");
    302 	}
    303 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    304 
    305 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    306 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    307 
    308 	validate_status_stopped(status, sigval);
    309 
    310 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
    311 	SYSCALL_REQUIRE(
    312 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    313 
    314 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    315 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
    316 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    317 	    info.psi_siginfo.si_errno);
    318 
    319 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
    320 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
    321 
    322 	DPRINTF("Set LWP event mask for the child %d\n", child);
    323 	memset(&event, 0, sizeof(event));
    324 	event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
    325 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
    326 
    327 	DPRINTF("Before resuming the child process where it left off and "
    328 	    "without signal to be sent\n");
    329 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    330 
    331 	DPRINTF("Before calling %s() for the child - expected stopped "
    332 	    "SIGTRAP\n", TWAIT_FNAME);
    333 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    334 	    child);
    335 
    336 	validate_status_stopped(status, SIGTRAP);
    337 
    338 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
    339 	    "child\n");
    340 	SYSCALL_REQUIRE(
    341 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    342 
    343 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    344 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    345 	    "si_errno=%#x\n",
    346 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    347 	    info.psi_siginfo.si_errno);
    348 
    349 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
    350 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
    351 
    352 	SYSCALL_REQUIRE(
    353 	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    354 
    355 	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
    356 	    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
    357 
    358 	lid = state.pe_lwp;
    359 	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
    360 
    361 	DPRINTF("Before resuming the child process where it left off "
    362 	    "and without signal to be sent\n");
    363 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    364 
    365 	DPRINTF("Before calling %s() for the child - expected stopped "
    366 	    "SIGTRAP\n", TWAIT_FNAME);
    367 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    368 	    child);
    369 
    370 	validate_status_stopped(status, SIGTRAP);
    371 
    372 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
    373 	    "child\n");
    374 	SYSCALL_REQUIRE(
    375 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    376 
    377 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    378 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    379 	    "si_errno=%#x\n",
    380 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    381 	    info.psi_siginfo.si_errno);
    382 
    383 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
    384 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
    385 
    386 	SYSCALL_REQUIRE(
    387 	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
    388 
    389 	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
    390 	    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
    391 
    392 	lid = state.pe_lwp;
    393 	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
    394 
    395 	DPRINTF("Before resuming the child process where it left off "
    396 	    "and without signal to be sent\n");
    397 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    398 
    399 	DPRINTF("Before calling %s() for the child - expected stopped "
    400 	    "SIGTRAP\n", TWAIT_FNAME);
    401 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    402 	    child);
    403 
    404 	validate_status_stopped(status, SIGTRAP);
    405 
    406 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
    407 	    "child\n");
    408 	SYSCALL_REQUIRE(
    409 	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
    410 
    411 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
    412 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
    413 	    "si_errno=%#x\n",
    414 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
    415 	    info.psi_siginfo.si_errno);
    416 
    417 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
    418 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
    419 
    420 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
    421 
    422 	DPRINTF("Before calling %s() for the child - expected exited\n",
    423 	    TWAIT_FNAME);
    424 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    425 
    426 	validate_status_signaled(status, SIGKILL, 0);
    427 
    428 	DPRINTF("Before calling %s() for the child - expected no process\n",
    429 	    TWAIT_FNAME);
    430 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    431 }
    432 
    433 ATF_TC(threads_and_exec);
    434 ATF_TC_HEAD(threads_and_exec, tc)
    435 {
    436         atf_tc_set_md_var(tc, "descr",
    437             "Verify that multithreaded application on exec() will report "
    438 	    "LWP_EXIT events");
    439 }
    440 
    441 ATF_TC_BODY(threads_and_exec, tc)
    442 {
    443 
    444         threads_and_exec();
    445 }
    446 
    447 /// ----------------------------------------------------------------------------
    448 
    449 ATF_TC(suspend_no_deadlock);
    450 ATF_TC_HEAD(suspend_no_deadlock, tc)
    451 {
    452 	atf_tc_set_md_var(tc, "descr",
    453 	    "Verify that the while the only thread within a process is "
    454 	    "suspended, the whole process cannot be unstopped");
    455 }
    456 
    457 ATF_TC_BODY(suspend_no_deadlock, tc)
    458 {
    459 	const int exitval = 5;
    460 	const int sigval = SIGSTOP;
    461 	pid_t child, wpid;
    462 #if defined(TWAIT_HAVE_STATUS)
    463 	int status;
    464 #endif
    465 	struct ptrace_siginfo psi;
    466 
    467 	DPRINTF("Before forking process PID=%d\n", getpid());
    468 	SYSCALL_REQUIRE((child = fork()) != -1);
    469 	if (child == 0) {
    470 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    471 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    472 
    473 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    474 		FORKEE_ASSERT(raise(sigval) == 0);
    475 
    476 		DPRINTF("Before exiting of the child process\n");
    477 		_exit(exitval);
    478 	}
    479 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    480 
    481 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    482 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    483 
    484 	validate_status_stopped(status, sigval);
    485 
    486 	DPRINTF("Before reading siginfo and lwpid_t\n");
    487 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
    488 
    489 	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
    490 	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
    491 
    492 	DPRINTF("Before resuming the child process where it left off and "
    493 	    "without signal to be sent\n");
    494 	ATF_REQUIRE_ERRNO(EDEADLK,
    495 	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
    496 
    497 	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
    498 	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
    499 
    500 	DPRINTF("Before resuming the child process where it left off and "
    501 	    "without signal to be sent\n");
    502 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    503 
    504 	DPRINTF("Before calling %s() for the child - expected exited\n",
    505 	    TWAIT_FNAME);
    506 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    507 
    508 	validate_status_exited(status, exitval);
    509 
    510 	DPRINTF("Before calling %s() for the child - expected no process\n",
    511 	    TWAIT_FNAME);
    512 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    513 }
    514 
    515 /// ----------------------------------------------------------------------------
    516 
    517 static pthread_barrier_t barrier1_resume;
    518 static pthread_barrier_t barrier2_resume;
    519 
    520 static void *
    521 resume_thread(void *arg)
    522 {
    523 
    524 	raise(SIGUSR1);
    525 
    526 	pthread_barrier_wait(&barrier1_resume);
    527 
    528 	/* Debugger will suspend the process here */
    529 
    530 	pthread_barrier_wait(&barrier2_resume);
    531 
    532 	raise(SIGUSR2);
    533 
    534 	return infinite_thread(arg);
    535 }
    536 
    537 ATF_TC(resume);
    538 ATF_TC_HEAD(resume, tc)
    539 {
    540 	atf_tc_set_md_var(tc, "descr",
    541 	    "Verify that a thread can be suspended by a debugger and later "
    542 	    "resumed by the debugger");
    543 }
    544 
    545 ATF_TC_BODY(resume, tc)
    546 {
    547 	const int sigval = SIGSTOP;
    548 	pid_t child, wpid;
    549 #if defined(TWAIT_HAVE_STATUS)
    550 	int status;
    551 #endif
    552 	lwpid_t lid;
    553 	struct ptrace_siginfo psi;
    554 	pthread_t t;
    555 
    556 	DPRINTF("Before forking process PID=%d\n", getpid());
    557 	SYSCALL_REQUIRE((child = fork()) != -1);
    558 	if (child == 0) {
    559 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    560 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    561 
    562 		pthread_barrier_init(&barrier1_resume, NULL, 2);
    563 		pthread_barrier_init(&barrier2_resume, NULL, 2);
    564 
    565 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    566 		FORKEE_ASSERT(raise(sigval) == 0);
    567 
    568 		DPRINTF("Before creating new thread in child\n");
    569 		FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0);
    570 
    571 		pthread_barrier_wait(&barrier1_resume);
    572 
    573 		pthread_barrier_wait(&barrier2_resume);
    574 
    575 		infinite_thread(NULL);
    576 	}
    577 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    578 
    579 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    580 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    581 
    582 	validate_status_stopped(status, sigval);
    583 
    584 	DPRINTF("Before resuming the child process where it left off and "
    585 	    "without signal to be sent\n");
    586 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    587 
    588 	DPRINTF("Before calling %s() for the child - expected stopped "
    589 	    "SIGUSR1\n", TWAIT_FNAME);
    590 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    591 
    592 	validate_status_stopped(status, SIGUSR1);
    593 
    594 	DPRINTF("Before reading siginfo and lwpid_t\n");
    595 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
    596 
    597 	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
    598 	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
    599 
    600 	lid = psi.psi_lwpid;
    601 
    602 	DPRINTF("Before resuming the child process where it left off and "
    603 	    "without signal to be sent\n");
    604 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    605 
    606 	DPRINTF("Before suspending the parent for 1 second, we expect no signals\n");
    607 	SYSCALL_REQUIRE(sleep(1) == 0);
    608 
    609 #if defined(TWAIT_HAVE_OPTIONS)
    610 	DPRINTF("Before calling %s() for the child - expected no status\n",
    611 	    TWAIT_FNAME);
    612 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0);
    613 #endif
    614 
    615 	DPRINTF("Before resuming the child process where it left off and "
    616 	    "without signal to be sent\n");
    617 	SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1);
    618 
    619 	DPRINTF("Before calling %s() for the child - expected stopped "
    620 	    "SIGSTOP\n", TWAIT_FNAME);
    621 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    622 
    623 	validate_status_stopped(status, SIGSTOP);
    624 
    625 	DPRINTF("Before resuming LWP %d\n", lid);
    626 	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1);
    627 
    628 	DPRINTF("Before resuming the child process where it left off and "
    629 	    "without signal to be sent\n");
    630 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    631 
    632 	DPRINTF("Before calling %s() for the child - expected stopped "
    633 	    "SIGUSR2\n", TWAIT_FNAME);
    634 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    635 
    636 	validate_status_stopped(status, SIGUSR2);
    637 
    638 	DPRINTF("Before resuming the child process where it left off and "
    639 	    "without signal to be sent\n");
    640 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
    641 
    642 	DPRINTF("Before calling %s() for the child - expected exited\n",
    643 	    TWAIT_FNAME);
    644 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    645 
    646 	validate_status_signaled(status, SIGKILL, 0);
    647 
    648 	DPRINTF("Before calling %s() for the child - expected no process\n",
    649 	    TWAIT_FNAME);
    650 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
    651 }
    652 
    653 /// ----------------------------------------------------------------------------
    654 
    655 #if defined(TWAIT_HAVE_STATUS)
    656 
    657 #define THREAD_CONCURRENT_BREAKPOINT_NUM 50
    658 #define THREAD_CONCURRENT_SIGNALS_NUM 50
    659 #define THREAD_CONCURRENT_WATCHPOINT_NUM 50
    660 
    661 /* List of signals to use for the test */
    662 const int thread_concurrent_signals_list[] = {
    663 	SIGIO,
    664 	SIGXCPU,
    665 	SIGXFSZ,
    666 	SIGVTALRM,
    667 	SIGPROF,
    668 	SIGWINCH,
    669 	SIGINFO,
    670 	SIGUSR1,
    671 	SIGUSR2
    672 };
    673 
    674 enum thread_concurrent_signal_handling {
    675 	/* the signal is discarded by debugger */
    676 	TCSH_DISCARD,
    677 	/* the handler is set to SIG_IGN */
    678 	TCSH_SIG_IGN,
    679 	/* an actual handler is used */
    680 	TCSH_HANDLER
    681 };
    682 
    683 static pthread_barrier_t thread_concurrent_barrier;
    684 static pthread_key_t thread_concurrent_key;
    685 static uint32_t thread_concurrent_watchpoint_var = 0;
    686 
    687 static void *
    688 thread_concurrent_breakpoint_thread(void *arg)
    689 {
    690 	static volatile int watchme = 1;
    691 	pthread_barrier_wait(&thread_concurrent_barrier);
    692 	DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self());
    693 	check_happy(watchme);
    694 	return NULL;
    695 }
    696 
    697 static void
    698 thread_concurrent_sig_handler(int sig)
    699 {
    700 	void *tls_val = pthread_getspecific(thread_concurrent_key);
    701 	DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
    702 	FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key,
    703 	    (void*)((uintptr_t)tls_val + 1)) == 0);
    704 }
    705 
    706 static void *
    707 thread_concurrent_signals_thread(void *arg)
    708 {
    709 	int sigval = thread_concurrent_signals_list[
    710 	    _lwp_self() % __arraycount(thread_concurrent_signals_list)];
    711 	enum thread_concurrent_signal_handling *signal_handle = arg;
    712 	void *tls_val;
    713 
    714 	pthread_barrier_wait(&thread_concurrent_barrier);
    715 	DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval),
    716 		_lwp_self());
    717 	pthread_kill(pthread_self(), sigval);
    718 	if (*signal_handle == TCSH_HANDLER) {
    719 	    tls_val = pthread_getspecific(thread_concurrent_key);
    720 	    DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
    721 	    FORKEE_ASSERT(tls_val == (void*)1);
    722 	}
    723 	return NULL;
    724 }
    725 
    726 static void *
    727 thread_concurrent_watchpoint_thread(void *arg)
    728 {
    729 	pthread_barrier_wait(&thread_concurrent_barrier);
    730 	DPRINTF("Before modifying var from LWP %d\n", _lwp_self());
    731 	thread_concurrent_watchpoint_var = 1;
    732 	return NULL;
    733 }
    734 
    735 #if defined(__i386__) || defined(__x86_64__)
    736 enum thread_concurrent_sigtrap_event {
    737 	TCSE_UNKNOWN,
    738 	TCSE_BREAKPOINT,
    739 	TCSE_WATCHPOINT
    740 };
    741 
    742 static void
    743 thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid);
    744 static enum thread_concurrent_sigtrap_event
    745 thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info);
    746 #endif
    747 
    748 static void
    749 thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle,
    750     int breakpoint_threads, int signal_threads, int watchpoint_threads)
    751 {
    752 	const int exitval = 5;
    753 	const int sigval = SIGSTOP;
    754 	pid_t child, wpid;
    755 	int status;
    756 	struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM]
    757 	    = {{0, 0}};
    758 	struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
    759 	    = {{0, 0}};
    760 	struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
    761 	    = {{0, 0}};
    762 	ptrace_event_t event;
    763 	int i;
    764 
    765 #if defined(HAVE_DBREGS)
    766 	if (!can_we_set_dbregs()) {
    767 		atf_tc_skip("Either run this test as root or set sysctl(3) "
    768 		            "security.models.extensions.user_set_dbregs to 1");
    769         }
    770 #endif
    771 
    772 	atf_tc_skip("PR kern/54960");
    773 
    774 	/* Protect against out-of-bounds array access. */
    775 	ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM);
    776 	ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM);
    777 	ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM);
    778 
    779 	DPRINTF("Before forking process PID=%d\n", getpid());
    780 	SYSCALL_REQUIRE((child = fork()) != -1);
    781 	if (child == 0) {
    782 		pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM];
    783 		pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM];
    784 		pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM];
    785 
    786 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
    787 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
    788 
    789 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
    790 		FORKEE_ASSERT(raise(sigval) == 0);
    791 
    792 		if (signal_handle != TCSH_DISCARD) {
    793 			struct sigaction sa;
    794 			unsigned int j;
    795 
    796 			memset(&sa, 0, sizeof(sa));
    797 			if (signal_handle == TCSH_SIG_IGN)
    798 				sa.sa_handler = SIG_IGN;
    799 			else
    800 				sa.sa_handler = thread_concurrent_sig_handler;
    801 			sigemptyset(&sa.sa_mask);
    802 
    803 			for (j = 0;
    804 			    j < __arraycount(thread_concurrent_signals_list);
    805 			    j++)
    806 				FORKEE_ASSERT(sigaction(
    807 				    thread_concurrent_signals_list[j], &sa, NULL)
    808 				    != -1);
    809 		}
    810 
    811 		DPRINTF("Before starting threads from the child\n");
    812 		FORKEE_ASSERT(pthread_barrier_init(
    813 		    &thread_concurrent_barrier, NULL,
    814 		    breakpoint_threads + signal_threads + watchpoint_threads)
    815 		    == 0);
    816 		FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL)
    817 		    == 0);
    818 
    819 		for (i = 0; i < signal_threads; i++) {
    820 			FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL,
    821 			    thread_concurrent_signals_thread,
    822 			    &signal_handle) == 0);
    823 		}
    824 		for (i = 0; i < breakpoint_threads; i++) {
    825 			FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL,
    826 			    thread_concurrent_breakpoint_thread, NULL) == 0);
    827 		}
    828 		for (i = 0; i < watchpoint_threads; i++) {
    829 			FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL,
    830 			    thread_concurrent_watchpoint_thread, NULL) == 0);
    831 		}
    832 
    833 		DPRINTF("Before joining threads from the child\n");
    834 		for (i = 0; i < watchpoint_threads; i++) {
    835 			FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0);
    836 		}
    837 		for (i = 0; i < breakpoint_threads; i++) {
    838 			FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0);
    839 		}
    840 		for (i = 0; i < signal_threads; i++) {
    841 			FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0);
    842 		}
    843 
    844 		FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0);
    845 		FORKEE_ASSERT(pthread_barrier_destroy(
    846 		    &thread_concurrent_barrier) == 0);
    847 
    848 		DPRINTF("Before exiting of the child process\n");
    849 		_exit(exitval);
    850 	}
    851 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
    852 
    853 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    854 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
    855 
    856 	validate_status_stopped(status, sigval);
    857 
    858 	DPRINTF("Set LWP event mask for the child process\n");
    859 	memset(&event, 0, sizeof(event));
    860 	event.pe_set_event |= PTRACE_LWP_CREATE;
    861 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event))
    862 	    != -1);
    863 
    864 	DPRINTF("Before resuming the child process where it left off\n");
    865 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
    866 
    867 	DPRINTF("Before entering signal collection loop\n");
    868 	while (1) {
    869 		ptrace_siginfo_t info;
    870 
    871 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
    872 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
    873 		    child);
    874 		if (WIFEXITED(status))
    875 			break;
    876 		/* Note: we use validate_status_stopped() to get nice error
    877 		 * message.  Signal is irrelevant since it won't be reached.
    878 		 */
    879 		else if (!WIFSTOPPED(status))
    880 			validate_status_stopped(status, 0);
    881 
    882 		DPRINTF("Before calling PT_GET_SIGINFO\n");
    883 		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
    884 		    sizeof(info)) != -1);
    885 
    886 		DPRINTF("Received signal %d from LWP %d (wait: %d)\n",
    887 		    info.psi_siginfo.si_signo, info.psi_lwpid,
    888 		    WSTOPSIG(status));
    889 
    890 		ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status),
    891 		    "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid,
    892 		    WSTOPSIG(status), info.psi_siginfo.si_signo);
    893 
    894 		if (WSTOPSIG(status) != SIGTRAP) {
    895 			int expected_sig =
    896 			    thread_concurrent_signals_list[info.psi_lwpid %
    897 			    __arraycount(thread_concurrent_signals_list)];
    898 			ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig,
    899 				"lwp=%d, expected %d, got %d", info.psi_lwpid,
    900 				expected_sig, WSTOPSIG(status));
    901 
    902 			*FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1;
    903 		} else if (info.psi_siginfo.si_code == TRAP_LWP) {
    904 #if defined(__i386__) || defined(__x86_64__)
    905 			thread_concurrent_lwp_setup(child, info.psi_lwpid);
    906 #endif
    907 		} else {
    908 #if defined(__i386__) || defined(__x86_64__)
    909 			switch (thread_concurrent_handle_sigtrap(child, &info)) {
    910 				case TCSE_UNKNOWN:
    911 					/* already reported inside the function */
    912 					break;
    913 				case TCSE_BREAKPOINT:
    914 					*FIND_EVENT_COUNT(bp_counts,
    915 					    info.psi_lwpid) += 1;
    916 					break;
    917 				case TCSE_WATCHPOINT:
    918 					*FIND_EVENT_COUNT(wp_counts,
    919 					    info.psi_lwpid) += 1;
    920 					break;
    921 			}
    922 #else
    923 			ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n",
    924 			    info.psi_siginfo.si_code);
    925 #endif
    926 		}
    927 
    928 		DPRINTF("Before resuming the child process\n");
    929 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
    930 		     signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP
    931 		     ? WSTOPSIG(status) : 0) != -1);
    932 	}
    933 
    934 	for (i = 0; i < signal_threads; i++)
    935 		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1,
    936 		    "signal_counts[%d].lec_count=%d; lec_lwp=%d",
    937 		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
    938 	for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++)
    939 		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0,
    940 		    "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d",
    941 		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
    942 
    943 	for (i = 0; i < breakpoint_threads; i++)
    944 		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1,
    945 		    "bp_counts[%d].lec_count=%d; lec_lwp=%d",
    946 		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
    947 	for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++)
    948 		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0,
    949 		    "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d",
    950 		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
    951 
    952 	for (i = 0; i < watchpoint_threads; i++)
    953 		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1,
    954 		    "wp_counts[%d].lec_count=%d; lec_lwp=%d",
    955 		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
    956 	for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++)
    957 		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0,
    958 		    "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d",
    959 		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
    960 
    961 	validate_status_exited(status, exitval);
    962 }
    963 
    964 #define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr)	\
    965 ATF_TC(test);								\
    966 ATF_TC_HEAD(test, tc)							\
    967 {									\
    968 	atf_tc_set_md_var(tc, "descr", descr);				\
    969 }									\
    970 									\
    971 ATF_TC_BODY(test, tc)							\
    972 {									\
    973 	thread_concurrent_test(sig_hdl, bps, sigs, wps);		\
    974 }
    975 
    976 THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD,
    977     0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
    978     "Verify that concurrent signals issued to a single thread are reported "
    979     "correctly");
    980 THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN,
    981     0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
    982     "Verify that concurrent signals issued to a single thread are reported "
    983     "correctly and passed back to SIG_IGN handler");
    984 THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER,
    985     0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
    986     "Verify that concurrent signals issued to a single thread are reported "
    987     "correctly and passed back to a handler function");
    988 
    989 #if defined(__i386__) || defined(__x86_64__)
    990 THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD,
    991     THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0,
    992     "Verify that concurrent breakpoints are reported correctly");
    993 THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD,
    994     0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
    995     "Verify that concurrent breakpoints are reported correctly");
    996 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD,
    997     THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
    998     "Verify that concurrent breakpoints and watchpoints are reported "
    999     "correctly");
   1000 
   1001 THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD,
   1002     THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
   1003     "Verify that concurrent breakpoints and signals are reported correctly");
   1004 THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN,
   1005     THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
   1006     "Verify that concurrent breakpoints and signals are reported correctly "
   1007     "and passed back to SIG_IGN handler");
   1008 THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER,
   1009     THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
   1010     "Verify that concurrent breakpoints and signals are reported correctly "
   1011     "and passed back to a handler function");
   1012 
   1013 THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD,
   1014     0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
   1015     "Verify that concurrent watchpoints and signals are reported correctly");
   1016 THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN,
   1017     0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
   1018     "Verify that concurrent watchpoints and signals are reported correctly "
   1019     "and passed back to SIG_IGN handler");
   1020 THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER,
   1021     0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
   1022     "Verify that concurrent watchpoints and signals are reported correctly "
   1023     "and passed back to a handler function");
   1024 
   1025 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD,
   1026     THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
   1027     THREAD_CONCURRENT_WATCHPOINT_NUM,
   1028     "Verify that concurrent breakpoints, watchpoints and signals are reported "
   1029     "correctly");
   1030 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN,
   1031     THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
   1032     THREAD_CONCURRENT_WATCHPOINT_NUM,
   1033     "Verify that concurrent breakpoints, watchpoints and signals are reported "
   1034     "correctly and passed back to SIG_IGN handler");
   1035 THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER,
   1036     THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
   1037     THREAD_CONCURRENT_WATCHPOINT_NUM,
   1038     "Verify that concurrent breakpoints, watchpoints and signals are reported "
   1039     "correctly and passed back to a handler function");
   1040 #endif
   1041 
   1042 #endif /*defined(TWAIT_HAVE_STATUS)*/
   1043 
   1044 #define ATF_TP_ADD_TCS_PTRACE_WAIT_THREADS() \
   1045 	ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); \
   1046 	ATF_TP_ADD_TC(tp, trace_thread_lwpexit); \
   1047 	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); \
   1048 	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); \
   1049 	ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap); \
   1050 	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap); \
   1051 	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap); \
   1052 	ATF_TP_ADD_TC(tp, threads_and_exec); \
   1053 	ATF_TP_ADD_TC(tp, suspend_no_deadlock); \
   1054 	ATF_TP_ADD_TC(tp, resume); \
   1055 	ATF_TP_ADD_TC_HAVE_STATUS(tp, thread_concurrent_signals); \
   1056 	ATF_TP_ADD_TC_HAVE_STATUS(tp, thread_concurrent_signals_sig_ign); \
   1057 	ATF_TP_ADD_TC_HAVE_STATUS(tp, thread_concurrent_signals_handler); \
   1058 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_breakpoints); \
   1059 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_watchpoints); \
   1060 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_bp_wp); \
   1061 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_bp_sig); \
   1062 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_bp_sig_sig_ign); \
   1063 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_bp_sig_handler); \
   1064 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_wp_sig); \
   1065 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_wp_sig_sig_ign); \
   1066 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_wp_sig_handler); \
   1067 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_bp_wp_sig); \
   1068 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_bp_wp_sig_sig_ign); \
   1069 	ATF_TP_ADD_TC_HAVE_STATUS_X86(tp, thread_concurrent_bp_wp_sig_handler);
   1070