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