t_ptrace_wait.c revision 1.182
1/* $NetBSD: t_ptrace_wait.c,v 1.182 2020/05/04 23:53:20 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.182 2020/05/04 23:53:20 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 void 931eventmask_preserved(int event) 932{ 933 const int exitval = 5; 934 const int sigval = SIGSTOP; 935 pid_t child, wpid; 936#if defined(TWAIT_HAVE_STATUS) 937 int status; 938#endif 939 ptrace_event_t set_event, get_event; 940 const int len = sizeof(ptrace_event_t); 941 942 DPRINTF("Before forking process PID=%d\n", getpid()); 943 SYSCALL_REQUIRE((child = fork()) != -1); 944 if (child == 0) { 945 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 946 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 947 948 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 949 FORKEE_ASSERT(raise(sigval) == 0); 950 951 DPRINTF("Before exiting of the child process\n"); 952 _exit(exitval); 953 } 954 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 955 956 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 957 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 958 959 validate_status_stopped(status, sigval); 960 961 set_event.pe_set_event = event; 962 SYSCALL_REQUIRE( 963 ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 964 SYSCALL_REQUIRE( 965 ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 966 DPRINTF("set_event=%#x get_event=%#x\n", set_event.pe_set_event, 967 get_event.pe_set_event); 968 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 969 970 DPRINTF("Before resuming the child process where it left off and " 971 "without signal to be sent\n"); 972 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 973 974 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 975 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 976 977 validate_status_exited(status, exitval); 978 979 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 980 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 981} 982 983#define EVENTMASK_PRESERVED(test, event) \ 984ATF_TC(test); \ 985ATF_TC_HEAD(test, tc) \ 986{ \ 987 atf_tc_set_md_var(tc, "descr", \ 988 "Verify that eventmask " #event " is preserved"); \ 989} \ 990 \ 991ATF_TC_BODY(test, tc) \ 992{ \ 993 \ 994 eventmask_preserved(event); \ 995} 996 997EVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 998EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 999EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 1000EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 1001EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 1002EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 1003EVENTMASK_PRESERVED(eventmask_preserved_posix_spawn, PTRACE_POSIX_SPAWN) 1004 1005/// ---------------------------------------------------------------------------- 1006 1007static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG}; 1008 1009static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER; 1010static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER; 1011static volatile size_t lwpinfo_thread_done; 1012 1013static void * 1014lwpinfo_thread(void *arg) 1015{ 1016 sigset_t s; 1017 volatile void **tcb; 1018 1019 tcb = (volatile void **)arg; 1020 1021 *tcb = _lwp_getprivate(); 1022 DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self()); 1023 1024 pthread_setname_np(pthread_self(), "thread %d", 1025 (void *)(intptr_t)_lwp_self()); 1026 1027 sigemptyset(&s); 1028 pthread_mutex_lock(&lwpinfo_thread_mtx); 1029 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 1030 lwpinfo_thread_done++; 1031 pthread_sigmask(SIG_BLOCK, &s, NULL); 1032 pthread_cond_signal(&lwpinfo_thread_cnd); 1033 pthread_mutex_unlock(&lwpinfo_thread_mtx); 1034 1035 return infinite_thread(NULL); 1036} 1037 1038static void 1039traceme_lwpinfo(const size_t threads, const char *iter) 1040{ 1041 const int sigval = SIGSTOP; 1042 const int sigval2 = SIGINT; 1043 pid_t child, wpid; 1044#if defined(TWAIT_HAVE_STATUS) 1045 int status; 1046#endif 1047 struct ptrace_lwpinfo lwp = {0, 0}; 1048 struct ptrace_lwpstatus lwpstatus = {0}; 1049 struct ptrace_siginfo info; 1050 void *private; 1051 char *name; 1052 char namebuf[PL_LNAMELEN]; 1053 volatile void *tcb[4]; 1054 bool found; 1055 sigset_t s; 1056 1057 /* Maximum number of supported threads in this test */ 1058 pthread_t t[__arraycount(tcb) - 1]; 1059 size_t n, m; 1060 int rv; 1061 size_t bytes_read; 1062 1063 struct ptrace_io_desc io; 1064 sigset_t sigmask; 1065 1066 ATF_REQUIRE(__arraycount(t) >= threads); 1067 memset(tcb, 0, sizeof(tcb)); 1068 1069 DPRINTF("Before forking process PID=%d\n", getpid()); 1070 SYSCALL_REQUIRE((child = fork()) != -1); 1071 if (child == 0) { 1072 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1073 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1074 1075 tcb[0] = _lwp_getprivate(); 1076 DPRINTF("Storing tcb[0] = %p\n", tcb[0]); 1077 1078 pthread_setname_np(pthread_self(), "thread %d", 1079 (void *)(intptr_t)_lwp_self()); 1080 1081 sigemptyset(&s); 1082 sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]); 1083 pthread_sigmask(SIG_BLOCK, &s, NULL); 1084 1085 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1086 FORKEE_ASSERT(raise(sigval) == 0); 1087 1088 for (n = 0; n < threads; n++) { 1089 rv = pthread_create(&t[n], NULL, lwpinfo_thread, 1090 &tcb[n + 1]); 1091 FORKEE_ASSERT(rv == 0); 1092 } 1093 1094 pthread_mutex_lock(&lwpinfo_thread_mtx); 1095 while (lwpinfo_thread_done < threads) { 1096 pthread_cond_wait(&lwpinfo_thread_cnd, 1097 &lwpinfo_thread_mtx); 1098 } 1099 pthread_mutex_unlock(&lwpinfo_thread_mtx); 1100 1101 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 1102 FORKEE_ASSERT(raise(sigval2) == 0); 1103 1104 /* NOTREACHED */ 1105 FORKEE_ASSERTX(0 && "Not reached"); 1106 } 1107 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1108 1109 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1110 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1111 1112 validate_status_stopped(status, sigval); 1113 1114 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 1115 SYSCALL_REQUIRE( 1116 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1117 1118 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1119 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1120 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1121 info.psi_siginfo.si_errno); 1122 1123 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1124 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1125 1126 if (strstr(iter, "LWPINFO") != NULL) { 1127 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 1128 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 1129 != -1); 1130 1131 DPRINTF("Assert that there exists a single thread only\n"); 1132 ATF_REQUIRE(lwp.pl_lwpid > 0); 1133 1134 DPRINTF("Assert that lwp thread %d received event " 1135 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 1136 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 1137 1138 if (strstr(iter, "LWPSTATUS") != NULL) { 1139 DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS " 1140 "for child\n"); 1141 lwpstatus.pl_lwpid = lwp.pl_lwpid; 1142 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus, 1143 sizeof(lwpstatus)) != -1); 1144 } 1145 1146 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 1147 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 1148 != -1); 1149 1150 DPRINTF("Assert that there exists a single thread only\n"); 1151 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 1152 } else { 1153 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 1154 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 1155 sizeof(lwpstatus)) != -1); 1156 1157 DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid); 1158 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 1159 1160 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 1161 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 1162 sizeof(lwpstatus)) != -1); 1163 1164 DPRINTF("Assert that there exists a single thread only\n"); 1165 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 1166 } 1167 1168 DPRINTF("Before resuming the child process where it left off and " 1169 "without signal to be sent\n"); 1170 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1171 1172 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1173 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1174 1175 validate_status_stopped(status, sigval2); 1176 1177 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 1178 SYSCALL_REQUIRE( 1179 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1180 1181 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1182 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1183 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1184 info.psi_siginfo.si_errno); 1185 1186 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 1187 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1188 1189 memset(&lwp, 0, sizeof(lwp)); 1190 memset(&lwpstatus, 0, sizeof(lwpstatus)); 1191 1192 memset(&io, 0, sizeof(io)); 1193 1194 bytes_read = 0; 1195 io.piod_op = PIOD_READ_D; 1196 io.piod_len = sizeof(tcb); 1197 1198 do { 1199 io.piod_addr = (char *)&tcb + bytes_read; 1200 io.piod_offs = io.piod_addr; 1201 1202 rv = ptrace(PT_IO, child, &io, sizeof(io)); 1203 ATF_REQUIRE(rv != -1 && io.piod_len != 0); 1204 1205 bytes_read += io.piod_len; 1206 io.piod_len = sizeof(tcb) - bytes_read; 1207 } while (bytes_read < sizeof(tcb)); 1208 1209 for (n = 0; n <= threads; n++) { 1210 if (strstr(iter, "LWPINFO") != NULL) { 1211 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1212 "child\n"); 1213 SYSCALL_REQUIRE( 1214 ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 1215 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1216 1217 DPRINTF("Assert that the thread exists\n"); 1218 ATF_REQUIRE(lwp.pl_lwpid > 0); 1219 1220 DPRINTF("Assert that lwp thread %d received expected " 1221 "event\n", lwp.pl_lwpid); 1222 FORKEE_ASSERT_EQ(lwp.pl_event, 1223 info.psi_lwpid == lwp.pl_lwpid ? 1224 PL_EVENT_SIGNAL : PL_EVENT_NONE); 1225 1226 if (strstr(iter, "LWPSTATUS") != NULL) { 1227 DPRINTF("Before calling ptrace(2) with " 1228 "PT_LWPSTATUS for child\n"); 1229 lwpstatus.pl_lwpid = lwp.pl_lwpid; 1230 SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, 1231 &lwpstatus, sizeof(lwpstatus)) != -1); 1232 1233 goto check_lwpstatus; 1234 } 1235 } else { 1236 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for " 1237 "child\n"); 1238 SYSCALL_REQUIRE( 1239 ptrace(PT_LWPNEXT, child, &lwpstatus, 1240 sizeof(lwpstatus)) != -1); 1241 DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid); 1242 1243 DPRINTF("Assert that the thread exists\n"); 1244 ATF_REQUIRE(lwpstatus.pl_lwpid > 0); 1245 1246 check_lwpstatus: 1247 1248 if (strstr(iter, "pl_sigmask") != NULL) { 1249 sigmask = lwpstatus.pl_sigmask; 1250 1251 DPRINTF("Retrieved sigmask: " 1252 "%02x%02x%02x%02x\n", 1253 sigmask.__bits[0], sigmask.__bits[1], 1254 sigmask.__bits[2], sigmask.__bits[3]); 1255 1256 found = false; 1257 for (m = 0; 1258 m < __arraycount(lwpinfo_thread_sigmask); 1259 m++) { 1260 if (sigismember(&sigmask, 1261 lwpinfo_thread_sigmask[m])) { 1262 found = true; 1263 lwpinfo_thread_sigmask[m] = 0; 1264 break; 1265 } 1266 } 1267 ATF_REQUIRE(found == true); 1268 } else if (strstr(iter, "pl_name") != NULL) { 1269 name = lwpstatus.pl_name; 1270 1271 DPRINTF("Retrieved thread name: " 1272 "%s\n", name); 1273 1274 snprintf(namebuf, sizeof namebuf, "thread %d", 1275 lwpstatus.pl_lwpid); 1276 1277 ATF_REQUIRE(strcmp(name, namebuf) == 0); 1278 } else if (strstr(iter, "pl_private") != NULL) { 1279 private = lwpstatus.pl_private; 1280 1281 DPRINTF("Retrieved thread private pointer: " 1282 "%p\n", private); 1283 1284 found = false; 1285 for (m = 0; m < __arraycount(tcb); m++) { 1286 DPRINTF("Comparing %p and %p\n", 1287 private, tcb[m]); 1288 if (private == tcb[m]) { 1289 found = true; 1290 break; 1291 } 1292 } 1293 ATF_REQUIRE(found == true); 1294 } 1295 } 1296 } 1297 1298 if (strstr(iter, "LWPINFO") != NULL) { 1299 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1300 "child\n"); 1301 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) 1302 != -1); 1303 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1304 1305 DPRINTF("Assert that there are no more threads\n"); 1306 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 1307 } else { 1308 DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n"); 1309 SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus, 1310 sizeof(lwpstatus)) != -1); 1311 1312 DPRINTF("Assert that there exists a single thread only\n"); 1313 ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0); 1314 } 1315 1316 DPRINTF("Before resuming the child process where it left off and " 1317 "without signal to be sent\n"); 1318 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 1319 1320 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1321 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1322 1323 validate_status_signaled(status, SIGKILL, 0); 1324 1325 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1326 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1327} 1328 1329#define TRACEME_LWPINFO(test, threads, iter) \ 1330ATF_TC(test); \ 1331ATF_TC_HEAD(test, tc) \ 1332{ \ 1333 atf_tc_set_md_var(tc, "descr", \ 1334 "Verify " iter " with the child with " #threads \ 1335 " spawned extra threads"); \ 1336} \ 1337 \ 1338ATF_TC_BODY(test, tc) \ 1339{ \ 1340 \ 1341 traceme_lwpinfo(threads, iter); \ 1342} 1343 1344TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO") 1345TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO") 1346TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO") 1347TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO") 1348 1349TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS") 1350TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS") 1351TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS") 1352TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS") 1353 1354TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0, 1355 "LWPINFO+LWPSTATUS+pl_sigmask") 1356TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1, 1357 "LWPINFO+LWPSTATUS+pl_sigmask") 1358TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2, 1359 "LWPINFO+LWPSTATUS+pl_sigmask") 1360TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3, 1361 "LWPINFO+LWPSTATUS+pl_sigmask") 1362 1363TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0, 1364 "LWPINFO+LWPSTATUS+pl_name") 1365TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1, 1366 "LWPINFO+LWPSTATUS+pl_name") 1367TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2, 1368 "LWPINFO+LWPSTATUS+pl_name") 1369TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3, 1370 "LWPINFO+LWPSTATUS+pl_name") 1371 1372TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0, 1373 "LWPINFO+LWPSTATUS+pl_private") 1374TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1, 1375 "LWPINFO+LWPSTATUS+pl_private") 1376TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2, 1377 "LWPINFO+LWPSTATUS+pl_private") 1378TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3, 1379 "LWPINFO+LWPSTATUS+pl_private") 1380 1381TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT") 1382TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT") 1383TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT") 1384TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT") 1385 1386TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask") 1387TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask") 1388TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask") 1389TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask") 1390 1391TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name") 1392TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name") 1393TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name") 1394TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name") 1395 1396TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private") 1397TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private") 1398TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private") 1399TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private") 1400 1401/// ---------------------------------------------------------------------------- 1402 1403#if defined(TWAIT_HAVE_PID) 1404static void 1405attach_lwpinfo(const int threads) 1406{ 1407 const int sigval = SIGINT; 1408 struct msg_fds parent_tracee, parent_tracer; 1409 const int exitval_tracer = 10; 1410 pid_t tracee, tracer, wpid; 1411 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 1412#if defined(TWAIT_HAVE_STATUS) 1413 int status; 1414#endif 1415 struct ptrace_lwpinfo lwp = {0, 0}; 1416 struct ptrace_siginfo info; 1417 1418 /* Maximum number of supported threads in this test */ 1419 pthread_t t[3]; 1420 int n, rv; 1421 1422 DPRINTF("Spawn tracee\n"); 1423 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 1424 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 1425 tracee = atf_utils_fork(); 1426 if (tracee == 0) { 1427 /* Wait for message from the parent */ 1428 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 1429 1430 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 1431 1432 for (n = 0; n < threads; n++) { 1433 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 1434 FORKEE_ASSERT(rv == 0); 1435 } 1436 1437 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 1438 1439 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1440 FORKEE_ASSERT(raise(sigval) == 0); 1441 1442 /* NOTREACHED */ 1443 FORKEE_ASSERTX(0 && "Not reached"); 1444 } 1445 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 1446 1447 DPRINTF("Spawn debugger\n"); 1448 tracer = atf_utils_fork(); 1449 if (tracer == 0) { 1450 /* No IPC to communicate with the child */ 1451 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 1452 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 1453 1454 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 1455 FORKEE_REQUIRE_SUCCESS( 1456 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1457 1458 forkee_status_stopped(status, SIGSTOP); 1459 1460 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1461 "tracee"); 1462 FORKEE_ASSERT( 1463 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1464 1465 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1466 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1467 "si_errno=%#x\n", 1468 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1469 info.psi_siginfo.si_errno); 1470 1471 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 1472 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 1473 1474 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 1475 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 1476 != -1); 1477 1478 DPRINTF("Assert that there exists a thread\n"); 1479 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 1480 1481 DPRINTF("Assert that lwp thread %d received event " 1482 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 1483 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 1484 1485 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1486 "tracee\n"); 1487 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 1488 != -1); 1489 1490 DPRINTF("Assert that there are no more lwp threads in " 1491 "tracee\n"); 1492 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 1493 1494 /* Resume tracee with PT_CONTINUE */ 1495 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 1496 1497 /* Inform parent that tracer has attached to tracee */ 1498 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 1499 1500 /* Wait for parent */ 1501 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 1502 1503 /* Wait for tracee and assert that it raised a signal */ 1504 FORKEE_REQUIRE_SUCCESS( 1505 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1506 1507 forkee_status_stopped(status, SIGINT); 1508 1509 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1510 "child"); 1511 FORKEE_ASSERT( 1512 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 1513 1514 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1515 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1516 "si_errno=%#x\n", 1517 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1518 info.psi_siginfo.si_errno); 1519 1520 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 1521 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 1522 1523 memset(&lwp, 0, sizeof(lwp)); 1524 1525 for (n = 0; n <= threads; n++) { 1526 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1527 "child\n"); 1528 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 1529 sizeof(lwp)) != -1); 1530 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1531 1532 DPRINTF("Assert that the thread exists\n"); 1533 FORKEE_ASSERT(lwp.pl_lwpid > 0); 1534 1535 DPRINTF("Assert that lwp thread %d received expected " 1536 "event\n", lwp.pl_lwpid); 1537 FORKEE_ASSERT_EQ(lwp.pl_event, 1538 info.psi_lwpid == lwp.pl_lwpid ? 1539 PL_EVENT_SIGNAL : PL_EVENT_NONE); 1540 } 1541 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 1542 "tracee\n"); 1543 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 1544 != -1); 1545 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 1546 1547 DPRINTF("Assert that there are no more threads\n"); 1548 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 1549 1550 DPRINTF("Before resuming the child process where it left off " 1551 "and without signal to be sent\n"); 1552 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 1553 != -1); 1554 1555 /* Wait for tracee and assert that it exited */ 1556 FORKEE_REQUIRE_SUCCESS( 1557 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 1558 1559 forkee_status_signaled(status, SIGKILL, 0); 1560 1561 DPRINTF("Before exiting of the tracer process\n"); 1562 _exit(exitval_tracer); 1563 } 1564 1565 DPRINTF("Wait for the tracer to attach to the tracee\n"); 1566 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 1567 1568 DPRINTF("Resume the tracee and spawn threads\n"); 1569 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 1570 1571 DPRINTF("Resume the tracee and let it exit\n"); 1572 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 1573 1574 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 1575 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 1576 1577 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 1578 TWAIT_FNAME); 1579 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 1580 tracer); 1581 1582 validate_status_exited(status, exitval_tracer); 1583 1584 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 1585 TWAIT_FNAME); 1586 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 1587 tracee); 1588 1589 validate_status_signaled(status, SIGKILL, 0); 1590 1591 msg_close(&parent_tracer); 1592 msg_close(&parent_tracee); 1593} 1594 1595#define ATTACH_LWPINFO(test, threads) \ 1596ATF_TC(test); \ 1597ATF_TC_HEAD(test, tc) \ 1598{ \ 1599 atf_tc_set_md_var(tc, "descr", \ 1600 "Verify LWPINFO with the child with " #threads \ 1601 " spawned extra threads (tracer is not the original " \ 1602 "parent)"); \ 1603} \ 1604 \ 1605ATF_TC_BODY(test, tc) \ 1606{ \ 1607 \ 1608 attach_lwpinfo(threads); \ 1609} 1610 1611ATTACH_LWPINFO(attach_lwpinfo0, 0) 1612ATTACH_LWPINFO(attach_lwpinfo1, 1) 1613ATTACH_LWPINFO(attach_lwpinfo2, 2) 1614ATTACH_LWPINFO(attach_lwpinfo3, 3) 1615#endif 1616 1617/// ---------------------------------------------------------------------------- 1618 1619static void 1620ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 1621{ 1622 const int exitval = 5; 1623 const int sigval = SIGINT; 1624 const int sigfaked = SIGTRAP; 1625 const int sicodefaked = TRAP_BRKPT; 1626 pid_t child, wpid; 1627 struct sigaction sa; 1628#if defined(TWAIT_HAVE_STATUS) 1629 int status; 1630#endif 1631 struct ptrace_siginfo info; 1632 memset(&info, 0, sizeof(info)); 1633 1634 DPRINTF("Before forking process PID=%d\n", getpid()); 1635 SYSCALL_REQUIRE((child = fork()) != -1); 1636 if (child == 0) { 1637 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1638 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1639 1640 sa.sa_sigaction = sah; 1641 sa.sa_flags = SA_SIGINFO; 1642 sigemptyset(&sa.sa_mask); 1643 1644 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 1645 != -1); 1646 1647 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1648 FORKEE_ASSERT(raise(sigval) == 0); 1649 1650 FORKEE_ASSERT_EQ(*signal_caught, 1); 1651 1652 DPRINTF("Before exiting of the child process\n"); 1653 _exit(exitval); 1654 } 1655 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1656 1657 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1658 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1659 1660 validate_status_stopped(status, sigval); 1661 1662 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1663 SYSCALL_REQUIRE( 1664 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1665 1666 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1667 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1668 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1669 info.psi_siginfo.si_errno); 1670 1671 if (faked) { 1672 DPRINTF("Before setting new faked signal to signo=%d " 1673 "si_code=%d\n", sigfaked, sicodefaked); 1674 info.psi_siginfo.si_signo = sigfaked; 1675 info.psi_siginfo.si_code = sicodefaked; 1676 } 1677 1678 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 1679 SYSCALL_REQUIRE( 1680 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 1681 1682 if (faked) { 1683 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1684 "child\n"); 1685 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1686 sizeof(info)) != -1); 1687 1688 DPRINTF("Before checking siginfo_t\n"); 1689 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 1690 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 1691 } 1692 1693 DPRINTF("Before resuming the child process where it left off and " 1694 "without signal to be sent\n"); 1695 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 1696 faked ? sigfaked : sigval) != -1); 1697 1698 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1699 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1700 1701 validate_status_exited(status, exitval); 1702 1703 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1704 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1705} 1706 1707#define PTRACE_SIGINFO(test, faked) \ 1708ATF_TC(test); \ 1709ATF_TC_HEAD(test, tc) \ 1710{ \ 1711 atf_tc_set_md_var(tc, "descr", \ 1712 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 1713 "with%s setting signal to new value", faked ? "" : "out"); \ 1714} \ 1715 \ 1716static int test##_caught = 0; \ 1717 \ 1718static void \ 1719test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 1720{ \ 1721 if (faked) { \ 1722 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 1723 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 1724 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 1725 } else { \ 1726 FORKEE_ASSERT_EQ(sig, SIGINT); \ 1727 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 1728 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 1729 } \ 1730 \ 1731 ++ test##_caught; \ 1732} \ 1733 \ 1734ATF_TC_BODY(test, tc) \ 1735{ \ 1736 \ 1737 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 1738} 1739 1740PTRACE_SIGINFO(siginfo_set_unmodified, false) 1741PTRACE_SIGINFO(siginfo_set_faked, true) 1742 1743/// ---------------------------------------------------------------------------- 1744 1745static void 1746traceme_exec(bool masked, bool ignored) 1747{ 1748 const int sigval = SIGTRAP; 1749 pid_t child, wpid; 1750#if defined(TWAIT_HAVE_STATUS) 1751 int status; 1752#endif 1753 struct sigaction sa; 1754 struct ptrace_siginfo info; 1755 sigset_t intmask; 1756 struct kinfo_proc2 kp; 1757 size_t len = sizeof(kp); 1758 1759 int name[6]; 1760 const size_t namelen = __arraycount(name); 1761 ki_sigset_t kp_sigmask; 1762 ki_sigset_t kp_sigignore; 1763 1764 memset(&info, 0, sizeof(info)); 1765 1766 DPRINTF("Before forking process PID=%d\n", getpid()); 1767 SYSCALL_REQUIRE((child = fork()) != -1); 1768 if (child == 0) { 1769 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1770 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1771 1772 if (masked) { 1773 sigemptyset(&intmask); 1774 sigaddset(&intmask, sigval); 1775 sigprocmask(SIG_BLOCK, &intmask, NULL); 1776 } 1777 1778 if (ignored) { 1779 memset(&sa, 0, sizeof(sa)); 1780 sa.sa_handler = SIG_IGN; 1781 sigemptyset(&sa.sa_mask); 1782 FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); 1783 } 1784 1785 DPRINTF("Before calling execve(2) from child\n"); 1786 execlp("/bin/echo", "/bin/echo", NULL); 1787 1788 FORKEE_ASSERT(0 && "Not reached"); 1789 } 1790 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1791 1792 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1793 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1794 1795 validate_status_stopped(status, sigval); 1796 1797 name[0] = CTL_KERN, 1798 name[1] = KERN_PROC2, 1799 name[2] = KERN_PROC_PID; 1800 name[3] = getpid(); 1801 name[4] = sizeof(kp); 1802 name[5] = 1; 1803 1804 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1805 1806 if (masked) 1807 kp_sigmask = kp.p_sigmask; 1808 1809 if (ignored) 1810 kp_sigignore = kp.p_sigignore; 1811 1812 name[3] = getpid(); 1813 1814 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1815 1816 if (masked) { 1817 DPRINTF("kp_sigmask=" 1818 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1819 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 1820 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 1821 1822 DPRINTF("kp.p_sigmask=" 1823 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1824 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 1825 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 1826 1827 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 1828 sizeof(kp_sigmask))); 1829 } 1830 1831 if (ignored) { 1832 DPRINTF("kp_sigignore=" 1833 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1834 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 1835 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 1836 1837 DPRINTF("kp.p_sigignore=" 1838 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 1839 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 1840 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 1841 1842 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 1843 sizeof(kp_sigignore))); 1844 } 1845 1846 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1847 SYSCALL_REQUIRE( 1848 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1849 1850 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1851 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1852 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1853 info.psi_siginfo.si_errno); 1854 1855 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1856 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1857 1858 DPRINTF("Before resuming the child process where it left off and " 1859 "without signal to be sent\n"); 1860 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1861 1862 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1863 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1864 1865 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1866 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1867} 1868 1869#define TRACEME_EXEC(test, masked, ignored) \ 1870ATF_TC(test); \ 1871ATF_TC_HEAD(test, tc) \ 1872{ \ 1873 atf_tc_set_md_var(tc, "descr", \ 1874 "Detect SIGTRAP TRAP_EXEC from " \ 1875 "child%s%s", masked ? " with masked signal" : "", \ 1876 masked ? " with ignored signal" : ""); \ 1877} \ 1878 \ 1879ATF_TC_BODY(test, tc) \ 1880{ \ 1881 \ 1882 traceme_exec(masked, ignored); \ 1883} 1884 1885TRACEME_EXEC(traceme_exec, false, false) 1886TRACEME_EXEC(traceme_signalmasked_exec, true, false) 1887TRACEME_EXEC(traceme_signalignored_exec, false, true) 1888 1889/// ---------------------------------------------------------------------------- 1890 1891#define TRACE_THREADS_NUM 100 1892 1893static volatile int done; 1894pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER; 1895 1896static void * 1897trace_threads_cb(void *arg __unused) 1898{ 1899 1900 pthread_mutex_lock(&trace_threads_mtx); 1901 done++; 1902 pthread_mutex_unlock(&trace_threads_mtx); 1903 1904 while (done < TRACE_THREADS_NUM) 1905 sched_yield(); 1906 1907 return NULL; 1908} 1909 1910static void 1911trace_threads(bool trace_create, bool trace_exit, bool masked) 1912{ 1913 const int sigval = SIGSTOP; 1914 pid_t child, wpid; 1915#if defined(TWAIT_HAVE_STATUS) 1916 int status; 1917#endif 1918 ptrace_state_t state; 1919 const int slen = sizeof(state); 1920 ptrace_event_t event; 1921 const int elen = sizeof(event); 1922 struct ptrace_siginfo info; 1923 1924 sigset_t intmask; 1925 1926 pthread_t t[TRACE_THREADS_NUM]; 1927 int rv; 1928 size_t n; 1929 lwpid_t lid; 1930 1931 /* Track created and exited threads */ 1932 struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}}; 1933 1934 DPRINTF("Before forking process PID=%d\n", getpid()); 1935 SYSCALL_REQUIRE((child = fork()) != -1); 1936 if (child == 0) { 1937 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1938 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1939 1940 if (masked) { 1941 sigemptyset(&intmask); 1942 sigaddset(&intmask, SIGTRAP); 1943 sigprocmask(SIG_BLOCK, &intmask, NULL); 1944 } 1945 1946 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1947 FORKEE_ASSERT(raise(sigval) == 0); 1948 1949 for (n = 0; n < __arraycount(t); n++) { 1950 rv = pthread_create(&t[n], NULL, trace_threads_cb, 1951 NULL); 1952 FORKEE_ASSERT(rv == 0); 1953 } 1954 1955 for (n = 0; n < __arraycount(t); n++) { 1956 rv = pthread_join(t[n], NULL); 1957 FORKEE_ASSERT(rv == 0); 1958 } 1959 1960 /* 1961 * There is race between _exit() and pthread_join() detaching 1962 * a thread. For simplicity kill the process after detecting 1963 * LWP events. 1964 */ 1965 while (true) 1966 continue; 1967 1968 FORKEE_ASSERT(0 && "Not reached"); 1969 } 1970 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1971 1972 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1973 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1974 1975 validate_status_stopped(status, sigval); 1976 1977 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1978 SYSCALL_REQUIRE( 1979 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1980 1981 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1982 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1983 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1984 info.psi_siginfo.si_errno); 1985 1986 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1987 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1988 1989 DPRINTF("Set LWP event mask for the child %d\n", child); 1990 memset(&event, 0, sizeof(event)); 1991 if (trace_create) 1992 event.pe_set_event |= PTRACE_LWP_CREATE; 1993 if (trace_exit) 1994 event.pe_set_event |= PTRACE_LWP_EXIT; 1995 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1996 1997 DPRINTF("Before resuming the child process where it left off and " 1998 "without signal to be sent\n"); 1999 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2000 2001 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 2002 DPRINTF("Before calling %s() for the child - expected stopped " 2003 "SIGTRAP\n", TWAIT_FNAME); 2004 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2005 child); 2006 2007 validate_status_stopped(status, SIGTRAP); 2008 2009 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2010 "child\n"); 2011 SYSCALL_REQUIRE( 2012 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2013 2014 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2015 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2016 "si_errno=%#x\n", 2017 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2018 info.psi_siginfo.si_errno); 2019 2020 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2021 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 2022 2023 SYSCALL_REQUIRE( 2024 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2025 2026 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 2027 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 2028 2029 lid = state.pe_lwp; 2030 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 2031 2032 *FIND_EVENT_COUNT(traced_lwps, lid) += 1; 2033 2034 DPRINTF("Before resuming the child process where it left off " 2035 "and without signal to be sent\n"); 2036 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2037 } 2038 2039 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 2040 DPRINTF("Before calling %s() for the child - expected stopped " 2041 "SIGTRAP\n", TWAIT_FNAME); 2042 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2043 child); 2044 2045 validate_status_stopped(status, SIGTRAP); 2046 2047 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2048 "child\n"); 2049 SYSCALL_REQUIRE( 2050 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2051 2052 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2053 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2054 "si_errno=%#x\n", 2055 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2056 info.psi_siginfo.si_errno); 2057 2058 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2059 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 2060 2061 SYSCALL_REQUIRE( 2062 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2063 2064 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 2065 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 2066 2067 lid = state.pe_lwp; 2068 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 2069 2070 if (trace_create) { 2071 int *count = FIND_EVENT_COUNT(traced_lwps, lid); 2072 ATF_REQUIRE_EQ(*count, 1); 2073 *count = 0; 2074 } 2075 2076 DPRINTF("Before resuming the child process where it left off " 2077 "and without signal to be sent\n"); 2078 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2079 } 2080 2081 kill(child, SIGKILL); 2082 2083 DPRINTF("Before calling %s() for the child - expected exited\n", 2084 TWAIT_FNAME); 2085 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2086 2087 validate_status_signaled(status, SIGKILL, 0); 2088 2089 DPRINTF("Before calling %s() for the child - expected no process\n", 2090 TWAIT_FNAME); 2091 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2092} 2093 2094#define TRACE_THREADS(test, trace_create, trace_exit, mask) \ 2095ATF_TC(test); \ 2096ATF_TC_HEAD(test, tc) \ 2097{ \ 2098 atf_tc_set_md_var(tc, "descr", \ 2099 "Verify spawning threads with%s tracing LWP create and" \ 2100 "with%s tracing LWP exit", trace_create ? "" : "out", \ 2101 trace_exit ? "" : "out"); \ 2102} \ 2103 \ 2104ATF_TC_BODY(test, tc) \ 2105{ \ 2106 \ 2107 trace_threads(trace_create, trace_exit, mask); \ 2108} 2109 2110TRACE_THREADS(trace_thread_nolwpevents, false, false, false) 2111TRACE_THREADS(trace_thread_lwpexit, false, true, false) 2112TRACE_THREADS(trace_thread_lwpcreate, true, false, false) 2113TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false) 2114 2115TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true) 2116TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true) 2117TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true) 2118 2119/// ---------------------------------------------------------------------------- 2120 2121static void * 2122thread_and_exec_thread_cb(void *arg __unused) 2123{ 2124 2125 execlp("/bin/echo", "/bin/echo", NULL); 2126 2127 abort(); 2128} 2129 2130static void 2131threads_and_exec(void) 2132{ 2133 const int sigval = SIGSTOP; 2134 pid_t child, wpid; 2135#if defined(TWAIT_HAVE_STATUS) 2136 int status; 2137#endif 2138 ptrace_state_t state; 2139 const int slen = sizeof(state); 2140 ptrace_event_t event; 2141 const int elen = sizeof(event); 2142 struct ptrace_siginfo info; 2143 2144 pthread_t t; 2145 lwpid_t lid; 2146 2147 DPRINTF("Before forking process PID=%d\n", getpid()); 2148 SYSCALL_REQUIRE((child = fork()) != -1); 2149 if (child == 0) { 2150 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2151 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2152 2153 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2154 FORKEE_ASSERT(raise(sigval) == 0); 2155 2156 FORKEE_ASSERT(pthread_create(&t, NULL, 2157 thread_and_exec_thread_cb, NULL) == 0); 2158 2159 for (;;) 2160 continue; 2161 2162 FORKEE_ASSERT(0 && "Not reached"); 2163 } 2164 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2165 2166 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2167 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2168 2169 validate_status_stopped(status, sigval); 2170 2171 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 2172 SYSCALL_REQUIRE( 2173 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2174 2175 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2176 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 2177 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2178 info.psi_siginfo.si_errno); 2179 2180 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 2181 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2182 2183 DPRINTF("Set LWP event mask for the child %d\n", child); 2184 memset(&event, 0, sizeof(event)); 2185 event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT; 2186 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 2187 2188 DPRINTF("Before resuming the child process where it left off and " 2189 "without signal to be sent\n"); 2190 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2191 2192 DPRINTF("Before calling %s() for the child - expected stopped " 2193 "SIGTRAP\n", TWAIT_FNAME); 2194 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2195 child); 2196 2197 validate_status_stopped(status, SIGTRAP); 2198 2199 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2200 "child\n"); 2201 SYSCALL_REQUIRE( 2202 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2203 2204 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2205 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2206 "si_errno=%#x\n", 2207 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2208 info.psi_siginfo.si_errno); 2209 2210 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2211 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 2212 2213 SYSCALL_REQUIRE( 2214 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2215 2216 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 2217 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 2218 2219 lid = state.pe_lwp; 2220 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 2221 2222 DPRINTF("Before resuming the child process where it left off " 2223 "and without signal to be sent\n"); 2224 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2225 2226 DPRINTF("Before calling %s() for the child - expected stopped " 2227 "SIGTRAP\n", TWAIT_FNAME); 2228 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2229 child); 2230 2231 validate_status_stopped(status, SIGTRAP); 2232 2233 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2234 "child\n"); 2235 SYSCALL_REQUIRE( 2236 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2237 2238 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2239 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2240 "si_errno=%#x\n", 2241 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2242 info.psi_siginfo.si_errno); 2243 2244 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2245 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 2246 2247 SYSCALL_REQUIRE( 2248 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2249 2250 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 2251 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 2252 2253 lid = state.pe_lwp; 2254 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 2255 2256 DPRINTF("Before resuming the child process where it left off " 2257 "and without signal to be sent\n"); 2258 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2259 2260 DPRINTF("Before calling %s() for the child - expected stopped " 2261 "SIGTRAP\n", TWAIT_FNAME); 2262 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2263 child); 2264 2265 validate_status_stopped(status, SIGTRAP); 2266 2267 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2268 "child\n"); 2269 SYSCALL_REQUIRE( 2270 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2271 2272 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2273 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2274 "si_errno=%#x\n", 2275 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2276 info.psi_siginfo.si_errno); 2277 2278 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 2279 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 2280 2281 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2282 2283 DPRINTF("Before calling %s() for the child - expected exited\n", 2284 TWAIT_FNAME); 2285 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2286 2287 validate_status_signaled(status, SIGKILL, 0); 2288 2289 DPRINTF("Before calling %s() for the child - expected no process\n", 2290 TWAIT_FNAME); 2291 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2292} 2293 2294ATF_TC(threads_and_exec); 2295ATF_TC_HEAD(threads_and_exec, tc) 2296{ 2297 atf_tc_set_md_var(tc, "descr", 2298 "Verify that multithreaded application on exec() will report " 2299 "LWP_EXIT events"); 2300} 2301 2302ATF_TC_BODY(threads_and_exec, tc) 2303{ 2304 2305 threads_and_exec(); 2306} 2307 2308/// ---------------------------------------------------------------------------- 2309 2310ATF_TC(suspend_no_deadlock); 2311ATF_TC_HEAD(suspend_no_deadlock, tc) 2312{ 2313 atf_tc_set_md_var(tc, "descr", 2314 "Verify that the while the only thread within a process is " 2315 "suspended, the whole process cannot be unstopped"); 2316} 2317 2318ATF_TC_BODY(suspend_no_deadlock, tc) 2319{ 2320 const int exitval = 5; 2321 const int sigval = SIGSTOP; 2322 pid_t child, wpid; 2323#if defined(TWAIT_HAVE_STATUS) 2324 int status; 2325#endif 2326 struct ptrace_siginfo psi; 2327 2328 DPRINTF("Before forking process PID=%d\n", getpid()); 2329 SYSCALL_REQUIRE((child = fork()) != -1); 2330 if (child == 0) { 2331 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2332 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2333 2334 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2335 FORKEE_ASSERT(raise(sigval) == 0); 2336 2337 DPRINTF("Before exiting of the child process\n"); 2338 _exit(exitval); 2339 } 2340 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2341 2342 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2343 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2344 2345 validate_status_stopped(status, sigval); 2346 2347 DPRINTF("Before reading siginfo and lwpid_t\n"); 2348 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 2349 2350 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 2351 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 2352 2353 DPRINTF("Before resuming the child process where it left off and " 2354 "without signal to be sent\n"); 2355 ATF_REQUIRE_ERRNO(EDEADLK, 2356 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 2357 2358 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 2359 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 2360 2361 DPRINTF("Before resuming the child process where it left off and " 2362 "without signal to be sent\n"); 2363 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2364 2365 DPRINTF("Before calling %s() for the child - expected exited\n", 2366 TWAIT_FNAME); 2367 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2368 2369 validate_status_exited(status, exitval); 2370 2371 DPRINTF("Before calling %s() for the child - expected no process\n", 2372 TWAIT_FNAME); 2373 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2374} 2375 2376/// ---------------------------------------------------------------------------- 2377 2378static pthread_barrier_t barrier1_resume; 2379static pthread_barrier_t barrier2_resume; 2380 2381static void * 2382resume_thread(void *arg) 2383{ 2384 2385 raise(SIGUSR1); 2386 2387 pthread_barrier_wait(&barrier1_resume); 2388 2389 /* Debugger will suspend the process here */ 2390 2391 pthread_barrier_wait(&barrier2_resume); 2392 2393 raise(SIGUSR2); 2394 2395 return infinite_thread(arg); 2396} 2397 2398ATF_TC(resume); 2399ATF_TC_HEAD(resume, tc) 2400{ 2401 atf_tc_set_md_var(tc, "descr", 2402 "Verify that a thread can be suspended by a debugger and later " 2403 "resumed by the debugger"); 2404} 2405 2406ATF_TC_BODY(resume, tc) 2407{ 2408 const int sigval = SIGSTOP; 2409 pid_t child, wpid; 2410#if defined(TWAIT_HAVE_STATUS) 2411 int status; 2412#endif 2413 lwpid_t lid; 2414 struct ptrace_siginfo psi; 2415 pthread_t t; 2416 2417 DPRINTF("Before forking process PID=%d\n", getpid()); 2418 SYSCALL_REQUIRE((child = fork()) != -1); 2419 if (child == 0) { 2420 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2421 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2422 2423 pthread_barrier_init(&barrier1_resume, NULL, 2); 2424 pthread_barrier_init(&barrier2_resume, NULL, 2); 2425 2426 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2427 FORKEE_ASSERT(raise(sigval) == 0); 2428 2429 DPRINTF("Before creating new thread in child\n"); 2430 FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0); 2431 2432 pthread_barrier_wait(&barrier1_resume); 2433 2434 pthread_barrier_wait(&barrier2_resume); 2435 2436 infinite_thread(NULL); 2437 } 2438 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2439 2440 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2441 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2442 2443 validate_status_stopped(status, sigval); 2444 2445 DPRINTF("Before resuming the child process where it left off and " 2446 "without signal to be sent\n"); 2447 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2448 2449 DPRINTF("Before calling %s() for the child - expected stopped " 2450 "SIGUSR1\n", TWAIT_FNAME); 2451 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2452 2453 validate_status_stopped(status, SIGUSR1); 2454 2455 DPRINTF("Before reading siginfo and lwpid_t\n"); 2456 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 2457 2458 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 2459 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 2460 2461 lid = psi.psi_lwpid; 2462 2463 DPRINTF("Before resuming the child process where it left off and " 2464 "without signal to be sent\n"); 2465 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2466 2467 DPRINTF("Before suspending the parent for 1 second, we expect no signals\n"); 2468 SYSCALL_REQUIRE(sleep(1) == 0); 2469 2470#if defined(TWAIT_HAVE_OPTIONS) 2471 DPRINTF("Before calling %s() for the child - expected no status\n", 2472 TWAIT_FNAME); 2473 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0); 2474#endif 2475 2476 DPRINTF("Before resuming the child process where it left off and " 2477 "without signal to be sent\n"); 2478 SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1); 2479 2480 DPRINTF("Before calling %s() for the child - expected stopped " 2481 "SIGSTOP\n", TWAIT_FNAME); 2482 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2483 2484 validate_status_stopped(status, SIGSTOP); 2485 2486 DPRINTF("Before resuming LWP %d\n", lid); 2487 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1); 2488 2489 DPRINTF("Before resuming the child process where it left off and " 2490 "without signal to be sent\n"); 2491 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2492 2493 DPRINTF("Before calling %s() for the child - expected stopped " 2494 "SIGUSR2\n", TWAIT_FNAME); 2495 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2496 2497 validate_status_stopped(status, SIGUSR2); 2498 2499 DPRINTF("Before resuming the child process where it left off and " 2500 "without signal to be sent\n"); 2501 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 2502 2503 DPRINTF("Before calling %s() for the child - expected exited\n", 2504 TWAIT_FNAME); 2505 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2506 2507 validate_status_signaled(status, SIGKILL, 0); 2508 2509 DPRINTF("Before calling %s() for the child - expected no process\n", 2510 TWAIT_FNAME); 2511 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2512} 2513 2514/// ---------------------------------------------------------------------------- 2515 2516static void 2517user_va0_disable(int operation) 2518{ 2519 pid_t child, wpid; 2520#if defined(TWAIT_HAVE_STATUS) 2521 int status; 2522#endif 2523 const int sigval = SIGSTOP; 2524 int rv; 2525 2526 struct ptrace_siginfo info; 2527 2528 if (get_user_va0_disable() == 0) 2529 atf_tc_skip("vm.user_va0_disable is set to 0"); 2530 2531 memset(&info, 0, sizeof(info)); 2532 2533 DPRINTF("Before forking process PID=%d\n", getpid()); 2534 SYSCALL_REQUIRE((child = fork()) != -1); 2535 if (child == 0) { 2536 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2537 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2538 2539 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2540 FORKEE_ASSERT(raise(sigval) == 0); 2541 2542 /* NOTREACHED */ 2543 FORKEE_ASSERTX(0 && "This shall not be reached"); 2544 __unreachable(); 2545 } 2546 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2547 2548 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2549 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2550 2551 validate_status_stopped(status, sigval); 2552 2553 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 2554 "child\n"); 2555 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 2556 sizeof(info)) != -1); 2557 2558 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2559 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 2560 "si_errno=%#x\n", 2561 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2562 info.psi_siginfo.si_errno); 2563 2564 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 2565 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2566 2567 DPRINTF("Before resuming the child process in PC=0x0 " 2568 "and without signal to be sent\n"); 2569 errno = 0; 2570 rv = ptrace(operation, child, (void *)0, 0); 2571 ATF_REQUIRE_EQ(errno, EINVAL); 2572 ATF_REQUIRE_EQ(rv, -1); 2573 2574 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2575 2576 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2577 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2578 validate_status_signaled(status, SIGKILL, 0); 2579 2580 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2581 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2582} 2583 2584#define USER_VA0_DISABLE(test, operation) \ 2585ATF_TC(test); \ 2586ATF_TC_HEAD(test, tc) \ 2587{ \ 2588 atf_tc_set_md_var(tc, "descr", \ 2589 "Verify behavior of " #operation " with PC set to 0x0"); \ 2590} \ 2591 \ 2592ATF_TC_BODY(test, tc) \ 2593{ \ 2594 \ 2595 user_va0_disable(operation); \ 2596} 2597 2598USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 2599USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 2600USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 2601 2602/// ---------------------------------------------------------------------------- 2603 2604/* 2605 * Parse the core file and find the requested note. If the reading or parsing 2606 * fails, the test is failed. If the note is found, it is read onto buf, up to 2607 * buf_len. The actual length of the note is returned (which can be greater 2608 * than buf_len, indicating that it has been truncated). If the note is not 2609 * found, -1 is returned. 2610 * 2611 * If the note_name ends in '*', then we find the first note that matches 2612 * the note_name prefix up to the '*' character, e.g.: 2613 * 2614 * NetBSD-CORE@* 2615 * 2616 * finds the first note whose name prefix matches "NetBSD-CORE@". 2617 */ 2618static ssize_t core_find_note(const char *core_path, 2619 const char *note_name, uint64_t note_type, void *buf, size_t buf_len) 2620{ 2621 int core_fd; 2622 Elf *core_elf; 2623 size_t core_numhdr, i; 2624 ssize_t ret = -1; 2625 size_t name_len = strlen(note_name); 2626 bool prefix_match = false; 2627 2628 if (note_name[name_len - 1] == '*') { 2629 prefix_match = true; 2630 name_len--; 2631 } else { 2632 /* note: we assume note name will be null-terminated */ 2633 name_len++; 2634 } 2635 2636 SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1); 2637 SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE); 2638 SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL))); 2639 2640 SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0); 2641 for (i = 0; i < core_numhdr && ret == -1; i++) { 2642 GElf_Phdr core_hdr; 2643 size_t offset; 2644 SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr)); 2645 if (core_hdr.p_type != PT_NOTE) 2646 continue; 2647 2648 for (offset = core_hdr.p_offset; 2649 offset < core_hdr.p_offset + core_hdr.p_filesz;) { 2650 Elf64_Nhdr note_hdr; 2651 char name_buf[64]; 2652 2653 switch (gelf_getclass(core_elf)) { 2654 case ELFCLASS64: 2655 SYSCALL_REQUIRE(pread(core_fd, ¬e_hdr, 2656 sizeof(note_hdr), offset) 2657 == sizeof(note_hdr)); 2658 offset += sizeof(note_hdr); 2659 break; 2660 case ELFCLASS32: 2661 { 2662 Elf32_Nhdr tmp_hdr; 2663 SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr, 2664 sizeof(tmp_hdr), offset) 2665 == sizeof(tmp_hdr)); 2666 offset += sizeof(tmp_hdr); 2667 note_hdr.n_namesz = tmp_hdr.n_namesz; 2668 note_hdr.n_descsz = tmp_hdr.n_descsz; 2669 note_hdr.n_type = tmp_hdr.n_type; 2670 } 2671 break; 2672 } 2673 2674 /* indicates end of notes */ 2675 if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0) 2676 break; 2677 if (((prefix_match && 2678 note_hdr.n_namesz > name_len) || 2679 (!prefix_match && 2680 note_hdr.n_namesz == name_len)) && 2681 note_hdr.n_namesz <= sizeof(name_buf)) { 2682 SYSCALL_REQUIRE(pread(core_fd, name_buf, 2683 note_hdr.n_namesz, offset) 2684 == (ssize_t)(size_t)note_hdr.n_namesz); 2685 2686 if (!strncmp(note_name, name_buf, name_len) && 2687 note_hdr.n_type == note_type) 2688 ret = note_hdr.n_descsz; 2689 } 2690 2691 offset += note_hdr.n_namesz; 2692 /* fix to alignment */ 2693 offset = roundup(offset, core_hdr.p_align); 2694 2695 /* if name & type matched above */ 2696 if (ret != -1) { 2697 ssize_t read_len = MIN(buf_len, 2698 note_hdr.n_descsz); 2699 SYSCALL_REQUIRE(pread(core_fd, buf, 2700 read_len, offset) == read_len); 2701 break; 2702 } 2703 2704 offset += note_hdr.n_descsz; 2705 /* fix to alignment */ 2706 offset = roundup(offset, core_hdr.p_align); 2707 } 2708 } 2709 2710 elf_end(core_elf); 2711 close(core_fd); 2712 2713 return ret; 2714} 2715 2716ATF_TC(core_dump_procinfo); 2717ATF_TC_HEAD(core_dump_procinfo, tc) 2718{ 2719 atf_tc_set_md_var(tc, "descr", 2720 "Trigger a core dump and verify its contents."); 2721} 2722 2723ATF_TC_BODY(core_dump_procinfo, tc) 2724{ 2725 const int exitval = 5; 2726 pid_t child, wpid; 2727#if defined(TWAIT_HAVE_STATUS) 2728 const int sigval = SIGTRAP; 2729 int status; 2730#endif 2731 char core_path[] = "/tmp/core.XXXXXX"; 2732 int core_fd; 2733 struct netbsd_elfcore_procinfo procinfo; 2734 2735 DPRINTF("Before forking process PID=%d\n", getpid()); 2736 SYSCALL_REQUIRE((child = fork()) != -1); 2737 if (child == 0) { 2738 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2739 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2740 2741 DPRINTF("Before triggering SIGTRAP\n"); 2742 trigger_trap(); 2743 2744 DPRINTF("Before exiting of the child process\n"); 2745 _exit(exitval); 2746 } 2747 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2748 2749 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2750 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2751 2752 validate_status_stopped(status, sigval); 2753 2754 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 2755 close(core_fd); 2756 2757 DPRINTF("Call DUMPCORE for the child process\n"); 2758 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path)) 2759 != -1); 2760 2761 DPRINTF("Read core file\n"); 2762 ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE", 2763 ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)), 2764 sizeof(procinfo)); 2765 2766 ATF_CHECK_EQ(procinfo.cpi_version, 1); 2767 ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo)); 2768 ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP); 2769 ATF_CHECK_EQ(procinfo.cpi_pid, child); 2770 ATF_CHECK_EQ(procinfo.cpi_ppid, getpid()); 2771 ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child)); 2772 ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child)); 2773 ATF_CHECK_EQ(procinfo.cpi_ruid, getuid()); 2774 ATF_CHECK_EQ(procinfo.cpi_euid, geteuid()); 2775 ATF_CHECK_EQ(procinfo.cpi_rgid, getgid()); 2776 ATF_CHECK_EQ(procinfo.cpi_egid, getegid()); 2777 ATF_CHECK_EQ(procinfo.cpi_nlwps, 1); 2778 ATF_CHECK(procinfo.cpi_siglwp > 0); 2779 2780 unlink(core_path); 2781 2782 DPRINTF("Before resuming the child process where it left off and " 2783 "without signal to be sent\n"); 2784 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2785 2786 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2787 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2788 2789 validate_status_exited(status, exitval); 2790 2791 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2792 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2793} 2794 2795/// ---------------------------------------------------------------------------- 2796 2797#if defined(TWAIT_HAVE_STATUS) 2798 2799#define THREAD_CONCURRENT_BREAKPOINT_NUM 50 2800#define THREAD_CONCURRENT_SIGNALS_NUM 50 2801#define THREAD_CONCURRENT_WATCHPOINT_NUM 50 2802 2803/* List of signals to use for the test */ 2804const int thread_concurrent_signals_list[] = { 2805 SIGIO, 2806 SIGXCPU, 2807 SIGXFSZ, 2808 SIGVTALRM, 2809 SIGPROF, 2810 SIGWINCH, 2811 SIGINFO, 2812 SIGUSR1, 2813 SIGUSR2 2814}; 2815 2816enum thread_concurrent_signal_handling { 2817 /* the signal is discarded by debugger */ 2818 TCSH_DISCARD, 2819 /* the handler is set to SIG_IGN */ 2820 TCSH_SIG_IGN, 2821 /* an actual handler is used */ 2822 TCSH_HANDLER 2823}; 2824 2825static pthread_barrier_t thread_concurrent_barrier; 2826static pthread_key_t thread_concurrent_key; 2827static uint32_t thread_concurrent_watchpoint_var = 0; 2828 2829static void * 2830thread_concurrent_breakpoint_thread(void *arg) 2831{ 2832 static volatile int watchme = 1; 2833 pthread_barrier_wait(&thread_concurrent_barrier); 2834 DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self()); 2835 check_happy(watchme); 2836 return NULL; 2837} 2838 2839static void 2840thread_concurrent_sig_handler(int sig) 2841{ 2842 void *tls_val = pthread_getspecific(thread_concurrent_key); 2843 DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 2844 FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key, 2845 (void*)((uintptr_t)tls_val + 1)) == 0); 2846} 2847 2848static void * 2849thread_concurrent_signals_thread(void *arg) 2850{ 2851 int sigval = thread_concurrent_signals_list[ 2852 _lwp_self() % __arraycount(thread_concurrent_signals_list)]; 2853 enum thread_concurrent_signal_handling *signal_handle = arg; 2854 void *tls_val; 2855 2856 pthread_barrier_wait(&thread_concurrent_barrier); 2857 DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval), 2858 _lwp_self()); 2859 pthread_kill(pthread_self(), sigval); 2860 if (*signal_handle == TCSH_HANDLER) { 2861 tls_val = pthread_getspecific(thread_concurrent_key); 2862 DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val); 2863 FORKEE_ASSERT(tls_val == (void*)1); 2864 } 2865 return NULL; 2866} 2867 2868static void * 2869thread_concurrent_watchpoint_thread(void *arg) 2870{ 2871 pthread_barrier_wait(&thread_concurrent_barrier); 2872 DPRINTF("Before modifying var from LWP %d\n", _lwp_self()); 2873 thread_concurrent_watchpoint_var = 1; 2874 return NULL; 2875} 2876 2877#if defined(__i386__) || defined(__x86_64__) 2878enum thread_concurrent_sigtrap_event { 2879 TCSE_UNKNOWN, 2880 TCSE_BREAKPOINT, 2881 TCSE_WATCHPOINT 2882}; 2883 2884static void 2885thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid); 2886static enum thread_concurrent_sigtrap_event 2887thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info); 2888#endif 2889 2890static void 2891thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle, 2892 int breakpoint_threads, int signal_threads, int watchpoint_threads) 2893{ 2894 const int exitval = 5; 2895 const int sigval = SIGSTOP; 2896 pid_t child, wpid; 2897 int status; 2898 struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] 2899 = {{0, 0}}; 2900 struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 2901 = {{0, 0}}; 2902 struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM] 2903 = {{0, 0}}; 2904 ptrace_event_t event; 2905 int i; 2906 2907#if defined(HAVE_DBREGS) 2908 if (!can_we_set_dbregs()) { 2909 atf_tc_skip("Either run this test as root or set sysctl(3) " 2910 "security.models.extensions.user_set_dbregs to 1"); 2911 } 2912#endif 2913 2914 atf_tc_skip("PR kern/54960"); 2915 2916 /* Protect against out-of-bounds array access. */ 2917 ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM); 2918 ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM); 2919 ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM); 2920 2921 DPRINTF("Before forking process PID=%d\n", getpid()); 2922 SYSCALL_REQUIRE((child = fork()) != -1); 2923 if (child == 0) { 2924 pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM]; 2925 pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM]; 2926 pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM]; 2927 2928 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2929 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2930 2931 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2932 FORKEE_ASSERT(raise(sigval) == 0); 2933 2934 if (signal_handle != TCSH_DISCARD) { 2935 struct sigaction sa; 2936 unsigned int j; 2937 2938 memset(&sa, 0, sizeof(sa)); 2939 if (signal_handle == TCSH_SIG_IGN) 2940 sa.sa_handler = SIG_IGN; 2941 else 2942 sa.sa_handler = thread_concurrent_sig_handler; 2943 sigemptyset(&sa.sa_mask); 2944 2945 for (j = 0; 2946 j < __arraycount(thread_concurrent_signals_list); 2947 j++) 2948 FORKEE_ASSERT(sigaction( 2949 thread_concurrent_signals_list[j], &sa, NULL) 2950 != -1); 2951 } 2952 2953 DPRINTF("Before starting threads from the child\n"); 2954 FORKEE_ASSERT(pthread_barrier_init( 2955 &thread_concurrent_barrier, NULL, 2956 breakpoint_threads + signal_threads + watchpoint_threads) 2957 == 0); 2958 FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL) 2959 == 0); 2960 2961 for (i = 0; i < signal_threads; i++) { 2962 FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL, 2963 thread_concurrent_signals_thread, 2964 &signal_handle) == 0); 2965 } 2966 for (i = 0; i < breakpoint_threads; i++) { 2967 FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL, 2968 thread_concurrent_breakpoint_thread, NULL) == 0); 2969 } 2970 for (i = 0; i < watchpoint_threads; i++) { 2971 FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL, 2972 thread_concurrent_watchpoint_thread, NULL) == 0); 2973 } 2974 2975 DPRINTF("Before joining threads from the child\n"); 2976 for (i = 0; i < watchpoint_threads; i++) { 2977 FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0); 2978 } 2979 for (i = 0; i < breakpoint_threads; i++) { 2980 FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0); 2981 } 2982 for (i = 0; i < signal_threads; i++) { 2983 FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0); 2984 } 2985 2986 FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0); 2987 FORKEE_ASSERT(pthread_barrier_destroy( 2988 &thread_concurrent_barrier) == 0); 2989 2990 DPRINTF("Before exiting of the child process\n"); 2991 _exit(exitval); 2992 } 2993 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2994 2995 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2996 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2997 2998 validate_status_stopped(status, sigval); 2999 3000 DPRINTF("Set LWP event mask for the child process\n"); 3001 memset(&event, 0, sizeof(event)); 3002 event.pe_set_event |= PTRACE_LWP_CREATE; 3003 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event)) 3004 != -1); 3005 3006 DPRINTF("Before resuming the child process where it left off\n"); 3007 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3008 3009 DPRINTF("Before entering signal collection loop\n"); 3010 while (1) { 3011 ptrace_siginfo_t info; 3012 3013 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3014 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3015 child); 3016 if (WIFEXITED(status)) 3017 break; 3018 /* Note: we use validate_status_stopped() to get nice error 3019 * message. Signal is irrelevant since it won't be reached. 3020 */ 3021 else if (!WIFSTOPPED(status)) 3022 validate_status_stopped(status, 0); 3023 3024 DPRINTF("Before calling PT_GET_SIGINFO\n"); 3025 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 3026 sizeof(info)) != -1); 3027 3028 DPRINTF("Received signal %d from LWP %d (wait: %d)\n", 3029 info.psi_siginfo.si_signo, info.psi_lwpid, 3030 WSTOPSIG(status)); 3031 3032 ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status), 3033 "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid, 3034 WSTOPSIG(status), info.psi_siginfo.si_signo); 3035 3036 if (WSTOPSIG(status) != SIGTRAP) { 3037 int expected_sig = 3038 thread_concurrent_signals_list[info.psi_lwpid % 3039 __arraycount(thread_concurrent_signals_list)]; 3040 ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig, 3041 "lwp=%d, expected %d, got %d", info.psi_lwpid, 3042 expected_sig, WSTOPSIG(status)); 3043 3044 *FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1; 3045 } else if (info.psi_siginfo.si_code == TRAP_LWP) { 3046#if defined(__i386__) || defined(__x86_64__) 3047 thread_concurrent_lwp_setup(child, info.psi_lwpid); 3048#endif 3049 } else { 3050#if defined(__i386__) || defined(__x86_64__) 3051 switch (thread_concurrent_handle_sigtrap(child, &info)) { 3052 case TCSE_UNKNOWN: 3053 /* already reported inside the function */ 3054 break; 3055 case TCSE_BREAKPOINT: 3056 *FIND_EVENT_COUNT(bp_counts, 3057 info.psi_lwpid) += 1; 3058 break; 3059 case TCSE_WATCHPOINT: 3060 *FIND_EVENT_COUNT(wp_counts, 3061 info.psi_lwpid) += 1; 3062 break; 3063 } 3064#else 3065 ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n", 3066 info.psi_siginfo.si_code); 3067#endif 3068 } 3069 3070 DPRINTF("Before resuming the child process\n"); 3071 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 3072 signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP 3073 ? WSTOPSIG(status) : 0) != -1); 3074 } 3075 3076 for (i = 0; i < signal_threads; i++) 3077 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1, 3078 "signal_counts[%d].lec_count=%d; lec_lwp=%d", 3079 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 3080 for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++) 3081 ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0, 3082 "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d", 3083 i, signal_counts[i].lec_count, signal_counts[i].lec_lwp); 3084 3085 for (i = 0; i < breakpoint_threads; i++) 3086 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1, 3087 "bp_counts[%d].lec_count=%d; lec_lwp=%d", 3088 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 3089 for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++) 3090 ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0, 3091 "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d", 3092 i, bp_counts[i].lec_count, bp_counts[i].lec_lwp); 3093 3094 for (i = 0; i < watchpoint_threads; i++) 3095 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1, 3096 "wp_counts[%d].lec_count=%d; lec_lwp=%d", 3097 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 3098 for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++) 3099 ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0, 3100 "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d", 3101 i, wp_counts[i].lec_count, wp_counts[i].lec_lwp); 3102 3103 validate_status_exited(status, exitval); 3104} 3105 3106#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr) \ 3107ATF_TC(test); \ 3108ATF_TC_HEAD(test, tc) \ 3109{ \ 3110 atf_tc_set_md_var(tc, "descr", descr); \ 3111} \ 3112 \ 3113ATF_TC_BODY(test, tc) \ 3114{ \ 3115 thread_concurrent_test(sig_hdl, bps, sigs, wps); \ 3116} 3117 3118THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD, 3119 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3120 "Verify that concurrent signals issued to a single thread are reported " 3121 "correctly"); 3122THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN, 3123 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3124 "Verify that concurrent signals issued to a single thread are reported " 3125 "correctly and passed back to SIG_IGN handler"); 3126THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER, 3127 0, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3128 "Verify that concurrent signals issued to a single thread are reported " 3129 "correctly and passed back to a handler function"); 3130 3131#if defined(__i386__) || defined(__x86_64__) 3132THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD, 3133 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0, 3134 "Verify that concurrent breakpoints are reported correctly"); 3135THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD, 3136 0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 3137 "Verify that concurrent breakpoints are reported correctly"); 3138THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD, 3139 THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM, 3140 "Verify that concurrent breakpoints and watchpoints are reported " 3141 "correctly"); 3142 3143THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD, 3144 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3145 "Verify that concurrent breakpoints and signals are reported correctly"); 3146THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN, 3147 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3148 "Verify that concurrent breakpoints and signals are reported correctly " 3149 "and passed back to SIG_IGN handler"); 3150THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER, 3151 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0, 3152 "Verify that concurrent breakpoints and signals are reported correctly " 3153 "and passed back to a handler function"); 3154 3155THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD, 3156 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 3157 "Verify that concurrent watchpoints and signals are reported correctly"); 3158THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN, 3159 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 3160 "Verify that concurrent watchpoints and signals are reported correctly " 3161 "and passed back to SIG_IGN handler"); 3162THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER, 3163 0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM, 3164 "Verify that concurrent watchpoints and signals are reported correctly " 3165 "and passed back to a handler function"); 3166 3167THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD, 3168 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 3169 THREAD_CONCURRENT_WATCHPOINT_NUM, 3170 "Verify that concurrent breakpoints, watchpoints and signals are reported " 3171 "correctly"); 3172THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN, 3173 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 3174 THREAD_CONCURRENT_WATCHPOINT_NUM, 3175 "Verify that concurrent breakpoints, watchpoints and signals are reported " 3176 "correctly and passed back to SIG_IGN handler"); 3177THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER, 3178 THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 3179 THREAD_CONCURRENT_WATCHPOINT_NUM, 3180 "Verify that concurrent breakpoints, watchpoints and signals are reported " 3181 "correctly and passed back to a handler function"); 3182#endif 3183 3184#endif /*defined(TWAIT_HAVE_STATUS)*/ 3185 3186/// ---------------------------------------------------------------------------- 3187 3188#include "t_ptrace_register_wait.h" 3189#include "t_ptrace_syscall_wait.h" 3190#include "t_ptrace_step_wait.h" 3191#include "t_ptrace_kill_wait.h" 3192#include "t_ptrace_bytetransfer_wait.h" 3193#include "t_ptrace_clone_wait.h" 3194#include "t_ptrace_fork_wait.h" 3195#include "t_ptrace_signal_wait.h" 3196 3197/// ---------------------------------------------------------------------------- 3198 3199#include "t_ptrace_amd64_wait.h" 3200#include "t_ptrace_i386_wait.h" 3201#include "t_ptrace_x86_wait.h" 3202 3203/// ---------------------------------------------------------------------------- 3204 3205#else 3206ATF_TC(dummy); 3207ATF_TC_HEAD(dummy, tc) 3208{ 3209 atf_tc_set_md_var(tc, "descr", "A dummy test"); 3210} 3211 3212ATF_TC_BODY(dummy, tc) 3213{ 3214 3215 // Dummy, skipped 3216 // The ATF framework requires at least a single defined test. 3217} 3218#endif 3219 3220ATF_TP_ADD_TCS(tp) 3221{ 3222 setvbuf(stdout, NULL, _IONBF, 0); 3223 setvbuf(stderr, NULL, _IONBF, 0); 3224 3225#ifdef ENABLE_TESTS 3226 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 3227 3228 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 3229 ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec); 3230 ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec); 3231 3232 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 3233 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 3234 ATF_TP_ADD_TC_HAVE_PID(tp, 3235 unrelated_tracer_sees_terminaton_before_the_parent); 3236 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 3237 3238 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 3239 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 3240 3241 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 3242 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 3243 3244 ATF_TP_ADD_TC_HAVE_PID(tp, 3245 tracee_sees_its_original_parent_getppid); 3246 ATF_TP_ADD_TC_HAVE_PID(tp, 3247 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 3248 ATF_TP_ADD_TC_HAVE_PID(tp, 3249 tracee_sees_its_original_parent_procfs_status); 3250 3251 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 3252 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 3253 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 3254 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 3255 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 3256 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 3257 ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn); 3258 3259 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 3260 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 3261 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 3262 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 3263 3264 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus); 3265 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus); 3266 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus); 3267 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus); 3268 3269 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask); 3270 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask); 3271 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask); 3272 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask); 3273 3274 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name); 3275 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name); 3276 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name); 3277 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name); 3278 3279 ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private); 3280 ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private); 3281 ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private); 3282 ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private); 3283 3284 ATF_TP_ADD_TC(tp, traceme_lwpnext0); 3285 ATF_TP_ADD_TC(tp, traceme_lwpnext1); 3286 ATF_TP_ADD_TC(tp, traceme_lwpnext2); 3287 ATF_TP_ADD_TC(tp, traceme_lwpnext3); 3288 3289 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask); 3290 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask); 3291 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask); 3292 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask); 3293 3294 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name); 3295 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name); 3296 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name); 3297 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name); 3298 3299 ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private); 3300 ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private); 3301 ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private); 3302 ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private); 3303 3304 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 3305 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 3306 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 3307 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 3308 3309 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 3310 ATF_TP_ADD_TC(tp, siginfo_set_faked); 3311 3312 ATF_TP_ADD_TC(tp, traceme_exec); 3313 ATF_TP_ADD_TC(tp, traceme_signalmasked_exec); 3314 ATF_TP_ADD_TC(tp, traceme_signalignored_exec); 3315 3316 ATF_TP_ADD_TC(tp, trace_thread_nolwpevents); 3317 ATF_TP_ADD_TC(tp, trace_thread_lwpexit); 3318 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate); 3319 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit); 3320 3321 ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap); 3322 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap); 3323 ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap); 3324 3325 ATF_TP_ADD_TC(tp, threads_and_exec); 3326 3327 ATF_TP_ADD_TC(tp, suspend_no_deadlock); 3328 3329 ATF_TP_ADD_TC(tp, resume); 3330 3331 ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 3332 ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 3333 ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 3334 3335 ATF_TP_ADD_TC(tp, core_dump_procinfo); 3336 3337#if defined(TWAIT_HAVE_STATUS) 3338 ATF_TP_ADD_TC(tp, thread_concurrent_signals); 3339 ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign); 3340 ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler); 3341#if defined(__i386__) || defined(__x86_64__) 3342 ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints); 3343 ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints); 3344 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp); 3345 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig); 3346 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign); 3347 ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler); 3348 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig); 3349 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign); 3350 ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler); 3351 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig); 3352 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign); 3353 ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler); 3354#endif 3355#endif 3356 3357 ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER(); 3358 ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL(); 3359 ATF_TP_ADD_TCS_PTRACE_WAIT_STEP(); 3360 ATF_TP_ADD_TCS_PTRACE_WAIT_KILL(); 3361 ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER(); 3362 ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE(); 3363 ATF_TP_ADD_TCS_PTRACE_WAIT_FORK(); 3364 ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL(); 3365 3366 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 3367 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 3368 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 3369 3370#else 3371 ATF_TP_ADD_TC(tp, dummy); 3372#endif 3373 3374 return atf_no_error(); 3375} 3376