t_ptrace_wait.c revision 1.184
1/* $NetBSD: t_ptrace_wait.c,v 1.184 2020/05/05 00:03:49 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#include <sys/cdefs.h> 30__RCSID("$NetBSD: t_ptrace_wait.c,v 1.184 2020/05/05 00:03:49 kamil Exp $"); 31 32#define __LEGACY_PT_LWPINFO 33 34#include <sys/param.h> 35#include <sys/types.h> 36#include <sys/exec_elf.h> 37#include <sys/mman.h> 38#include <sys/ptrace.h> 39#include <sys/resource.h> 40#include <sys/stat.h> 41#include <sys/syscall.h> 42#include <sys/sysctl.h> 43#include <sys/uio.h> 44#include <sys/wait.h> 45#include <machine/reg.h> 46#include <assert.h> 47#include <elf.h> 48#include <err.h> 49#include <errno.h> 50#include <fcntl.h> 51#include <lwp.h> 52#include <pthread.h> 53#include <sched.h> 54#include <signal.h> 55#include <spawn.h> 56#include <stdint.h> 57#include <stdio.h> 58#include <stdlib.h> 59#include <strings.h> 60#include <time.h> 61#include <unistd.h> 62 63#if defined(__i386__) || defined(__x86_64__) 64#include <cpuid.h> 65#include <x86/cpu_extended_state.h> 66#include <x86/specialreg.h> 67#endif 68 69#include <libelf.h> 70#include <gelf.h> 71 72#include <atf-c.h> 73 74#ifdef ENABLE_TESTS 75 76/* Assumptions in the kernel code that must be kept. */ 77__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) == 78 sizeof(((siginfo_t *)0)->si_pe_report_event)); 79__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 80 sizeof(((siginfo_t *)0)->si_pe_other_pid)); 81__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) == 82 sizeof(((siginfo_t *)0)->si_pe_lwp)); 83__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 84 sizeof(((struct ptrace_state *)0)->pe_lwp)); 85 86#include "h_macros.h" 87 88#include "t_ptrace_wait.h" 89#include "msg.h" 90 91#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 92 strerror(errno)) 93#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 94 "%d(%s) != %d", res, strerror(res), exp) 95 96static int debug = 0; 97 98#define DPRINTF(a, ...) do \ 99 if (debug) \ 100 printf("%s() %d.%d %s:%d " a, \ 101 __func__, getpid(), _lwp_self(), __FILE__, __LINE__, ##__VA_ARGS__); \ 102 while (/*CONSTCOND*/0) 103 104/// ---------------------------------------------------------------------------- 105 106ATF_TC(traceme_pid1_parent); 107ATF_TC_HEAD(traceme_pid1_parent, tc) 108{ 109 atf_tc_set_md_var(tc, "descr", 110 "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 111} 112 113ATF_TC_BODY(traceme_pid1_parent, tc) 114{ 115 struct msg_fds parent_child; 116 int exitval_child1 = 1, exitval_child2 = 2; 117 pid_t child1, child2, wpid; 118 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 119#if defined(TWAIT_HAVE_STATUS) 120 int status; 121#endif 122 123 SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 124 125 DPRINTF("Before forking process PID=%d\n", getpid()); 126 SYSCALL_REQUIRE((child1 = fork()) != -1); 127 if (child1 == 0) { 128 DPRINTF("Before forking process PID=%d\n", getpid()); 129 SYSCALL_REQUIRE((child2 = fork()) != -1); 130 if (child2 != 0) { 131 DPRINTF("Parent process PID=%d, child2's PID=%d\n", 132 getpid(), child2); 133 _exit(exitval_child1); 134 } 135 CHILD_FROM_PARENT("exit child1", parent_child, msg); 136 137 DPRINTF("Assert that our parent is PID1 (initproc)\n"); 138 FORKEE_ASSERT_EQ(getppid(), 1); 139 140 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 141 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 142 SYSCALL_REQUIRE_ERRNO(errno, EPERM); 143 144 CHILD_TO_PARENT("child2 exiting", parent_child, msg); 145 146 _exit(exitval_child2); 147 } 148 DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 149 150 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 151 TWAIT_REQUIRE_SUCCESS( 152 wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 153 154 validate_status_exited(status, exitval_child1); 155 156 DPRINTF("Notify that child1 is dead\n"); 157 PARENT_TO_CHILD("exit child1", parent_child, msg); 158 159 DPRINTF("Wait for exiting of child2\n"); 160 PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 161} 162 163/// ---------------------------------------------------------------------------- 164 165static void 166traceme_vfork_exec(bool masked, bool ignored) 167{ 168 const int sigval = SIGTRAP; 169 pid_t child, wpid; 170#if defined(TWAIT_HAVE_STATUS) 171 int status; 172#endif 173 struct sigaction sa; 174 struct ptrace_siginfo info; 175 sigset_t intmask; 176 struct kinfo_proc2 kp; 177 size_t len = sizeof(kp); 178 179 int name[6]; 180 const size_t namelen = __arraycount(name); 181 ki_sigset_t kp_sigmask; 182 ki_sigset_t kp_sigignore; 183 184 memset(&info, 0, sizeof(info)); 185 186 DPRINTF("Before forking process PID=%d\n", getpid()); 187 SYSCALL_REQUIRE((child = vfork()) != -1); 188 if (child == 0) { 189 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 190 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 191 192 if (masked) { 193 sigemptyset(&intmask); 194 sigaddset(&intmask, sigval); 195 sigprocmask(SIG_BLOCK, &intmask, NULL); 196 } 197 198 if (ignored) { 199 memset(&sa, 0, sizeof(sa)); 200 sa.sa_handler = SIG_IGN; 201 sigemptyset(&sa.sa_mask); 202 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 203 } 204 205 DPRINTF("Before calling execve(2) from child\n"); 206 execlp("/bin/echo", "/bin/echo", NULL); 207 208 /* NOTREACHED */ 209 FORKEE_ASSERTX(0 && "Not reached"); 210 } 211 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 212 213 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 214 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 215 216 validate_status_stopped(status, sigval); 217 218 name[0] = CTL_KERN, 219 name[1] = KERN_PROC2, 220 name[2] = KERN_PROC_PID; 221 name[3] = getpid(); 222 name[4] = sizeof(kp); 223 name[5] = 1; 224 225 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 226 227 if (masked) 228 kp_sigmask = kp.p_sigmask; 229 230 if (ignored) 231 kp_sigignore = kp.p_sigignore; 232 233 name[3] = getpid(); 234 235 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 236 237 if (masked) { 238 DPRINTF("kp_sigmask=" 239 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 240 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 241 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 242 243 DPRINTF("kp.p_sigmask=" 244 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 245 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 246 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 247 248 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 249 sizeof(kp_sigmask))); 250 } 251 252 if (ignored) { 253 DPRINTF("kp_sigignore=" 254 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 255 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 256 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 257 258 DPRINTF("kp.p_sigignore=" 259 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 260 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 261 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 262 263 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 264 sizeof(kp_sigignore))); 265 } 266 267 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 268 SYSCALL_REQUIRE( 269 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 270 271 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 272 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 273 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 274 info.psi_siginfo.si_errno); 275 276 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 277 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 278 279 DPRINTF("Before resuming the child process where it left off and " 280 "without signal to be sent\n"); 281 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 282 283 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 284 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 285 286 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 287 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 288} 289 290#define TRACEME_VFORK_EXEC(test, masked, ignored) \ 291ATF_TC(test); \ 292ATF_TC_HEAD(test, tc) \ 293{ \ 294 atf_tc_set_md_var(tc, "descr", \ 295 "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed " \ 296 "child%s%s", masked ? " with masked signal" : "", \ 297 masked ? " with ignored signal" : ""); \ 298} \ 299 \ 300ATF_TC_BODY(test, tc) \ 301{ \ 302 \ 303 traceme_vfork_exec(masked, ignored); \ 304} 305 306TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false) 307TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false) 308TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true) 309 310/// ---------------------------------------------------------------------------- 311 312#if defined(TWAIT_HAVE_PID) 313static void 314tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 315 bool stopped) 316{ 317 /* 318 * notimeout - disable timeout in await zombie function 319 * unrelated - attach from unrelated tracer reparented to initproc 320 * stopped - attach to a stopped process 321 */ 322 323 struct msg_fds parent_tracee, parent_tracer; 324 const int exitval_tracee = 5; 325 const int exitval_tracer = 10; 326 pid_t tracee, tracer, wpid; 327 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 328#if defined(TWAIT_HAVE_STATUS) 329 int status; 330#endif 331 332 /* 333 * Only a subset of options are supported. 334 */ 335 ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 336 (!notimeout && unrelated && !stopped) || 337 (notimeout && !unrelated && !stopped) || 338 (!notimeout && unrelated && stopped)); 339 340 DPRINTF("Spawn tracee\n"); 341 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 342 tracee = atf_utils_fork(); 343 if (tracee == 0) { 344 if (stopped) { 345 DPRINTF("Stop self PID %d\n", getpid()); 346 raise(SIGSTOP); 347 } 348 349 // Wait for parent to let us exit 350 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 351 _exit(exitval_tracee); 352 } 353 354 DPRINTF("Spawn debugger\n"); 355 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 356 tracer = atf_utils_fork(); 357 if (tracer == 0) { 358 if(unrelated) { 359 /* Fork again and drop parent to reattach to PID 1 */ 360 tracer = atf_utils_fork(); 361 if (tracer != 0) 362 _exit(exitval_tracer); 363 } 364 365 if (stopped) { 366 DPRINTF("Await for a stopped parent PID %d\n", tracee); 367 await_stopped(tracee); 368 } 369 370 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 371 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 372 373 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 374 FORKEE_REQUIRE_SUCCESS( 375 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 376 377 forkee_status_stopped(status, SIGSTOP); 378 379 /* Resume tracee with PT_CONTINUE */ 380 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 381 382 /* Inform parent that tracer has attached to tracee */ 383 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 384 385 /* Wait for parent to tell use that tracee should have exited */ 386 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 387 388 /* Wait for tracee and assert that it exited */ 389 FORKEE_REQUIRE_SUCCESS( 390 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 391 392 forkee_status_exited(status, exitval_tracee); 393 DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 394 395 DPRINTF("Before exiting of the tracer process\n"); 396 _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 397 } 398 399 if (unrelated) { 400 DPRINTF("Wait for the tracer process (direct child) to exit " 401 "calling %s()\n", TWAIT_FNAME); 402 TWAIT_REQUIRE_SUCCESS( 403 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 404 405 validate_status_exited(status, exitval_tracer); 406 407 DPRINTF("Wait for the non-exited tracee process with %s()\n", 408 TWAIT_FNAME); 409 TWAIT_REQUIRE_SUCCESS( 410 wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 411 } 412 413 DPRINTF("Wait for the tracer to attach to the tracee\n"); 414 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 415 416 DPRINTF("Resume the tracee and let it exit\n"); 417 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 418 419 DPRINTF("Detect that tracee is zombie\n"); 420 if (notimeout) 421 await_zombie_raw(tracee, 0); 422 else 423 await_zombie(tracee); 424 425 DPRINTF("Assert that there is no status about tracee %d - " 426 "Tracer must detect zombie first - calling %s()\n", tracee, 427 TWAIT_FNAME); 428 TWAIT_REQUIRE_SUCCESS( 429 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 430 431 if (unrelated) { 432 DPRINTF("Resume the tracer and let it detect exited tracee\n"); 433 PARENT_TO_CHILD("Message 2", parent_tracer, msg); 434 } else { 435 DPRINTF("Tell the tracer child should have exited\n"); 436 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 437 DPRINTF("Wait for tracer to finish its job and exit - calling " 438 "%s()\n", TWAIT_FNAME); 439 440 DPRINTF("Wait from tracer child to complete waiting for " 441 "tracee\n"); 442 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 443 tracer); 444 445 validate_status_exited(status, exitval_tracer); 446 } 447 448 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 449 TWAIT_FNAME); 450 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 451 452 validate_status_exited(status, exitval_tracee); 453 454 msg_close(&parent_tracer); 455 msg_close(&parent_tracee); 456} 457 458ATF_TC(tracer_sees_terminaton_before_the_parent); 459ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 460{ 461 atf_tc_set_md_var(tc, "descr", 462 "Assert that tracer sees process termination before the parent"); 463} 464 465ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 466{ 467 468 tracer_sees_terminaton_before_the_parent_raw(false, false, false); 469} 470 471ATF_TC(tracer_sysctl_lookup_without_duplicates); 472ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 473{ 474 atf_tc_set_md_var(tc, "timeout", "15"); 475 atf_tc_set_md_var(tc, "descr", 476 "Assert that await_zombie() in attach1 always finds a single " 477 "process and no other error is reported"); 478} 479 480ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 481{ 482 time_t start, end; 483 double diff; 484 unsigned long N = 0; 485 486 /* 487 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 488 * This test body isn't specific to this race, however it's just good 489 * enough for this purposes, no need to invent a dedicated code flow. 490 */ 491 492 start = time(NULL); 493 while (true) { 494 DPRINTF("Step: %lu\n", N); 495 tracer_sees_terminaton_before_the_parent_raw(true, false, 496 false); 497 end = time(NULL); 498 diff = difftime(end, start); 499 if (diff >= 5.0) 500 break; 501 ++N; 502 } 503 DPRINTF("Iterations: %lu\n", N); 504} 505 506ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 507ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 508{ 509 atf_tc_set_md_var(tc, "descr", 510 "Assert that tracer sees process termination before the parent"); 511} 512 513ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 514{ 515 516 tracer_sees_terminaton_before_the_parent_raw(false, true, false); 517} 518 519ATF_TC(tracer_attach_to_unrelated_stopped_process); 520ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 521{ 522 atf_tc_set_md_var(tc, "descr", 523 "Assert that tracer can attach to an unrelated stopped process"); 524} 525 526ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 527{ 528 529 tracer_sees_terminaton_before_the_parent_raw(false, true, true); 530} 531#endif 532 533/// ---------------------------------------------------------------------------- 534 535static void 536parent_attach_to_its_child(bool stopped) 537{ 538 struct msg_fds parent_tracee; 539 const int exitval_tracee = 5; 540 pid_t tracee, wpid; 541 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 542#if defined(TWAIT_HAVE_STATUS) 543 int status; 544#endif 545 546 DPRINTF("Spawn tracee\n"); 547 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 548 tracee = atf_utils_fork(); 549 if (tracee == 0) { 550 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 551 DPRINTF("Parent should now attach to tracee\n"); 552 553 if (stopped) { 554 DPRINTF("Stop self PID %d\n", getpid()); 555 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 556 } 557 558 CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 559 /* Wait for message from the parent */ 560 _exit(exitval_tracee); 561 } 562 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 563 564 if (stopped) { 565 DPRINTF("Await for a stopped tracee PID %d\n", tracee); 566 await_stopped(tracee); 567 } 568 569 DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 570 SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 571 572 DPRINTF("Wait for the stopped tracee process with %s()\n", 573 TWAIT_FNAME); 574 TWAIT_REQUIRE_SUCCESS( 575 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 576 577 validate_status_stopped(status, SIGSTOP); 578 579 DPRINTF("Resume tracee with PT_CONTINUE\n"); 580 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 581 582 DPRINTF("Let the tracee exit now\n"); 583 PARENT_TO_CHILD("Message 2", parent_tracee, msg); 584 585 DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 586 TWAIT_REQUIRE_SUCCESS( 587 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 588 589 validate_status_exited(status, exitval_tracee); 590 591 DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 592 TWAIT_REQUIRE_FAILURE(ECHILD, 593 wpid = TWAIT_GENERIC(tracee, &status, 0)); 594 595 msg_close(&parent_tracee); 596} 597 598ATF_TC(parent_attach_to_its_child); 599ATF_TC_HEAD(parent_attach_to_its_child, tc) 600{ 601 atf_tc_set_md_var(tc, "descr", 602 "Assert that tracer parent can PT_ATTACH to its child"); 603} 604 605ATF_TC_BODY(parent_attach_to_its_child, tc) 606{ 607 608 parent_attach_to_its_child(false); 609} 610 611ATF_TC(parent_attach_to_its_stopped_child); 612ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 613{ 614 atf_tc_set_md_var(tc, "descr", 615 "Assert that tracer parent can PT_ATTACH to its stopped child"); 616} 617 618ATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 619{ 620 621 parent_attach_to_its_child(true); 622} 623 624/// ---------------------------------------------------------------------------- 625 626static void 627child_attach_to_its_parent(bool stopped) 628{ 629 struct msg_fds parent_tracee; 630 const int exitval_tracer = 5; 631 pid_t tracer, wpid; 632 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 633#if defined(TWAIT_HAVE_STATUS) 634 int status; 635#endif 636 637 DPRINTF("Spawn tracer\n"); 638 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 639 tracer = atf_utils_fork(); 640 if (tracer == 0) { 641 /* Wait for message from the parent */ 642 CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 643 644 if (stopped) { 645 DPRINTF("Await for a stopped parent PID %d\n", 646 getppid()); 647 await_stopped(getppid()); 648 } 649 650 DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 651 getppid()); 652 FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 653 654 DPRINTF("Wait for the stopped parent process with %s()\n", 655 TWAIT_FNAME); 656 FORKEE_REQUIRE_SUCCESS( 657 wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 658 659 forkee_status_stopped(status, SIGSTOP); 660 661 DPRINTF("Resume parent with PT_DETACH\n"); 662 FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 663 != -1); 664 665 /* Tell parent we are ready */ 666 CHILD_TO_PARENT("Message 1", parent_tracee, msg); 667 668 _exit(exitval_tracer); 669 } 670 671 DPRINTF("Wait for the tracer to become ready\n"); 672 PARENT_TO_CHILD("Message 1", parent_tracee, msg); 673 674 if (stopped) { 675 DPRINTF("Stop self PID %d\n", getpid()); 676 SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 677 } 678 679 DPRINTF("Allow the tracer to exit now\n"); 680 PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 681 682 DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 683 TWAIT_REQUIRE_SUCCESS( 684 wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 685 686 validate_status_exited(status, exitval_tracer); 687 688 DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 689 TWAIT_REQUIRE_FAILURE(ECHILD, 690 wpid = TWAIT_GENERIC(tracer, &status, 0)); 691 692 msg_close(&parent_tracee); 693} 694 695ATF_TC(child_attach_to_its_parent); 696ATF_TC_HEAD(child_attach_to_its_parent, tc) 697{ 698 atf_tc_set_md_var(tc, "descr", 699 "Assert that tracer child can PT_ATTACH to its parent"); 700} 701 702ATF_TC_BODY(child_attach_to_its_parent, tc) 703{ 704 705 child_attach_to_its_parent(false); 706} 707 708ATF_TC(child_attach_to_its_stopped_parent); 709ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 710{ 711 atf_tc_set_md_var(tc, "descr", 712 "Assert that tracer child can PT_ATTACH to its stopped parent"); 713} 714 715ATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 716{ 717 /* 718 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 719 * this causes a pipe (established from atf-run) to be broken. 720 * atf-run uses this mechanism to monitor whether a test is alive. 721 * 722 * As a workaround spawn this test as a subprocess. 723 */ 724 725 const int exitval = 15; 726 pid_t child, wpid; 727#if defined(TWAIT_HAVE_STATUS) 728 int status; 729#endif 730 731 SYSCALL_REQUIRE((child = fork()) != -1); 732 if (child == 0) { 733 child_attach_to_its_parent(true); 734 _exit(exitval); 735 } else { 736 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 737 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 738 739 validate_status_exited(status, exitval); 740 741 DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 742 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 743 } 744} 745 746/// ---------------------------------------------------------------------------- 747 748#if defined(TWAIT_HAVE_PID) 749 750enum tracee_sees_its_original_parent_type { 751 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 752 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 753 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 754}; 755 756static void 757tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 758{ 759 struct msg_fds parent_tracer, parent_tracee; 760 const int exitval_tracee = 5; 761 const int exitval_tracer = 10; 762 pid_t parent, tracee, tracer, wpid; 763 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 764#if defined(TWAIT_HAVE_STATUS) 765 int status; 766#endif 767 /* sysctl(3) - kinfo_proc2 */ 768 int name[CTL_MAXNAME]; 769 struct kinfo_proc2 kp; 770 size_t len = sizeof(kp); 771 unsigned int namelen; 772 773 /* procfs - status */ 774 FILE *fp; 775 struct stat st; 776 const char *fname = "/proc/curproc/status"; 777 char s_executable[MAXPATHLEN]; 778 int s_pid, s_ppid; 779 int rv; 780 781 if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 782 SYSCALL_REQUIRE( 783 (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 784 if (rv != 0) 785 atf_tc_skip("/proc/curproc/status not found"); 786 } 787 788 DPRINTF("Spawn tracee\n"); 789 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 790 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 791 tracee = atf_utils_fork(); 792 if (tracee == 0) { 793 parent = getppid(); 794 795 /* Emit message to the parent */ 796 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 797 CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 798 799 switch (type) { 800 case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 801 FORKEE_ASSERT_EQ(parent, getppid()); 802 break; 803 case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 804 namelen = 0; 805 name[namelen++] = CTL_KERN; 806 name[namelen++] = KERN_PROC2; 807 name[namelen++] = KERN_PROC_PID; 808 name[namelen++] = getpid(); 809 name[namelen++] = len; 810 name[namelen++] = 1; 811 812 FORKEE_ASSERT_EQ( 813 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 814 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 815 break; 816 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 817 /* 818 * Format: 819 * EXECUTABLE PID PPID ... 820 */ 821 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 822 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 823 FORKEE_ASSERT_EQ(fclose(fp), 0); 824 FORKEE_ASSERT_EQ(parent, s_ppid); 825 break; 826 } 827 828 _exit(exitval_tracee); 829 } 830 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 831 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 832 833 DPRINTF("Spawn debugger\n"); 834 tracer = atf_utils_fork(); 835 if (tracer == 0) { 836 /* No IPC to communicate with the child */ 837 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 838 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 839 840 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 841 FORKEE_REQUIRE_SUCCESS( 842 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 843 844 forkee_status_stopped(status, SIGSTOP); 845 846 /* Resume tracee with PT_CONTINUE */ 847 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 848 849 /* Inform parent that tracer has attached to tracee */ 850 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 851 852 /* Wait for parent to tell use that tracee should have exited */ 853 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 854 855 /* Wait for tracee and assert that it exited */ 856 FORKEE_REQUIRE_SUCCESS( 857 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 858 859 forkee_status_exited(status, exitval_tracee); 860 861 DPRINTF("Before exiting of the tracer process\n"); 862 _exit(exitval_tracer); 863 } 864 865 DPRINTF("Wait for the tracer to attach to the tracee\n"); 866 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 867 868 DPRINTF("Resume the tracee and let it exit\n"); 869 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 870 871 DPRINTF("Detect that tracee is zombie\n"); 872 await_zombie(tracee); 873 874 DPRINTF("Assert that there is no status about tracee - " 875 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 876 TWAIT_REQUIRE_SUCCESS( 877 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 878 879 DPRINTF("Tell the tracer child should have exited\n"); 880 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 881 882 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 883 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 884 tracer); 885 886 validate_status_exited(status, exitval_tracer); 887 888 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 889 TWAIT_FNAME); 890 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 891 tracee); 892 893 validate_status_exited(status, exitval_tracee); 894 895 msg_close(&parent_tracer); 896 msg_close(&parent_tracee); 897} 898 899#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 900ATF_TC(test); \ 901ATF_TC_HEAD(test, tc) \ 902{ \ 903 atf_tc_set_md_var(tc, "descr", \ 904 "Assert that tracee sees its original parent when being traced " \ 905 "(check " descr ")"); \ 906} \ 907 \ 908ATF_TC_BODY(test, tc) \ 909{ \ 910 \ 911 tracee_sees_its_original_parent(type); \ 912} 913 914TRACEE_SEES_ITS_ORIGINAL_PARENT( 915 tracee_sees_its_original_parent_getppid, 916 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 917 "getppid(2)"); 918TRACEE_SEES_ITS_ORIGINAL_PARENT( 919 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 920 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 921 "sysctl(3) and kinfo_proc2"); 922TRACEE_SEES_ITS_ORIGINAL_PARENT( 923 tracee_sees_its_original_parent_procfs_status, 924 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 925 "the status file in procfs"); 926#endif 927 928/// ---------------------------------------------------------------------------- 929 930static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG}; 931 932static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER; 933static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER; 934static volatile size_t lwpinfo_thread_done; 935 936static void * 937lwpinfo_thread(void *arg) 938{ 939 sigset_t s; 940 volatile void **tcb; 941 942 tcb = (volatile void **)arg; 943 944 *tcb = _lwp_getprivate(); 945 DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self()); 946 947 pthread_setname_np(pthread_self(), "thread %d", 948 (void *)(intptr_t)_lwp_self()); 949 950 sigemptyset(&s); 951 pthread_mutex_lock(&lwpinfo_thread_mtx); 952 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 953 lwpinfo_thread_done++; 954 pthread_sigmask(SIG_BLOCK, &s, NULL); 955 pthread_cond_signal(&lwpinfo_thread_cnd); 956 pthread_mutex_unlock(&lwpinfo_thread_mtx); 957 958 return infinite_thread(NULL); 959} 960 961static void 962traceme_lwpinfo(const size_t threads, const char *iter) 963{ 964 const int sigval = SIGSTOP; 965 const int sigval2 = SIGINT; 966 pid_t child, wpid; 967#if defined(TWAIT_HAVE_STATUS) 968 int status; 969#endif 970 struct ptrace_lwpinfo lwp = {0, 0}; 971 struct ptrace_lwpstatus lwpstatus = {0}; 972 struct ptrace_siginfo info; 973 void *private; 974 char *name; 975 char namebuf[PL_LNAMELEN]; 976 volatile void *tcb[4]; 977 bool found; 978 sigset_t s; 979 980 /* Maximum number of supported threads in this test */ 981 pthread_t t[__arraycount(tcb) - 1]; 982 size_t n, m; 983 int rv; 984 size_t bytes_read; 985 986 struct ptrace_io_desc io; 987 sigset_t sigmask; 988 989 ATF_REQUIRE(__arraycount(t) >= threads); 990 memset(tcb, 0, sizeof(tcb)); 991 992 DPRINTF("Before forking process PID=%d\n", getpid()); 993 SYSCALL_REQUIRE((child = fork()) != -1); 994 if (child == 0) { 995 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 996 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 997 998 tcb[0] = _lwp_getprivate(); 999 DPRINTF("Storing tcb[0] = %p\n", tcb[0]); 1000 1001 pthread_setname_np(pthread_self(), "thread %d", 1002 (void *)(intptr_t)_lwp_self()); 1003 1004 sigemptyset(&s); 1005 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 1006 pthread_sigmask(SIG_BLOCK, &s, NULL); 1007 1008 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1009 FORKEE_ASSERT(raise(sigval) == 0); 1010 1011 for (n = 0; n < threads; n++) { 1012 rv = pthread_create(&t[n], NULL, lwpinfo_thread, 1013 &tcb[n + 1]); 1014 FORKEE_ASSERT(rv == 0); 1015 } 1016 1017 pthread_mutex_lock(&lwpinfo_thread_mtx); 1018 while (lwpinfo_thread_done < threads) { 1019 pthread_cond_wait(&lwpinfo_thread_cnd, 1020 &lwpinfo_thread_mtx); 1021 } 1022 pthread_mutex_unlock(&lwpinfo_thread_mtx); 1023 1024 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 1025 FORKEE_ASSERT(raise(sigval2) == 0); 1026 1027 /* NOTREACHED */ 1028 FORKEE_ASSERTX(0 && "Not reached"); 1029 } 1030 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1031 1032 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1033 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1034 1035 validate_status_stopped(status, sigval); 1036 1037 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 1038 SYSCALL_REQUIRE( 1039 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1040 1041 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1042 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1043 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1044 info.psi_siginfo.si_errno); 1045 1046 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1047 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1048 1049 if (strstr(iter, "LWPINFO") != NULL) { 1050 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 1051 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 1052 != -1); 1053 1054 DPRINTF("Assert that there exists a single thread only\n"); 1055 ATF_REQUIRE(lwp.pl_lwpid > 0); 1056 1057 DPRINTF("Assert that lwp thread %d received event " 1058 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 1059 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 1060 1061 if (strstr(iter, "LWPSTATUS") != NULL) { 1062 DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS " 1063 "for child\n"); 1064 lwpstatus.pl_lwpid = lwp.pl_lwpid; 1065 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus, 1066 sizeof(lwpstatus)) != -1); 1067 } 1068 1069 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 1070 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 1071 != -1); 1072 1073 DPRINTF("Assert that there exists a single thread only\n"); 1074 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 1075 } else { 1076 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 1077 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 1078 sizeof(lwpstatus)) != -1); 1079 1080 DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid); 1081 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 1082 1083 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 1084 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 1085 sizeof(lwpstatus)) != -1); 1086 1087 DPRINTF("Assert that there exists a single thread only\n"); 1088 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 1089 } 1090 1091 DPRINTF("Before resuming the child process where it left off and " 1092 "without signal to be sent\n"); 1093 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1094 1095 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1096 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1097 1098 validate_status_stopped(status, sigval2); 1099 1100 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 1101 SYSCALL_REQUIRE( 1102 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1103 1104 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1105 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1106 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1107 info.psi_siginfo.si_errno); 1108 1109 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 1110 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1111 1112 memset(&lwp, 0, sizeof(lwp)); 1113 memset(&lwpstatus, 0, sizeof(lwpstatus)); 1114 1115 memset(&io, 0, sizeof(io)); 1116 1117 bytes_read = 0; 1118 io.piod_op = PIOD_READ_D; 1119 io.piod_len = sizeof(tcb); 1120 1121 do { 1122 io.piod_addr = (char *)&tcb + bytes_read; 1123 io.piod_offs = io.piod_addr; 1124 1125 rv = ptrace(PT_IO, child, &io, sizeof(io)); 1126 ATF_REQUIRE(rv != -1 && io.piod_len != 0); 1127 1128 bytes_read += io.piod_len; 1129 io.piod_len = sizeof(tcb) - bytes_read; 1130 } while (bytes_read < sizeof(tcb)); 1131 1132 for (n = 0; n <= threads; n++) { 1133 if (strstr(iter, "LWPINFO") != NULL) { 1134 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1135 "child\n"); 1136 SYSCALL_REQUIRE( 1137 ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 1138 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1139 1140 DPRINTF("Assert that the thread exists\n"); 1141 ATF_REQUIRE(lwp.pl_lwpid > 0); 1142 1143 DPRINTF("Assert that lwp thread %d received expected " 1144 "event\n", lwp.pl_lwpid); 1145 FORKEE_ASSERT_EQ(lwp.pl_event, 1146 info.psi_lwpid == lwp.pl_lwpid ? 1147 PL_EVENT_SIGNAL : PL_EVENT_NONE); 1148 1149 if (strstr(iter, "LWPSTATUS") != NULL) { 1150 DPRINTF("Before calling ptrace(2) with " 1151 "PT_LWPSTATUS for child\n"); 1152 lwpstatus.pl_lwpid = lwp.pl_lwpid; 1153 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, 1154 &lwpstatus, sizeof(lwpstatus)) != -1); 1155 1156 goto check_lwpstatus; 1157 } 1158 } else { 1159 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for " 1160 "child\n"); 1161 SYSCALL_REQUIRE( 1162 ptrace(PT_LWPNEXT, child, &lwpstatus, 1163 sizeof(lwpstatus)) != -1); 1164 DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid); 1165 1166 DPRINTF("Assert that the thread exists\n"); 1167 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 1168 1169 check_lwpstatus: 1170 1171 if (strstr(iter, "pl_sigmask") != NULL) { 1172 sigmask = lwpstatus.pl_sigmask; 1173 1174 DPRINTF("Retrieved sigmask: " 1175 "%02x%02x%02x%02x\n", 1176 sigmask.__bits[0], sigmask.__bits[1], 1177 sigmask.__bits[2], sigmask.__bits[3]); 1178 1179 found = false; 1180 for (m = 0; 1181 m < __arraycount(lwpinfo_thread_sigmask); 1182 m++) { 1183 if (sigismember(&sigmask, 1184 lwpinfo_thread_sigmask[m])) { 1185 found = true; 1186 lwpinfo_thread_sigmask[m] = 0; 1187 break; 1188 } 1189 } 1190 ATF_REQUIRE(found == true); 1191 } else if (strstr(iter, "pl_name") != NULL) { 1192 name = lwpstatus.pl_name; 1193 1194 DPRINTF("Retrieved thread name: " 1195 "%s\n", name); 1196 1197 snprintf(namebuf, sizeof namebuf, "thread %d", 1198 lwpstatus.pl_lwpid); 1199 1200 ATF_REQUIRE(strcmp(name, namebuf) == 0); 1201 } else if (strstr(iter, "pl_private") != NULL) { 1202 private = lwpstatus.pl_private; 1203 1204 DPRINTF("Retrieved thread private pointer: " 1205 "%p\n", private); 1206 1207 found = false; 1208 for (m = 0; m < __arraycount(tcb); m++) { 1209 DPRINTF("Comparing %p and %p\n", 1210 private, tcb[m]); 1211 if (private == tcb[m]) { 1212 found = true; 1213 break; 1214 } 1215 } 1216 ATF_REQUIRE(found == true); 1217 } 1218 } 1219 } 1220 1221 if (strstr(iter, "LWPINFO") != NULL) { 1222 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1223 "child\n"); 1224 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 1225 != -1); 1226 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1227 1228 DPRINTF("Assert that there are no more threads\n"); 1229 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 1230 } else { 1231 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 1232 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 1233 sizeof(lwpstatus)) != -1); 1234 1235 DPRINTF("Assert that there exists a single thread only\n"); 1236 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 1237 } 1238 1239 DPRINTF("Before resuming the child process where it left off and " 1240 "without signal to be sent\n"); 1241 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 1242 1243 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1244 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1245 1246 validate_status_signaled(status, SIGKILL, 0); 1247 1248 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1249 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1250} 1251 1252#define TRACEME_LWPINFO(test, threads, iter) \ 1253ATF_TC(test); \ 1254ATF_TC_HEAD(test, tc) \ 1255{ \ 1256 atf_tc_set_md_var(tc, "descr", \ 1257 "Verify " iter " with the child with " #threads \ 1258 " spawned extra threads"); \ 1259} \ 1260 \ 1261ATF_TC_BODY(test, tc) \ 1262{ \ 1263 \ 1264 traceme_lwpinfo(threads, iter); \ 1265} 1266 1267TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO") 1268TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO") 1269TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO") 1270TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO") 1271 1272TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS") 1273TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS") 1274TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS") 1275TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS") 1276 1277TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0, 1278 "LWPINFO+LWPSTATUS+pl_sigmask") 1279TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1, 1280 "LWPINFO+LWPSTATUS+pl_sigmask") 1281TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2, 1282 "LWPINFO+LWPSTATUS+pl_sigmask") 1283TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3, 1284 "LWPINFO+LWPSTATUS+pl_sigmask") 1285 1286TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0, 1287 "LWPINFO+LWPSTATUS+pl_name") 1288TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1, 1289 "LWPINFO+LWPSTATUS+pl_name") 1290TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2, 1291 "LWPINFO+LWPSTATUS+pl_name") 1292TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3, 1293 "LWPINFO+LWPSTATUS+pl_name") 1294 1295TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0, 1296 "LWPINFO+LWPSTATUS+pl_private") 1297TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1, 1298 "LWPINFO+LWPSTATUS+pl_private") 1299TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2, 1300 "LWPINFO+LWPSTATUS+pl_private") 1301TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3, 1302 "LWPINFO+LWPSTATUS+pl_private") 1303 1304TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT") 1305TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT") 1306TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT") 1307TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT") 1308 1309TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask") 1310TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask") 1311TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask") 1312TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask") 1313 1314TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name") 1315TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name") 1316TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name") 1317TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name") 1318 1319TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private") 1320TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private") 1321TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private") 1322TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private") 1323 1324/// ---------------------------------------------------------------------------- 1325 1326#if defined(TWAIT_HAVE_PID) 1327static void 1328attach_lwpinfo(const int threads) 1329{ 1330 const int sigval = SIGINT; 1331 struct msg_fds parent_tracee, parent_tracer; 1332 const int exitval_tracer = 10; 1333 pid_t tracee, tracer, wpid; 1334 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1335#if defined(TWAIT_HAVE_STATUS) 1336 int status; 1337#endif 1338 struct ptrace_lwpinfo lwp = {0, 0}; 1339 struct ptrace_siginfo info; 1340 1341 /* Maximum number of supported threads in this test */ 1342 pthread_t t[3]; 1343 int n, rv; 1344 1345 DPRINTF("Spawn tracee\n"); 1346 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1347 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 1348 tracee = atf_utils_fork(); 1349 if (tracee == 0) { 1350 /* Wait for message from the parent */ 1351 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 1352 1353 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 1354 1355 for (n = 0; n < threads; n++) { 1356 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 1357 FORKEE_ASSERT(rv == 0); 1358 } 1359 1360 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 1361 1362 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1363 FORKEE_ASSERT(raise(sigval) == 0); 1364 1365 /* NOTREACHED */ 1366 FORKEE_ASSERTX(0 && "Not reached"); 1367 } 1368 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 1369 1370 DPRINTF("Spawn debugger\n"); 1371 tracer = atf_utils_fork(); 1372 if (tracer == 0) { 1373 /* No IPC to communicate with the child */ 1374 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 1375 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 1376 1377 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 1378 FORKEE_REQUIRE_SUCCESS( 1379 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1380 1381 forkee_status_stopped(status, SIGSTOP); 1382 1383 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1384 "tracee"); 1385 FORKEE_ASSERT( 1386 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1387 1388 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1389 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1390 "si_errno=%#x\n", 1391 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1392 info.psi_siginfo.si_errno); 1393 1394 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 1395 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 1396 1397 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 1398 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 1399 != -1); 1400 1401 DPRINTF("Assert that there exists a thread\n"); 1402 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 1403 1404 DPRINTF("Assert that lwp thread %d received event " 1405 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 1406 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 1407 1408 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1409 "tracee\n"); 1410 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 1411 != -1); 1412 1413 DPRINTF("Assert that there are no more lwp threads in " 1414 "tracee\n"); 1415 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 1416 1417 /* Resume tracee with PT_CONTINUE */ 1418 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1419 1420 /* Inform parent that tracer has attached to tracee */ 1421 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 1422 1423 /* Wait for parent */ 1424 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 1425 1426 /* Wait for tracee and assert that it raised a signal */ 1427 FORKEE_REQUIRE_SUCCESS( 1428 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1429 1430 forkee_status_stopped(status, SIGINT); 1431 1432 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1433 "child"); 1434 FORKEE_ASSERT( 1435 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1436 1437 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1438 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1439 "si_errno=%#x\n", 1440 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1441 info.psi_siginfo.si_errno); 1442 1443 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 1444 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 1445 1446 memset(&lwp, 0, sizeof(lwp)); 1447 1448 for (n = 0; n <= threads; n++) { 1449 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1450 "child\n"); 1451 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 1452 sizeof(lwp)) != -1); 1453 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1454 1455 DPRINTF("Assert that the thread exists\n"); 1456 FORKEE_ASSERT(lwp.pl_lwpid > 0); 1457 1458 DPRINTF("Assert that lwp thread %d received expected " 1459 "event\n", lwp.pl_lwpid); 1460 FORKEE_ASSERT_EQ(lwp.pl_event, 1461 info.psi_lwpid == lwp.pl_lwpid ? 1462 PL_EVENT_SIGNAL : PL_EVENT_NONE); 1463 } 1464 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1465 "tracee\n"); 1466 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 1467 != -1); 1468 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1469 1470 DPRINTF("Assert that there are no more threads\n"); 1471 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 1472 1473 DPRINTF("Before resuming the child process where it left off " 1474 "and without signal to be sent\n"); 1475 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 1476 != -1); 1477 1478 /* Wait for tracee and assert that it exited */ 1479 FORKEE_REQUIRE_SUCCESS( 1480 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1481 1482 forkee_status_signaled(status, SIGKILL, 0); 1483 1484 DPRINTF("Before exiting of the tracer process\n"); 1485 _exit(exitval_tracer); 1486 } 1487 1488 DPRINTF("Wait for the tracer to attach to the tracee\n"); 1489 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 1490 1491 DPRINTF("Resume the tracee and spawn threads\n"); 1492 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 1493 1494 DPRINTF("Resume the tracee and let it exit\n"); 1495 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 1496 1497 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 1498 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 1499 1500 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 1501 TWAIT_FNAME); 1502 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 1503 tracer); 1504 1505 validate_status_exited(status, exitval_tracer); 1506 1507 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 1508 TWAIT_FNAME); 1509 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 1510 tracee); 1511 1512 validate_status_signaled(status, SIGKILL, 0); 1513 1514 msg_close(&parent_tracer); 1515 msg_close(&parent_tracee); 1516} 1517 1518#define ATTACH_LWPINFO(test, threads) \ 1519ATF_TC(test); \ 1520ATF_TC_HEAD(test, tc) \ 1521{ \ 1522 atf_tc_set_md_var(tc, "descr", \ 1523 "Verify LWPINFO with the child with " #threads \ 1524 " spawned extra threads (tracer is not the original " \ 1525 "parent)"); \ 1526} \ 1527 \ 1528ATF_TC_BODY(test, tc) \ 1529{ \ 1530 \ 1531 attach_lwpinfo(threads); \ 1532} 1533 1534ATTACH_LWPINFO(attach_lwpinfo0, 0) 1535ATTACH_LWPINFO(attach_lwpinfo1, 1) 1536ATTACH_LWPINFO(attach_lwpinfo2, 2) 1537ATTACH_LWPINFO(attach_lwpinfo3, 3) 1538#endif 1539 1540/// ---------------------------------------------------------------------------- 1541 1542static void 1543ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 1544{ 1545 const int exitval = 5; 1546 const int sigval = SIGINT; 1547 const int sigfaked = SIGTRAP; 1548 const int sicodefaked = TRAP_BRKPT; 1549 pid_t child, wpid; 1550 struct sigaction sa; 1551#if defined(TWAIT_HAVE_STATUS) 1552 int status; 1553#endif 1554 struct ptrace_siginfo info; 1555 memset(&info, 0, sizeof(info)); 1556 1557 DPRINTF("Before forking process PID=%d\n", getpid()); 1558 SYSCALL_REQUIRE((child = fork()) != -1); 1559 if (child == 0) { 1560 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1561 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1562 1563 sa.sa_sigaction = sah; 1564 sa.sa_flags = SA_SIGINFO; 1565 sigemptyset(&sa.sa_mask); 1566 1567 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 1568 != -1); 1569 1570 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1571 FORKEE_ASSERT(raise(sigval) == 0); 1572 1573 FORKEE_ASSERT_EQ(*signal_caught, 1); 1574 1575 DPRINTF("Before exiting of the child process\n"); 1576 _exit(exitval); 1577 } 1578 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1579 1580 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1581 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1582 1583 validate_status_stopped(status, sigval); 1584 1585 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1586 SYSCALL_REQUIRE( 1587 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1588 1589 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1590 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1591 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1592 info.psi_siginfo.si_errno); 1593 1594 if (faked) { 1595 DPRINTF("Before setting new faked signal to signo=%d " 1596 "si_code=%d\n", sigfaked, sicodefaked); 1597 info.psi_siginfo.si_signo = sigfaked; 1598 info.psi_siginfo.si_code = sicodefaked; 1599 } 1600 1601 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 1602 SYSCALL_REQUIRE( 1603 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 1604 1605 if (faked) { 1606 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1607 "child\n"); 1608 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1609 sizeof(info)) != -1); 1610 1611 DPRINTF("Before checking siginfo_t\n"); 1612 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 1613 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 1614 } 1615 1616 DPRINTF("Before resuming the child process where it left off and " 1617 "without signal to be sent\n"); 1618 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 1619 faked ? sigfaked : sigval) != -1); 1620 1621 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1622 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1623 1624 validate_status_exited(status, exitval); 1625 1626 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1627 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1628} 1629 1630#define PTRACE_SIGINFO(test, faked) \ 1631ATF_TC(test); \ 1632ATF_TC_HEAD(test, tc) \ 1633{ \ 1634 atf_tc_set_md_var(tc, "descr", \ 1635 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 1636 "with%s setting signal to new value", faked ? "" : "out"); \ 1637} \ 1638 \ 1639static int test##_caught = 0; \ 1640 \ 1641static void \ 1642test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 1643{ \ 1644 if (faked) { \ 1645 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 1646 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 1647 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 1648 } else { \ 1649 FORKEE_ASSERT_EQ(sig, SIGINT); \ 1650 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 1651 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 1652 } \ 1653 \ 1654 ++ test##_caught; \ 1655} \ 1656 \ 1657ATF_TC_BODY(test, tc) \ 1658{ \ 1659 \ 1660 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 1661} 1662 1663PTRACE_SIGINFO(siginfo_set_unmodified, false) 1664PTRACE_SIGINFO(siginfo_set_faked, true) 1665 1666/// ---------------------------------------------------------------------------- 1667 1668static void 1669traceme_exec(bool masked, bool ignored) 1670{ 1671 const int sigval = SIGTRAP; 1672 pid_t child, wpid; 1673#if defined(TWAIT_HAVE_STATUS) 1674 int status; 1675#endif 1676 struct sigaction sa; 1677 struct ptrace_siginfo info; 1678 sigset_t intmask; 1679 struct kinfo_proc2 kp; 1680 size_t len = sizeof(kp); 1681 1682 int name[6]; 1683 const size_t namelen = __arraycount(name); 1684 ki_sigset_t kp_sigmask; 1685 ki_sigset_t kp_sigignore; 1686 1687 memset(&info, 0, sizeof(info)); 1688 1689 DPRINTF("Before forking process PID=%d\n", getpid()); 1690 SYSCALL_REQUIRE((child = fork()) != -1); 1691 if (child == 0) { 1692 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1693 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1694 1695 if (masked) { 1696 sigemptyset(&intmask); 1697 sigaddset(&intmask, sigval); 1698 sigprocmask(SIG_BLOCK, &intmask, NULL); 1699 } 1700 1701 if (ignored) { 1702 memset(&sa, 0, sizeof(sa)); 1703 sa.sa_handler = SIG_IGN; 1704 sigemptyset(&sa.sa_mask); 1705 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 1706 } 1707 1708 DPRINTF("Before calling execve(2) from child\n"); 1709 execlp("/bin/echo", "/bin/echo", NULL); 1710 1711 FORKEE_ASSERT(0 && "Not reached"); 1712 } 1713 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1714 1715 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1716 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1717 1718 validate_status_stopped(status, sigval); 1719 1720 name[0] = CTL_KERN, 1721 name[1] = KERN_PROC2, 1722 name[2] = KERN_PROC_PID; 1723 name[3] = getpid(); 1724 name[4] = sizeof(kp); 1725 name[5] = 1; 1726 1727 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1728 1729 if (masked) 1730 kp_sigmask = kp.p_sigmask; 1731 1732 if (ignored) 1733 kp_sigignore = kp.p_sigignore; 1734 1735 name[3] = getpid(); 1736 1737 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1738 1739 if (masked) { 1740 DPRINTF("kp_sigmask=" 1741 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1742 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1743 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1744 1745 DPRINTF("kp.p_sigmask=" 1746 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1747 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1748 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1749 1750 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 1751 sizeof(kp_sigmask))); 1752 } 1753 1754 if (ignored) { 1755 DPRINTF("kp_sigignore=" 1756 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1757 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1758 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1759 1760 DPRINTF("kp.p_sigignore=" 1761 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1762 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1763 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1764 1765 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 1766 sizeof(kp_sigignore))); 1767 } 1768 1769 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1770 SYSCALL_REQUIRE( 1771 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1772 1773 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1774 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1775 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1776 info.psi_siginfo.si_errno); 1777 1778 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1779 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1780 1781 DPRINTF("Before resuming the child process where it left off and " 1782 "without signal to be sent\n"); 1783 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1784 1785 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1786 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1787 1788 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1789 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1790} 1791 1792#define TRACEME_EXEC(test, masked, ignored) \ 1793ATF_TC(test); \ 1794ATF_TC_HEAD(test, tc) \ 1795{ \ 1796 atf_tc_set_md_var(tc, "descr", \ 1797 "Detect SIGTRAP TRAP_EXEC from " \ 1798 "child%s%s", masked ? " with masked signal" : "", \ 1799 masked ? " with ignored signal" : ""); \ 1800} \ 1801 \ 1802ATF_TC_BODY(test, tc) \ 1803{ \ 1804 \ 1805 traceme_exec(masked, ignored); \ 1806} 1807 1808TRACEME_EXEC(traceme_exec, false, false) 1809TRACEME_EXEC(traceme_signalmasked_exec, true, false) 1810TRACEME_EXEC(traceme_signalignored_exec, false, true) 1811 1812/// ---------------------------------------------------------------------------- 1813 1814#define TRACE_THREADS_NUM 100 1815 1816static volatile int done; 1817pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 1818 1819static void * 1820trace_threads_cb(void *arg __unused) 1821{ 1822 1823 pthread_mutex_lock(&trace_threads_mtx); 1824 done++; 1825 pthread_mutex_unlock(&trace_threads_mtx); 1826 1827 while (done < TRACE_THREADS_NUM) 1828 sched_yield(); 1829 1830 return NULL; 1831} 1832 1833static void 1834trace_threads(bool trace_create, bool trace_exit, bool masked) 1835{ 1836 const int sigval = SIGSTOP; 1837 pid_t child, wpid; 1838#if defined(TWAIT_HAVE_STATUS) 1839 int status; 1840#endif 1841 ptrace_state_t state; 1842 const int slen = sizeof(state); 1843 ptrace_event_t event; 1844 const int elen = sizeof(event); 1845 struct ptrace_siginfo info; 1846 1847 sigset_t intmask; 1848 1849 pthread_t t[TRACE_THREADS_NUM]; 1850 int rv; 1851 size_t n; 1852 lwpid_t lid; 1853 1854 /* Track created and exited threads */ 1855 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 1856 1857 DPRINTF("Before forking process PID=%d\n", getpid()); 1858 SYSCALL_REQUIRE((child = fork()) != -1); 1859 if (child == 0) { 1860 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1861 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1862 1863 if (masked) { 1864 sigemptyset(&intmask); 1865 sigaddset(&intmask, SIGTRAP); 1866 sigprocmask(SIG_BLOCK, &intmask, NULL); 1867 } 1868 1869 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1870 FORKEE_ASSERT(raise(sigval) == 0); 1871 1872 for (n = 0; n < __arraycount(t); n++) { 1873 rv = pthread_create(&t[n], NULL, trace_threads_cb, 1874 NULL); 1875 FORKEE_ASSERT(rv == 0); 1876 } 1877 1878 for (n = 0; n < __arraycount(t); n++) { 1879 rv = pthread_join(t[n], NULL); 1880 FORKEE_ASSERT(rv == 0); 1881 } 1882 1883 /* 1884 * There is race between _exit() and pthread_join() detaching 1885 * a thread. For simplicity kill the process after detecting 1886 * LWP events. 1887 */ 1888 while (true) 1889 continue; 1890 1891 FORKEE_ASSERT(0 && "Not reached"); 1892 } 1893 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1894 1895 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1896 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1897 1898 validate_status_stopped(status, sigval); 1899 1900 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1901 SYSCALL_REQUIRE( 1902 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1903 1904 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1905 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1906 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1907 info.psi_siginfo.si_errno); 1908 1909 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1910 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1911 1912 DPRINTF("Set LWP event mask for the child %d\n", child); 1913 memset(&event, 0, sizeof(event)); 1914 if (trace_create) 1915 event.pe_set_event |= PTRACE_LWP_CREATE; 1916 if (trace_exit) 1917 event.pe_set_event |= PTRACE_LWP_EXIT; 1918 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1919 1920 DPRINTF("Before resuming the child process where it left off and " 1921 "without signal to be sent\n"); 1922 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1923 1924 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 1925 DPRINTF("Before calling %s() for the child - expected stopped " 1926 "SIGTRAP\n", TWAIT_FNAME); 1927 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1928 child); 1929 1930 validate_status_stopped(status, SIGTRAP); 1931 1932 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1933 "child\n"); 1934 SYSCALL_REQUIRE( 1935 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1936 1937 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1938 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1939 "si_errno=%#x\n", 1940 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1941 info.psi_siginfo.si_errno); 1942 1943 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1944 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 1945 1946 SYSCALL_REQUIRE( 1947 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1948 1949 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 1950 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 1951 1952 lid = state.pe_lwp; 1953 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 1954 1955 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 1956 1957 DPRINTF("Before resuming the child process where it left off " 1958 "and without signal to be sent\n"); 1959 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1960 } 1961 1962 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 1963 DPRINTF("Before calling %s() for the child - expected stopped " 1964 "SIGTRAP\n", TWAIT_FNAME); 1965 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1966 child); 1967 1968 validate_status_stopped(status, SIGTRAP); 1969 1970 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1971 "child\n"); 1972 SYSCALL_REQUIRE( 1973 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1974 1975 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1976 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1977 "si_errno=%#x\n", 1978 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1979 info.psi_siginfo.si_errno); 1980 1981 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1982 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 1983 1984 SYSCALL_REQUIRE( 1985 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1986 1987 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 1988 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 1989 1990 lid = state.pe_lwp; 1991 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 1992 1993 if (trace_create) { 1994 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 1995 ATF_REQUIRE_EQ(*count, 1); 1996 *count = 0; 1997 } 1998 1999 DPRINTF("Before resuming the child process where it left off " 2000 "and without signal to be sent\n"); 2001 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2002 } 2003 2004 kill(child, SIGKILL); 2005 2006 DPRINTF("Before calling %s() for the child - expected exited\n", 2007 TWAIT_FNAME); 2008 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2009 2010 validate_status_signaled(status, SIGKILL, 0); 2011 2012 DPRINTF("Before calling %s() for the child - expected no process\n", 2013 TWAIT_FNAME); 2014 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2015} 2016 2017#define TRACE_THREADS(test, trace_create, trace_exit, mask) \ 2018ATF_TC(test); \ 2019ATF_TC_HEAD(test, tc) \ 2020{ \ 2021 atf_tc_set_md_var(tc, "descr", \ 2022 "Verify spawning threads with%s tracing LWP create and" \ 2023 "with%s tracing LWP exit", trace_create ? "" : "out", \ 2024 trace_exit ? "" : "out"); \ 2025} \ 2026 \ 2027ATF_TC_BODY(test, tc) \ 2028{ \ 2029 \ 2030 trace_threads(trace_create, trace_exit, mask); \ 2031} 2032 2033TRACE_THREADS(trace_thread_nolwpevents, false, false, false) 2034TRACE_THREADS(trace_thread_lwpexit, false, true, false) 2035TRACE_THREADS(trace_thread_lwpcreate, true, false, false) 2036TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false) 2037 2038TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true) 2039TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true) 2040TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true) 2041 2042/// ---------------------------------------------------------------------------- 2043 2044static void * 2045thread_and_exec_thread_cb(void *arg __unused) 2046{ 2047 2048 execlp("/bin/echo", "/bin/echo", NULL); 2049 2050 abort(); 2051} 2052 2053static void 2054threads_and_exec(void) 2055{ 2056 const int sigval = SIGSTOP; 2057 pid_t child, wpid; 2058#if defined(TWAIT_HAVE_STATUS) 2059 int status; 2060#endif 2061 ptrace_state_t state; 2062 const int slen = sizeof(state); 2063 ptrace_event_t event; 2064 const int elen = sizeof(event); 2065 struct ptrace_siginfo info; 2066 2067 pthread_t t; 2068 lwpid_t lid; 2069 2070 DPRINTF("Before forking process PID=%d\n", getpid()); 2071 SYSCALL_REQUIRE((child = fork()) != -1); 2072 if (child == 0) { 2073 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2074 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2075 2076 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2077 FORKEE_ASSERT(raise(sigval) == 0); 2078 2079 FORKEE_ASSERT(pthread_create(&t, NULL, 2080 thread_and_exec_thread_cb, NULL) == 0); 2081 2082 for (;;) 2083 continue; 2084 2085 FORKEE_ASSERT(0 && "Not reached"); 2086 } 2087 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2088 2089 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2090 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2091 2092 validate_status_stopped(status, sigval); 2093 2094 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 2095 SYSCALL_REQUIRE( 2096 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2097 2098 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2099 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 2100 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2101 info.psi_siginfo.si_errno); 2102 2103 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 2104 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2105 2106 DPRINTF("Set LWP event mask for the child %d\n", child); 2107 memset(&event, 0, sizeof(event)); 2108 event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; 2109 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 2110 2111 DPRINTF("Before resuming the child process where it left off and " 2112 "without signal to be sent\n"); 2113 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2114 2115 DPRINTF("Before calling %s() for the child - expected stopped " 2116 "SIGTRAP\n", TWAIT_FNAME); 2117 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2118 child); 2119 2120 validate_status_stopped(status, SIGTRAP); 2121 2122 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2123 "child\n"); 2124 SYSCALL_REQUIRE( 2125 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2126 2127 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2128 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2129 "si_errno=%#x\n", 2130 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2131 info.psi_siginfo.si_errno); 2132 2133 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2134 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 2135 2136 SYSCALL_REQUIRE( 2137 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2138 2139 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 2140 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 2141 2142 lid = state.pe_lwp; 2143 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 2144 2145 DPRINTF("Before resuming the child process where it left off " 2146 "and without signal to be sent\n"); 2147 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2148 2149 DPRINTF("Before calling %s() for the child - expected stopped " 2150 "SIGTRAP\n", TWAIT_FNAME); 2151 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2152 child); 2153 2154 validate_status_stopped(status, SIGTRAP); 2155 2156 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2157 "child\n"); 2158 SYSCALL_REQUIRE( 2159 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2160 2161 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2162 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2163 "si_errno=%#x\n", 2164 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2165 info.psi_siginfo.si_errno); 2166 2167 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2168 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 2169 2170 SYSCALL_REQUIRE( 2171 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2172 2173 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 2174 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 2175 2176 lid = state.pe_lwp; 2177 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 2178 2179 DPRINTF("Before resuming the child process where it left off " 2180 "and without signal to be sent\n"); 2181 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2182 2183 DPRINTF("Before calling %s() for the child - expected stopped " 2184 "SIGTRAP\n", TWAIT_FNAME); 2185 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2186 child); 2187 2188 validate_status_stopped(status, SIGTRAP); 2189 2190 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2191 "child\n"); 2192 SYSCALL_REQUIRE( 2193 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2194 2195 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2196 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2197 "si_errno=%#x\n", 2198 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2199 info.psi_siginfo.si_errno); 2200 2201 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2202 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 2203 2204 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2205 2206 DPRINTF("Before calling %s() for the child - expected exited\n", 2207 TWAIT_FNAME); 2208 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2209 2210 validate_status_signaled(status, SIGKILL, 0); 2211 2212 DPRINTF("Before calling %s() for the child - expected no process\n", 2213 TWAIT_FNAME); 2214 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2215} 2216 2217ATF_TC(threads_and_exec); 2218ATF_TC_HEAD(threads_and_exec, tc) 2219{ 2220 atf_tc_set_md_var(tc, "descr", 2221 "Verify that multithreaded application on exec() will report " 2222 "LWP_EXIT events"); 2223} 2224 2225ATF_TC_BODY(threads_and_exec, tc) 2226{ 2227 2228 threads_and_exec(); 2229} 2230 2231/// ---------------------------------------------------------------------------- 2232 2233ATF_TC(suspend_no_deadlock); 2234ATF_TC_HEAD(suspend_no_deadlock, tc) 2235{ 2236 atf_tc_set_md_var(tc, "descr", 2237 "Verify that the while the only thread within a process is " 2238 "suspended, the whole process cannot be unstopped"); 2239} 2240 2241ATF_TC_BODY(suspend_no_deadlock, tc) 2242{ 2243 const int exitval = 5; 2244 const int sigval = SIGSTOP; 2245 pid_t child, wpid; 2246#if defined(TWAIT_HAVE_STATUS) 2247 int status; 2248#endif 2249 struct ptrace_siginfo psi; 2250 2251 DPRINTF("Before forking process PID=%d\n", getpid()); 2252 SYSCALL_REQUIRE((child = fork()) != -1); 2253 if (child == 0) { 2254 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2255 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2256 2257 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2258 FORKEE_ASSERT(raise(sigval) == 0); 2259 2260 DPRINTF("Before exiting of the child process\n"); 2261 _exit(exitval); 2262 } 2263 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2264 2265 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2266 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2267 2268 validate_status_stopped(status, sigval); 2269 2270 DPRINTF("Before reading siginfo and lwpid_t\n"); 2271 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 2272 2273 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 2274 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 2275 2276 DPRINTF("Before resuming the child process where it left off and " 2277 "without signal to be sent\n"); 2278 ATF_REQUIRE_ERRNO(EDEADLK, 2279 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 2280 2281 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 2282 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 2283 2284 DPRINTF("Before resuming the child process where it left off and " 2285 "without signal to be sent\n"); 2286 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2287 2288 DPRINTF("Before calling %s() for the child - expected exited\n", 2289 TWAIT_FNAME); 2290 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2291 2292 validate_status_exited(status, exitval); 2293 2294 DPRINTF("Before calling %s() for the child - expected no process\n", 2295 TWAIT_FNAME); 2296 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2297} 2298 2299/// ---------------------------------------------------------------------------- 2300 2301static pthread_barrier_t barrier1_resume; 2302static pthread_barrier_t barrier2_resume; 2303 2304static void * 2305resume_thread(void *arg) 2306{ 2307 2308 raise(SIGUSR1); 2309 2310 pthread_barrier_wait(&barrier1_resume); 2311 2312 /* Debugger will suspend the process here */ 2313 2314 pthread_barrier_wait(&barrier2_resume); 2315 2316 raise(SIGUSR2); 2317 2318 return infinite_thread(arg); 2319} 2320 2321ATF_TC(resume); 2322ATF_TC_HEAD(resume, tc) 2323{ 2324 atf_tc_set_md_var(tc, "descr", 2325 "Verify that a thread can be suspended by a debugger and later " 2326 "resumed by the debugger"); 2327} 2328 2329ATF_TC_BODY(resume, tc) 2330{ 2331 const int sigval = SIGSTOP; 2332 pid_t child, wpid; 2333#if defined(TWAIT_HAVE_STATUS) 2334 int status; 2335#endif 2336 lwpid_t lid; 2337 struct ptrace_siginfo psi; 2338 pthread_t t; 2339 2340 DPRINTF("Before forking process PID=%d\n", getpid()); 2341 SYSCALL_REQUIRE((child = fork()) != -1); 2342 if (child == 0) { 2343 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2344 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2345 2346 pthread_barrier_init(&barrier1_resume, NULL, 2); 2347 pthread_barrier_init(&barrier2_resume, NULL, 2); 2348 2349 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2350 FORKEE_ASSERT(raise(sigval) == 0); 2351 2352 DPRINTF("Before creating new thread in child\n"); 2353 FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0); 2354 2355 pthread_barrier_wait(&barrier1_resume); 2356 2357 pthread_barrier_wait(&barrier2_resume); 2358 2359 infinite_thread(NULL); 2360 } 2361 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2362 2363 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2364 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2365 2366 validate_status_stopped(status, sigval); 2367 2368 DPRINTF("Before resuming the child process where it left off and " 2369 "without signal to be sent\n"); 2370 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2371 2372 DPRINTF("Before calling %s() for the child - expected stopped " 2373 "SIGUSR1\n", TWAIT_FNAME); 2374 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2375 2376 validate_status_stopped(status, SIGUSR1); 2377 2378 DPRINTF("Before reading siginfo and lwpid_t\n"); 2379 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 2380 2381 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 2382 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 2383 2384 lid = psi.psi_lwpid; 2385 2386 DPRINTF("Before resuming the child process where it left off and " 2387 "without signal to be sent\n"); 2388 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2389 2390 DPRINTF("Before suspending the parent for 1 second, we expect no signals\n"); 2391 SYSCALL_REQUIRE(sleep(1) == 0); 2392 2393#if defined(TWAIT_HAVE_OPTIONS) 2394 DPRINTF("Before calling %s() for the child - expected no status\n", 2395 TWAIT_FNAME); 2396 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0); 2397#endif 2398 2399 DPRINTF("Before resuming the child process where it left off and " 2400 "without signal to be sent\n"); 2401 SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1); 2402 2403 DPRINTF("Before calling %s() for the child - expected stopped " 2404 "SIGSTOP\n", TWAIT_FNAME); 2405 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2406 2407 validate_status_stopped(status, SIGSTOP); 2408 2409 DPRINTF("Before resuming LWP %d\n", lid); 2410 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1); 2411 2412 DPRINTF("Before resuming the child process where it left off and " 2413 "without signal to be sent\n"); 2414 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2415 2416 DPRINTF("Before calling %s() for the child - expected stopped " 2417 "SIGUSR2\n", TWAIT_FNAME); 2418 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2419 2420 validate_status_stopped(status, SIGUSR2); 2421 2422 DPRINTF("Before resuming the child process where it left off and " 2423 "without signal to be sent\n"); 2424 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 2425 2426 DPRINTF("Before calling %s() for the child - expected exited\n", 2427 TWAIT_FNAME); 2428 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2429 2430 validate_status_signaled(status, SIGKILL, 0); 2431 2432 DPRINTF("Before calling %s() for the child - expected no process\n", 2433 TWAIT_FNAME); 2434 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2435} 2436 2437/// ---------------------------------------------------------------------------- 2438 2439static void 2440user_va0_disable(int operation) 2441{ 2442 pid_t child, wpid; 2443#if defined(TWAIT_HAVE_STATUS) 2444 int status; 2445#endif 2446 const int sigval = SIGSTOP; 2447 int rv; 2448 2449 struct ptrace_siginfo info; 2450 2451 if (get_user_va0_disable() == 0) 2452 atf_tc_skip("vm.user_va0_disable is set to 0"); 2453 2454 memset(&info, 0, sizeof(info)); 2455 2456 DPRINTF("Before forking process PID=%d\n", getpid()); 2457 SYSCALL_REQUIRE((child = fork()) != -1); 2458 if (child == 0) { 2459 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2460 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2461 2462 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2463 FORKEE_ASSERT(raise(sigval) == 0); 2464 2465 /* NOTREACHED */ 2466 FORKEE_ASSERTX(0 && "This shall not be reached"); 2467 __unreachable(); 2468 } 2469 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2470 2471 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2472 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2473 2474 validate_status_stopped(status, sigval); 2475 2476 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2477 "child\n"); 2478 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 2479 sizeof(info)) != -1); 2480 2481 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2482 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2483 "si_errno=%#x\n", 2484 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2485 info.psi_siginfo.si_errno); 2486 2487 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 2488 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2489 2490 DPRINTF("Before resuming the child process in PC=0x0 " 2491 "and without signal to be sent\n"); 2492 errno = 0; 2493 rv = ptrace(operation, child, (void *)0, 0); 2494 ATF_REQUIRE_EQ(errno, EINVAL); 2495 ATF_REQUIRE_EQ(rv, -1); 2496 2497 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2498 2499 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2500 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2501 validate_status_signaled(status, SIGKILL, 0); 2502 2503 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2504 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2505} 2506 2507#define USER_VA0_DISABLE(test, operation) \ 2508ATF_TC(test); \ 2509ATF_TC_HEAD(test, tc) \ 2510{ \ 2511 atf_tc_set_md_var(tc, "descr", \ 2512 "Verify behavior of " #operation " with PC set to 0x0"); \ 2513} \ 2514 \ 2515ATF_TC_BODY(test, tc) \ 2516{ \ 2517 \ 2518 user_va0_disable(operation); \ 2519} 2520 2521USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 2522USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 2523USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 2524 2525/// ---------------------------------------------------------------------------- 2526 2527/* 2528 * Parse the core file and find the requested note. If the reading or parsing 2529 * fails, the test is failed. If the note is found, it is read onto buf, up to 2530 * buf_len. The actual length of the note is returned (which can be greater 2531 * than buf_len, indicating that it has been truncated). If the note is not 2532 * found, -1 is returned. 2533 * 2534 * If the note_name ends in '*', then we find the first note that matches 2535 * the note_name prefix up to the '*' character, e.g.: 2536 * 2537 * NetBSD-CORE@* 2538 * 2539 * finds the first note whose name prefix matches "NetBSD-CORE@". 2540 */ 2541static ssize_t core_find_note(const char *core_path, 2542 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 2543{ 2544 int core_fd; 2545 Elf *core_elf; 2546 size_t core_numhdr, i; 2547 ssize_t ret = -1; 2548 size_t name_len = strlen(note_name); 2549 bool prefix_match = false; 2550 2551 if (note_name[name_len - 1] == '*') { 2552 prefix_match = true; 2553 name_len--; 2554 } else { 2555 /* note: we assume note name will be null-terminated */ 2556 name_len++; 2557 } 2558 2559 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 2560 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 2561 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 2562 2563 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 2564 for (i = 0; i < core_numhdr && ret == -1; i++) { 2565 GElf_Phdr core_hdr; 2566 size_t offset; 2567 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 2568 if (core_hdr.p_type != PT_NOTE) 2569 continue; 2570 2571 for (offset = core_hdr.p_offset; 2572 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 2573 Elf64_Nhdr note_hdr; 2574 char name_buf[64]; 2575 2576 switch (gelf_getclass(core_elf)) { 2577 case ELFCLASS64: 2578 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 2579 sizeof(note_hdr), offset) 2580 == sizeof(note_hdr)); 2581 offset += sizeof(note_hdr); 2582 break; 2583 case ELFCLASS32: 2584 { 2585 Elf32_Nhdr tmp_hdr; 2586 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 2587 sizeof(tmp_hdr), offset) 2588 == sizeof(tmp_hdr)); 2589 offset += sizeof(tmp_hdr); 2590 note_hdr.n_namesz = tmp_hdr.n_namesz; 2591 note_hdr.n_descsz = tmp_hdr.n_descsz; 2592 note_hdr.n_type = tmp_hdr.n_type; 2593 } 2594 break; 2595 } 2596 2597 /* indicates end of notes */ 2598 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 2599 break; 2600 if (((prefix_match && 2601 note_hdr.n_namesz > name_len) || 2602 (!prefix_match && 2603 note_hdr.n_namesz == name_len)) && 2604 note_hdr.n_namesz <= sizeof(name_buf)) { 2605 SYSCALL_REQUIRE(pread(core_fd, name_buf, 2606 note_hdr.n_namesz, offset) 2607 == (ssize_t)(size_t)note_hdr.n_namesz); 2608 2609 if (!strncmp(note_name, name_buf, name_len) && 2610 note_hdr.n_type == note_type) 2611 ret = note_hdr.n_descsz; 2612 } 2613 2614 offset += note_hdr.n_namesz; 2615 /* fix to alignment */ 2616 offset = roundup(offset, core_hdr.p_align); 2617 2618 /* if name & type matched above */ 2619 if (ret != -1) { 2620 ssize_t read_len = MIN(buf_len, 2621 note_hdr.n_descsz); 2622 SYSCALL_REQUIRE(pread(core_fd, buf, 2623 read_len, offset) == read_len); 2624 break; 2625 } 2626 2627 offset += note_hdr.n_descsz; 2628 /* fix to alignment */ 2629 offset = roundup(offset, core_hdr.p_align); 2630 } 2631 } 2632 2633 elf_end(core_elf); 2634 close(core_fd); 2635 2636 return ret; 2637} 2638 2639ATF_TC(core_dump_procinfo); 2640ATF_TC_HEAD(core_dump_procinfo, tc) 2641{ 2642 atf_tc_set_md_var(tc, "descr", 2643 "Trigger a core dump and verify its contents."); 2644} 2645 2646ATF_TC_BODY(core_dump_procinfo, tc) 2647{ 2648 const int exitval = 5; 2649 pid_t child, wpid; 2650#if defined(TWAIT_HAVE_STATUS) 2651 const int sigval = SIGTRAP; 2652 int status; 2653#endif 2654 char core_path[] = "/tmp/core.XXXXXX"; 2655 int core_fd; 2656 struct netbsd_elfcore_procinfo procinfo; 2657 2658 DPRINTF("Before forking process PID=%d\n", getpid()); 2659 SYSCALL_REQUIRE((child = fork()) != -1); 2660 if (child == 0) { 2661 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2662 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2663 2664 DPRINTF("Before triggering SIGTRAP\n"); 2665 trigger_trap(); 2666 2667 DPRINTF("Before exiting of the child process\n"); 2668 _exit(exitval); 2669 } 2670 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2671 2672 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2673 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2674 2675 validate_status_stopped(status, sigval); 2676 2677 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 2678 close(core_fd); 2679 2680 DPRINTF("Call DUMPCORE for the child process\n"); 2681 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 2682 != -1); 2683 2684 DPRINTF("Read core file\n"); 2685 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 2686 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 2687 sizeof(procinfo)); 2688 2689 ATF_CHECK_EQ(procinfo.cpi_version, 1); 2690 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 2691 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 2692 ATF_CHECK_EQ(procinfo.cpi_pid, child); 2693 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 2694 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 2695 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 2696 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 2697 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 2698 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 2699 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 2700 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 2701 ATF_CHECK(procinfo.cpi_siglwp > 0); 2702 2703 unlink(core_path); 2704 2705 DPRINTF("Before resuming the child process where it left off and " 2706 "without signal to be sent\n"); 2707 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2708 2709 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2710 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2711 2712 validate_status_exited(status, exitval); 2713 2714 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2715 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2716} 2717 2718/// ---------------------------------------------------------------------------- 2719 2720#if defined(TWAIT_HAVE_STATUS) 2721 2722#define THREAD_CONCURRENT_BREAKPOINT_NUM 50 2723#define THREAD_CONCURRENT_SIGNALS_NUM 50 2724#define THREAD_CONCURRENT_WATCHPOINT_NUM 50 2725 2726/* List of signals to use for the test */ 2727const int thread_concurrent_signals_list[] = { 2728 SIGIO, 2729 SIGXCPU, 2730 SIGXFSZ, 2731 SIGVTALRM, 2732 SIGPROF, 2733 SIGWINCH, 2734 SIGINFO, 2735 SIGUSR1, 2736 SIGUSR2 2737}; 2738 2739enum thread_concurrent_signal_handling { 2740 /* the signal is discarded by debugger */ 2741 TCSH_DISCARD, 2742 /* the handler is set to SIG_IGN */ 2743 TCSH_SIG_IGN, 2744 /* an actual handler is used */ 2745 TCSH_HANDLER 2746}; 2747 2748static pthread_barrier_t thread_concurrent_barrier; 2749static pthread_key_t thread_concurrent_key; 2750static uint32_t thread_concurrent_watchpoint_var = 0; 2751 2752static void * 2753thread_concurrent_breakpoint_thread(void *arg) 2754{ 2755 static volatile int watchme = 1; 2756 pthread_barrier_wait(&thread_concurrent_barrier); 2757 DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self()); 2758 check_happy(watchme); 2759 return NULL; 2760} 2761 2762static void 2763thread_concurrent_sig_handler(int sig) 2764{ 2765 void *tls_val = pthread_getspecific(thread_concurrent_key); 2766 DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 2767 FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key, 2768 (void*)((uintptr_t)tls_val + 1)) == 0); 2769} 2770 2771static void * 2772thread_concurrent_signals_thread(void *arg) 2773{ 2774 int sigval = thread_concurrent_signals_list[ 2775 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 2776 enum thread_concurrent_signal_handling *signal_handle = arg; 2777 void *tls_val; 2778 2779 pthread_barrier_wait(&thread_concurrent_barrier); 2780 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 2781 _lwp_self()); 2782 pthread_kill(pthread_self(), sigval); 2783 if (*signal_handle == TCSH_HANDLER) { 2784 tls_val = pthread_getspecific(thread_concurrent_key); 2785 DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 2786 FORKEE_ASSERT(tls_val == (void*)1); 2787 } 2788 return NULL; 2789} 2790 2791static void * 2792thread_concurrent_watchpoint_thread(void *arg) 2793{ 2794 pthread_barrier_wait(&thread_concurrent_barrier); 2795 DPRINTF("Before modifying var from LWP %d\n", _lwp_self()); 2796 thread_concurrent_watchpoint_var = 1; 2797 return NULL; 2798} 2799 2800#if defined(__i386__) || defined(__x86_64__) 2801enum thread_concurrent_sigtrap_event { 2802 TCSE_UNKNOWN, 2803 TCSE_BREAKPOINT, 2804 TCSE_WATCHPOINT 2805}; 2806 2807static void 2808thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid); 2809static enum thread_concurrent_sigtrap_event 2810thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info); 2811#endif 2812 2813static void 2814thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle, 2815 int breakpoint_threads, int signal_threads, int watchpoint_threads) 2816{ 2817 const int exitval = 5; 2818 const int sigval = SIGSTOP; 2819 pid_t child, wpid; 2820 int status; 2821 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 2822 = {{0, 0}}; 2823 struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 2824 = {{0, 0}}; 2825 struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 2826 = {{0, 0}}; 2827 ptrace_event_t event; 2828 int i; 2829 2830#if defined(HAVE_DBREGS) 2831 if (!can_we_set_dbregs()) { 2832 atf_tc_skip("Either run this test as root or set sysctl(3) " 2833 "security.models.extensions.user_set_dbregs to 1"); 2834 } 2835#endif 2836 2837 atf_tc_skip("PR kern/54960"); 2838 2839 /* Protect against out-of-bounds array access. */ 2840 ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM); 2841 ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM); 2842 ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM); 2843 2844 DPRINTF("Before forking process PID=%d\n", getpid()); 2845 SYSCALL_REQUIRE((child = fork()) != -1); 2846 if (child == 0) { 2847 pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM]; 2848 pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM]; 2849 pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM]; 2850 2851 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2852 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2853 2854 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2855 FORKEE_ASSERT(raise(sigval) == 0); 2856 2857 if (signal_handle != TCSH_DISCARD) { 2858 struct sigaction sa; 2859 unsigned int j; 2860 2861 memset(&sa, 0, sizeof(sa)); 2862 if (signal_handle == TCSH_SIG_IGN) 2863 sa.sa_handler = SIG_IGN; 2864 else 2865 sa.sa_handler = thread_concurrent_sig_handler; 2866 sigemptyset(&sa.sa_mask); 2867 2868 for (j = 0; 2869 j < __arraycount(thread_concurrent_signals_list); 2870 j++) 2871 FORKEE_ASSERT(sigaction( 2872 thread_concurrent_signals_list[j], &sa, NULL) 2873 != -1); 2874 } 2875 2876 DPRINTF("Before starting threads from the child\n"); 2877 FORKEE_ASSERT(pthread_barrier_init( 2878 &thread_concurrent_barrier, NULL, 2879 breakpoint_threads + signal_threads + watchpoint_threads) 2880 == 0); 2881 FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL) 2882 == 0); 2883 2884 for (i = 0; i < signal_threads; i++) { 2885 FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL, 2886 thread_concurrent_signals_thread, 2887 &signal_handle) == 0); 2888 } 2889 for (i = 0; i < breakpoint_threads; i++) { 2890 FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL, 2891 thread_concurrent_breakpoint_thread, NULL) == 0); 2892 } 2893 for (i = 0; i < watchpoint_threads; i++) { 2894 FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL, 2895 thread_concurrent_watchpoint_thread, NULL) == 0); 2896 } 2897 2898 DPRINTF("Before joining threads from the child\n"); 2899 for (i = 0; i < watchpoint_threads; i++) { 2900 FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0); 2901 } 2902 for (i = 0; i < breakpoint_threads; i++) { 2903 FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0); 2904 } 2905 for (i = 0; i < signal_threads; i++) { 2906 FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0); 2907 } 2908 2909 FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0); 2910 FORKEE_ASSERT(pthread_barrier_destroy( 2911 &thread_concurrent_barrier) == 0); 2912 2913 DPRINTF("Before exiting of the child process\n"); 2914 _exit(exitval); 2915 } 2916 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2917 2918 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2919 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2920 2921 validate_status_stopped(status, sigval); 2922 2923 DPRINTF("Set LWP event mask for the child process\n"); 2924 memset(&event, 0, sizeof(event)); 2925 event.pe_set_event |= PTRACE_LWP_CREATE; 2926 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event)) 2927 != -1); 2928 2929 DPRINTF("Before resuming the child process where it left off\n"); 2930 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2931 2932 DPRINTF("Before entering signal collection loop\n"); 2933 while (1) { 2934 ptrace_siginfo_t info; 2935 2936 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2937 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2938 child); 2939 if (WIFEXITED(status)) 2940 break; 2941 /* Note: we use validate_status_stopped() to get nice error 2942 * message. Signal is irrelevant since it won't be reached. 2943 */ 2944 else if (!WIFSTOPPED(status)) 2945 validate_status_stopped(status, 0); 2946 2947 DPRINTF("Before calling PT_GET_SIGINFO\n"); 2948 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 2949 sizeof(info)) != -1); 2950 2951 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 2952 info.psi_siginfo.si_signo, info.psi_lwpid, 2953 WSTOPSIG(status)); 2954 2955 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status), 2956 "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid, 2957 WSTOPSIG(status), info.psi_siginfo.si_signo); 2958 2959 if (WSTOPSIG(status) != SIGTRAP) { 2960 int expected_sig = 2961 thread_concurrent_signals_list[info.psi_lwpid % 2962 __arraycount(thread_concurrent_signals_list)]; 2963 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 2964 "lwp=%d, expected %d, got %d", info.psi_lwpid, 2965 expected_sig, WSTOPSIG(status)); 2966 2967 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 2968 } else if (info.psi_siginfo.si_code == TRAP_LWP) { 2969#if defined(__i386__) || defined(__x86_64__) 2970 thread_concurrent_lwp_setup(child, info.psi_lwpid); 2971#endif 2972 } else { 2973#if defined(__i386__) || defined(__x86_64__) 2974 switch (thread_concurrent_handle_sigtrap(child, &info)) { 2975 case TCSE_UNKNOWN: 2976 /* already reported inside the function */ 2977 break; 2978 case TCSE_BREAKPOINT: 2979 *FIND_EVENT_COUNT(bp_counts, 2980 info.psi_lwpid) += 1; 2981 break; 2982 case TCSE_WATCHPOINT: 2983 *FIND_EVENT_COUNT(wp_counts, 2984 info.psi_lwpid) += 1; 2985 break; 2986 } 2987#else 2988 ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n", 2989 info.psi_siginfo.si_code); 2990#endif 2991 } 2992 2993 DPRINTF("Before resuming the child process\n"); 2994 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 2995 signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP 2996 ? WSTOPSIG(status) : 0) != -1); 2997 } 2998 2999 for (i = 0; i < signal_threads; i++) 3000 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 3001 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 3002 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 3003 for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++) 3004 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0, 3005 "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d", 3006 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 3007 3008 for (i = 0; i < breakpoint_threads; i++) 3009 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1, 3010 "bp_counts[%d].lec_count=%d; lec_lwp=%d", 3011 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 3012 for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++) 3013 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0, 3014 "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d", 3015 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 3016 3017 for (i = 0; i < watchpoint_threads; i++) 3018 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1, 3019 "wp_counts[%d].lec_count=%d; lec_lwp=%d", 3020 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 3021 for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++) 3022 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0, 3023 "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d", 3024 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 3025 3026 validate_status_exited(status, exitval); 3027} 3028 3029#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr) \ 3030ATF_TC(test); \ 3031ATF_TC_HEAD(test, tc) \ 3032{ \ 3033 atf_tc_set_md_var(tc, "descr", descr); \ 3034} \ 3035 \ 3036ATF_TC_BODY(test, tc) \ 3037{ \ 3038 thread_concurrent_test(sig_hdl, bps, sigs, wps); \ 3039} 3040 3041THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD, 3042 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3043 "Verify that concurrent signals issued to a single thread are reported " 3044 "correctly"); 3045THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN, 3046 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3047 "Verify that concurrent signals issued to a single thread are reported " 3048 "correctly and passed back to SIG_IGN handler"); 3049THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER, 3050 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3051 "Verify that concurrent signals issued to a single thread are reported " 3052 "correctly and passed back to a handler function"); 3053 3054#if defined(__i386__) || defined(__x86_64__) 3055THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD, 3056 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0, 3057 "Verify that concurrent breakpoints are reported correctly"); 3058THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD, 3059 0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 3060 "Verify that concurrent breakpoints are reported correctly"); 3061THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD, 3062 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 3063 "Verify that concurrent breakpoints and watchpoints are reported " 3064 "correctly"); 3065 3066THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD, 3067 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3068 "Verify that concurrent breakpoints and signals are reported correctly"); 3069THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN, 3070 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3071 "Verify that concurrent breakpoints and signals are reported correctly " 3072 "and passed back to SIG_IGN handler"); 3073THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER, 3074 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3075 "Verify that concurrent breakpoints and signals are reported correctly " 3076 "and passed back to a handler function"); 3077 3078THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD, 3079 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 3080 "Verify that concurrent watchpoints and signals are reported correctly"); 3081THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN, 3082 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 3083 "Verify that concurrent watchpoints and signals are reported correctly " 3084 "and passed back to SIG_IGN handler"); 3085THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER, 3086 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 3087 "Verify that concurrent watchpoints and signals are reported correctly " 3088 "and passed back to a handler function"); 3089 3090THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD, 3091 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 3092 THREAD_CONCURRENT_WATCHPOINT_NUM, 3093 "Verify that concurrent breakpoints, watchpoints and signals are reported " 3094 "correctly"); 3095THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN, 3096 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 3097 THREAD_CONCURRENT_WATCHPOINT_NUM, 3098 "Verify that concurrent breakpoints, watchpoints and signals are reported " 3099 "correctly and passed back to SIG_IGN handler"); 3100THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER, 3101 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 3102 THREAD_CONCURRENT_WATCHPOINT_NUM, 3103 "Verify that concurrent breakpoints, watchpoints and signals are reported " 3104 "correctly and passed back to a handler function"); 3105#endif 3106 3107#endif /*defined(TWAIT_HAVE_STATUS)*/ 3108 3109/// ---------------------------------------------------------------------------- 3110 3111#include "t_ptrace_register_wait.h" 3112#include "t_ptrace_syscall_wait.h" 3113#include "t_ptrace_step_wait.h" 3114#include "t_ptrace_kill_wait.h" 3115#include "t_ptrace_bytetransfer_wait.h" 3116#include "t_ptrace_clone_wait.h" 3117#include "t_ptrace_fork_wait.h" 3118#include "t_ptrace_signal_wait.h" 3119#include "t_ptrace_eventmask_wait.h" 3120 3121/// ---------------------------------------------------------------------------- 3122 3123#include "t_ptrace_amd64_wait.h" 3124#include "t_ptrace_i386_wait.h" 3125#include "t_ptrace_x86_wait.h" 3126 3127/// ---------------------------------------------------------------------------- 3128 3129#else 3130ATF_TC(dummy); 3131ATF_TC_HEAD(dummy, tc) 3132{ 3133 atf_tc_set_md_var(tc, "descr", "A dummy test"); 3134} 3135 3136ATF_TC_BODY(dummy, tc) 3137{ 3138 3139 // Dummy, skipped 3140 // The ATF framework requires at least a single defined test. 3141} 3142#endif 3143 3144ATF_TP_ADD_TCS(tp) 3145{ 3146 setvbuf(stdout, NULL, _IONBF, 0); 3147 setvbuf(stderr, NULL, _IONBF, 0); 3148 3149#ifdef ENABLE_TESTS 3150 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 3151 3152 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 3153 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 3154 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 3155 3156 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 3157 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 3158 ATF_TP_ADD_TC_HAVE_PID(tp, 3159 unrelated_tracer_sees_terminaton_before_the_parent); 3160 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 3161 3162 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 3163 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 3164 3165 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 3166 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 3167 3168 ATF_TP_ADD_TC_HAVE_PID(tp, 3169 tracee_sees_its_original_parent_getppid); 3170 ATF_TP_ADD_TC_HAVE_PID(tp, 3171 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 3172 ATF_TP_ADD_TC_HAVE_PID(tp, 3173 tracee_sees_its_original_parent_procfs_status); 3174 3175 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 3176 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 3177 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 3178 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 3179 3180 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus); 3181 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus); 3182 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus); 3183 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus); 3184 3185 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask); 3186 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask); 3187 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask); 3188 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask); 3189 3190 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name); 3191 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name); 3192 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name); 3193 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name); 3194 3195 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private); 3196 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private); 3197 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private); 3198 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private); 3199 3200 ATF_TP_ADD_TC(tp, traceme_lwpnext0); 3201 ATF_TP_ADD_TC(tp, traceme_lwpnext1); 3202 ATF_TP_ADD_TC(tp, traceme_lwpnext2); 3203 ATF_TP_ADD_TC(tp, traceme_lwpnext3); 3204 3205 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask); 3206 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask); 3207 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask); 3208 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask); 3209 3210 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name); 3211 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name); 3212 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name); 3213 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name); 3214 3215 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private); 3216 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private); 3217 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private); 3218 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private); 3219 3220 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 3221 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 3222 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 3223 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 3224 3225 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 3226 ATF_TP_ADD_TC(tp, siginfo_set_faked); 3227 3228 ATF_TP_ADD_TC(tp, traceme_exec); 3229 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 3230 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 3231 3232 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 3233 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 3234 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 3235 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 3236 3237 ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap); 3238 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap); 3239 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap); 3240 3241 ATF_TP_ADD_TC(tp, threads_and_exec); 3242 3243 ATF_TP_ADD_TC(tp, suspend_no_deadlock); 3244 3245 ATF_TP_ADD_TC(tp, resume); 3246 3247 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 3248 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 3249 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 3250 3251 ATF_TP_ADD_TC(tp, core_dump_procinfo); 3252 3253#if defined(TWAIT_HAVE_STATUS) 3254 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 3255 ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign); 3256 ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler); 3257#if defined(__i386__) || defined(__x86_64__) 3258 ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints); 3259 ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints); 3260 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp); 3261 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig); 3262 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign); 3263 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler); 3264 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig); 3265 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign); 3266 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler); 3267 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig); 3268 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign); 3269 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler); 3270#endif 3271#endif 3272 3273 ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER(); 3274 ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL(); 3275 ATF_TP_ADD_TCS_PTRACE_WAIT_STEP(); 3276 ATF_TP_ADD_TCS_PTRACE_WAIT_KILL(); 3277 ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER(); 3278 ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE(); 3279 ATF_TP_ADD_TCS_PTRACE_WAIT_FORK(); 3280 ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL(); 3281 ATF_TP_ADD_TCS_PTRACE_WAIT_EVENTMASK(); 3282 3283 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 3284 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 3285 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 3286 3287#else 3288 ATF_TP_ADD_TC(tp, dummy); 3289#endif 3290 3291 return atf_no_error(); 3292} 3293