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