1 /* $NetBSD: t_ptrace_wait.c,v 1.11 2017/01/18 05:14:34 kamil Exp $ */ 2 3 /*- 4 * Copyright (c) 2016 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.11 2017/01/18 05:14:34 kamil Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/types.h> 34 #include <sys/ptrace.h> 35 #include <sys/resource.h> 36 #include <sys/stat.h> 37 #include <sys/sysctl.h> 38 #include <sys/wait.h> 39 #include <machine/reg.h> 40 #include <x86/dbregs.h> 41 #include <err.h> 42 #include <errno.h> 43 #include <sched.h> 44 #include <signal.h> 45 #include <stdint.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <strings.h> 49 #include <unistd.h> 50 51 #include <atf-c.h> 52 53 #include "h_macros.h" 54 55 #include "../../t_ptrace_wait.h" 56 57 58 #if defined(HAVE_GPREGS) 59 ATF_TC(regs1); 60 ATF_TC_HEAD(regs1, tc) 61 { 62 atf_tc_set_md_var(tc, "descr", 63 "Call PT_GETREGS and iterate over General Purpose registers"); 64 } 65 66 ATF_TC_BODY(regs1, tc) 67 { 68 const int exitval = 5; 69 const int sigval = SIGSTOP; 70 pid_t child, wpid; 71 #if defined(TWAIT_HAVE_STATUS) 72 int status; 73 #endif 74 struct reg r; 75 76 printf("Before forking process PID=%d\n", getpid()); 77 ATF_REQUIRE((child = fork()) != -1); 78 if (child == 0) { 79 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 80 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 81 82 printf("Before raising %s from child\n", strsignal(sigval)); 83 FORKEE_ASSERT(raise(sigval) == 0); 84 85 printf("Before exiting of the child process\n"); 86 _exit(exitval); 87 } 88 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 89 90 printf("Before calling %s() for the child\n", TWAIT_FNAME); 91 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 92 93 validate_status_stopped(status, sigval); 94 95 printf("Call GETREGS for the child process\n"); 96 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 97 98 printf("RAX=%#" PRIxREGISTER "\n", r.regs[_REG_RAX]); 99 printf("RBX=%#" PRIxREGISTER "\n", r.regs[_REG_RBX]); 100 printf("RCX=%#" PRIxREGISTER "\n", r.regs[_REG_RCX]); 101 printf("RDX=%#" PRIxREGISTER "\n", r.regs[_REG_RDX]); 102 103 printf("RDI=%#" PRIxREGISTER "\n", r.regs[_REG_RDI]); 104 printf("RSI=%#" PRIxREGISTER "\n", r.regs[_REG_RSI]); 105 106 printf("GS=%#" PRIxREGISTER "\n", r.regs[_REG_GS]); 107 printf("FS=%#" PRIxREGISTER "\n", r.regs[_REG_FS]); 108 printf("ES=%#" PRIxREGISTER "\n", r.regs[_REG_ES]); 109 printf("DS=%#" PRIxREGISTER "\n", r.regs[_REG_DS]); 110 printf("CS=%#" PRIxREGISTER "\n", r.regs[_REG_CS]); 111 printf("SS=%#" PRIxREGISTER "\n", r.regs[_REG_SS]); 112 113 printf("RSP=%#" PRIxREGISTER "\n", r.regs[_REG_RSP]); 114 printf("RIP=%#" PRIxREGISTER "\n", r.regs[_REG_RIP]); 115 116 printf("RFLAGS=%#" PRIxREGISTER "\n", r.regs[_REG_RFLAGS]); 117 118 printf("R8=%#" PRIxREGISTER "\n", r.regs[_REG_R8]); 119 printf("R9=%#" PRIxREGISTER "\n", r.regs[_REG_R9]); 120 printf("R10=%#" PRIxREGISTER "\n", r.regs[_REG_R10]); 121 printf("R11=%#" PRIxREGISTER "\n", r.regs[_REG_R11]); 122 printf("R12=%#" PRIxREGISTER "\n", r.regs[_REG_R12]); 123 printf("R13=%#" PRIxREGISTER "\n", r.regs[_REG_R13]); 124 printf("R14=%#" PRIxREGISTER "\n", r.regs[_REG_R14]); 125 printf("R15=%#" PRIxREGISTER "\n", r.regs[_REG_R15]); 126 127 printf("Before resuming the child process where it left off and " 128 "without signal to be sent\n"); 129 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 130 131 printf("Before calling %s() for the child\n", TWAIT_FNAME); 132 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 133 134 validate_status_exited(status, exitval); 135 136 printf("Before calling %s() for the child\n", TWAIT_FNAME); 137 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 138 } 139 #endif 140 141 #if defined(__HAVE_PTRACE_WATCHPOINTS) 142 ATF_TC(watchpoint_count); 143 ATF_TC_HEAD(watchpoint_count, tc) 144 { 145 atf_tc_set_md_var(tc, "descr", 146 "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints"); 147 } 148 149 ATF_TC_BODY(watchpoint_count, tc) 150 { 151 const int exitval = 5; 152 const int sigval = SIGSTOP; 153 pid_t child, wpid; 154 #if defined(TWAIT_HAVE_STATUS) 155 int status; 156 #endif 157 int N; 158 159 printf("Before forking process PID=%d\n", getpid()); 160 ATF_REQUIRE((child = fork()) != -1); 161 if (child == 0) { 162 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 163 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 164 165 printf("Before raising %s from child\n", strsignal(sigval)); 166 FORKEE_ASSERT(raise(sigval) == 0); 167 168 printf("Before exiting of the child process\n"); 169 _exit(exitval); 170 } 171 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 172 173 printf("Before calling %s() for the child\n", TWAIT_FNAME); 174 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 175 176 validate_status_stopped(status, sigval); 177 178 printf("Call GETREGS for the child process\n"); 179 ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); 180 printf("Reported %d watchpoints\n", N); 181 182 ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); 183 184 printf("Before resuming the child process where it left off and " 185 "without signal to be sent\n"); 186 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 187 188 printf("Before calling %s() for the child\n", TWAIT_FNAME); 189 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 190 191 validate_status_exited(status, exitval); 192 193 printf("Before calling %s() for the child\n", TWAIT_FNAME); 194 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 195 } 196 #endif 197 198 #if defined(__HAVE_PTRACE_WATCHPOINTS) 199 ATF_TC(watchpoint_read); 200 ATF_TC_HEAD(watchpoint_read, tc) 201 { 202 atf_tc_set_md_var(tc, "descr", 203 "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints"); 204 } 205 206 ATF_TC_BODY(watchpoint_read, tc) 207 { 208 const int exitval = 5; 209 const int sigval = SIGSTOP; 210 pid_t child, wpid; 211 #if defined(TWAIT_HAVE_STATUS) 212 int status; 213 #endif 214 int i, N; 215 struct ptrace_watchpoint pw; 216 int len = sizeof(pw); 217 218 printf("Before forking process PID=%d\n", getpid()); 219 ATF_REQUIRE((child = fork()) != -1); 220 if (child == 0) { 221 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 222 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 223 224 printf("Before raising %s from child\n", strsignal(sigval)); 225 FORKEE_ASSERT(raise(sigval) == 0); 226 227 printf("Before exiting of the child process\n"); 228 _exit(exitval); 229 } 230 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 231 232 printf("Before calling %s() for the child\n", TWAIT_FNAME); 233 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 234 235 validate_status_stopped(status, sigval); 236 237 printf("Call GETREGS for the child process\n"); 238 ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); 239 240 ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); 241 242 for (i = 0; i < N; i++) { 243 printf("Before reading watchpoint %d\n", i); 244 pw.pw_index = i; 245 ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1); 246 247 printf("struct ptrace {\n"); 248 printf("\t.pw_index=%d\n", pw.pw_index); 249 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 250 printf("\t.pw_type=%#x\n", pw.pw_type); 251 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 252 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 253 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 254 printf("}\n"); 255 } 256 257 printf("Before resuming the child process where it left off and " 258 "without signal to be sent\n"); 259 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 260 261 printf("Before calling %s() for the child\n", TWAIT_FNAME); 262 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 263 264 validate_status_exited(status, exitval); 265 266 printf("Before calling %s() for the child\n", TWAIT_FNAME); 267 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 268 } 269 #endif 270 271 #if defined(__HAVE_PTRACE_WATCHPOINTS) 272 ATF_TC(watchpoint_write_unmodified); 273 ATF_TC_HEAD(watchpoint_write_unmodified, tc) 274 { 275 atf_tc_set_md_var(tc, "descr", 276 "Call PT_COUNT_WATCHPOINTS and assert functional write of " 277 "unmodified data"); 278 } 279 280 ATF_TC_BODY(watchpoint_write_unmodified, tc) 281 { 282 const int exitval = 5; 283 const int sigval = SIGSTOP; 284 pid_t child, wpid; 285 #if defined(TWAIT_HAVE_STATUS) 286 int status; 287 #endif 288 int i, N; 289 struct ptrace_watchpoint pw; 290 int len = sizeof(pw); 291 292 printf("Before forking process PID=%d\n", getpid()); 293 ATF_REQUIRE((child = fork()) != -1); 294 if (child == 0) { 295 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 296 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 297 298 printf("Before raising %s from child\n", strsignal(sigval)); 299 FORKEE_ASSERT(raise(sigval) == 0); 300 301 printf("Before exiting of the child process\n"); 302 _exit(exitval); 303 } 304 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 305 306 printf("Before calling %s() for the child\n", TWAIT_FNAME); 307 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 308 309 validate_status_stopped(status, sigval); 310 311 printf("Call GETREGS for the child process\n"); 312 ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); 313 314 ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); 315 316 for (i = 0; i < N; i++) { 317 printf("Before reading watchpoint %d\n", i); 318 pw.pw_index = i; 319 ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1); 320 321 printf("struct ptrace {\n"); 322 printf("\t.pw_index=%d\n", pw.pw_index); 323 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 324 printf("\t.pw_type=%#x\n", pw.pw_type); 325 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 326 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 327 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 328 printf("}\n"); 329 330 printf("Before writing watchpoint %d (unmodified)\n", i); 331 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) 332 != -1); 333 } 334 335 printf("Before resuming the child process where it left off and " 336 "without signal to be sent\n"); 337 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 338 339 printf("Before calling %s() for the child\n", TWAIT_FNAME); 340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 341 342 validate_status_exited(status, exitval); 343 344 printf("Before calling %s() for the child\n", TWAIT_FNAME); 345 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 346 } 347 #endif 348 349 #if defined(__HAVE_PTRACE_WATCHPOINTS) 350 ATF_TC(watchpoint_trap_code0); 351 ATF_TC_HEAD(watchpoint_trap_code0, tc) 352 { 353 atf_tc_set_md_var(tc, "descr", 354 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 0"); 355 } 356 357 ATF_TC_BODY(watchpoint_trap_code0, tc) 358 { 359 const int exitval = 5; 360 const int sigval = SIGSTOP; 361 pid_t child, wpid; 362 #if defined(TWAIT_HAVE_STATUS) 363 int status; 364 #endif 365 const int i = 0; 366 struct ptrace_watchpoint pw; 367 int len = sizeof(pw); 368 int watchme = 1234; 369 struct ptrace_siginfo info; 370 memset(&info, 0, sizeof(info)); 371 372 printf("Before forking process PID=%d\n", getpid()); 373 ATF_REQUIRE((child = fork()) != -1); 374 if (child == 0) { 375 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 376 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 377 378 printf("Before raising %s from child\n", strsignal(sigval)); 379 FORKEE_ASSERT(raise(sigval) == 0); 380 381 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 382 383 printf("Before exiting of the child process\n"); 384 _exit(exitval); 385 } 386 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 387 388 printf("Before calling %s() for the child\n", TWAIT_FNAME); 389 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 390 391 validate_status_stopped(status, sigval); 392 393 printf("Preparing code watchpoint trap %d\n", i); 394 395 pw.pw_index = i; 396 pw.pw_lwpid = 0; 397 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 398 pw.pw_md.md_address = (void *)check_happy; 399 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 400 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 401 402 printf("struct ptrace {\n"); 403 printf("\t.pw_index=%d\n", pw.pw_index); 404 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 405 printf("\t.pw_type=%#x\n", pw.pw_type); 406 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 407 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 408 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 409 printf("}\n"); 410 411 printf("Before writing watchpoint %d\n", i); 412 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 413 414 printf("Before resuming the child process where it left off " 415 "and without signal to be sent\n"); 416 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 417 418 printf("Before calling %s() for the child\n", TWAIT_FNAME); 419 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 420 421 validate_status_stopped(status, SIGTRAP); 422 423 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 424 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 425 426 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 427 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 428 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 429 info.psi_siginfo.si_errno); 430 431 printf("Before checking siginfo_t\n"); 432 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 433 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 434 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0); 435 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 436 437 pw.pw_md.md_address = NULL; 438 printf("Before writing watchpoint %d (disable it)\n", i); 439 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 440 441 printf("Before resuming the child process where it left off and " 442 "without signal to be sent\n"); 443 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 444 445 printf("Before calling %s() for the child\n", TWAIT_FNAME); 446 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 447 448 validate_status_exited(status, exitval); 449 450 printf("Before calling %s() for the child\n", TWAIT_FNAME); 451 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 452 } 453 #endif 454 455 #if defined(__HAVE_PTRACE_WATCHPOINTS) 456 ATF_TC(watchpoint_trap_code1); 457 ATF_TC_HEAD(watchpoint_trap_code1, tc) 458 { 459 atf_tc_set_md_var(tc, "descr", 460 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 1"); 461 } 462 463 ATF_TC_BODY(watchpoint_trap_code1, tc) 464 { 465 const int exitval = 5; 466 const int sigval = SIGSTOP; 467 pid_t child, wpid; 468 #if defined(TWAIT_HAVE_STATUS) 469 int status; 470 #endif 471 const int i = 1; 472 struct ptrace_watchpoint pw; 473 int len = sizeof(pw); 474 int watchme = 1234; 475 struct ptrace_siginfo info; 476 memset(&info, 0, sizeof(info)); 477 478 printf("Before forking process PID=%d\n", getpid()); 479 ATF_REQUIRE((child = fork()) != -1); 480 if (child == 0) { 481 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 482 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 483 484 printf("Before raising %s from child\n", strsignal(sigval)); 485 FORKEE_ASSERT(raise(sigval) == 0); 486 487 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 488 489 printf("Before exiting of the child process\n"); 490 _exit(exitval); 491 } 492 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 493 494 printf("Before calling %s() for the child\n", TWAIT_FNAME); 495 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 496 497 validate_status_stopped(status, sigval); 498 499 printf("Preparing code watchpoint trap %d\n", i); 500 501 pw.pw_index = i; 502 pw.pw_lwpid = 0; 503 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 504 pw.pw_md.md_address = (void *)check_happy; 505 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 506 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 507 508 printf("struct ptrace {\n"); 509 printf("\t.pw_index=%d\n", pw.pw_index); 510 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 511 printf("\t.pw_type=%d\n", pw.pw_type); 512 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 513 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 514 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 515 printf("}\n"); 516 517 printf("Before writing watchpoint %d\n", i); 518 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 519 520 printf("Before resuming the child process where it left off " 521 "and without signal to be sent\n"); 522 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 523 524 printf("Before calling %s() for the child\n", TWAIT_FNAME); 525 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 526 527 validate_status_stopped(status, SIGTRAP); 528 529 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 530 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 531 532 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 533 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 534 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 535 info.psi_siginfo.si_errno); 536 537 printf("Before checking siginfo_t\n"); 538 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 539 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 540 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1); 541 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 542 543 pw.pw_md.md_address = NULL; 544 printf("Before writing watchpoint %d (disable it)\n", i); 545 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 546 547 printf("Before resuming the child process where it left off and " 548 "without signal to be sent\n"); 549 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 550 551 printf("Before calling %s() for the child\n", TWAIT_FNAME); 552 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 553 554 validate_status_exited(status, exitval); 555 556 printf("Before calling %s() for the child\n", TWAIT_FNAME); 557 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 558 } 559 #endif 560 561 #if defined(__HAVE_PTRACE_WATCHPOINTS) 562 ATF_TC(watchpoint_trap_code2); 563 ATF_TC_HEAD(watchpoint_trap_code2, tc) 564 { 565 atf_tc_set_md_var(tc, "descr", 566 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 2"); 567 } 568 569 ATF_TC_BODY(watchpoint_trap_code2, tc) 570 { 571 const int exitval = 5; 572 const int sigval = SIGSTOP; 573 pid_t child, wpid; 574 #if defined(TWAIT_HAVE_STATUS) 575 int status; 576 #endif 577 const int i = 2; 578 struct ptrace_watchpoint pw; 579 int len = sizeof(pw); 580 int watchme = 1234; 581 struct ptrace_siginfo info; 582 memset(&info, 0, sizeof(info)); 583 584 printf("Before forking process PID=%d\n", getpid()); 585 ATF_REQUIRE((child = fork()) != -1); 586 if (child == 0) { 587 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 588 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 589 590 printf("Before raising %s from child\n", strsignal(sigval)); 591 FORKEE_ASSERT(raise(sigval) == 0); 592 593 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 594 595 printf("Before exiting of the child process\n"); 596 _exit(exitval); 597 } 598 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 599 600 printf("Before calling %s() for the child\n", TWAIT_FNAME); 601 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 602 603 validate_status_stopped(status, sigval); 604 605 printf("Preparing code watchpoint trap %d\n", i); 606 607 pw.pw_index = i; 608 pw.pw_lwpid = 0; 609 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 610 pw.pw_md.md_address = (void *)check_happy; 611 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 612 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 613 614 printf("struct ptrace {\n"); 615 printf("\t.pw_index=%d\n", pw.pw_index); 616 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 617 printf("\t.pw_type=%#x\n", pw.pw_type); 618 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 619 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 620 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 621 printf("}\n"); 622 623 printf("Before writing watchpoint %d\n", i); 624 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 625 626 printf("Before resuming the child process where it left off " 627 "and without signal to be sent\n"); 628 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 629 630 printf("Before calling %s() for the child\n", TWAIT_FNAME); 631 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 632 633 validate_status_stopped(status, SIGTRAP); 634 635 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 636 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 637 638 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 639 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 640 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 641 info.psi_siginfo.si_errno); 642 643 printf("Before checking siginfo_t\n"); 644 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 645 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 646 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2); 647 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 648 649 pw.pw_md.md_address = NULL; 650 printf("Before writing watchpoint %d (disable it)\n", i); 651 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 652 653 printf("Before resuming the child process where it left off and " 654 "without signal to be sent\n"); 655 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 656 657 printf("Before calling %s() for the child\n", TWAIT_FNAME); 658 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 659 660 validate_status_exited(status, exitval); 661 662 printf("Before calling %s() for the child\n", TWAIT_FNAME); 663 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 664 } 665 #endif 666 667 #if defined(__HAVE_PTRACE_WATCHPOINTS) 668 ATF_TC(watchpoint_trap_code3); 669 ATF_TC_HEAD(watchpoint_trap_code3, tc) 670 { 671 atf_tc_set_md_var(tc, "descr", 672 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 3"); 673 } 674 675 ATF_TC_BODY(watchpoint_trap_code3, tc) 676 { 677 const int exitval = 5; 678 const int sigval = SIGSTOP; 679 pid_t child, wpid; 680 #if defined(TWAIT_HAVE_STATUS) 681 int status; 682 #endif 683 const int i = 3; 684 struct ptrace_watchpoint pw; 685 int len = sizeof(pw); 686 int watchme = 1234; 687 struct ptrace_siginfo info; 688 memset(&info, 0, sizeof(info)); 689 690 printf("Before forking process PID=%d\n", getpid()); 691 ATF_REQUIRE((child = fork()) != -1); 692 if (child == 0) { 693 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 694 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 695 696 printf("Before raising %s from child\n", strsignal(sigval)); 697 FORKEE_ASSERT(raise(sigval) == 0); 698 699 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 700 701 printf("Before exiting of the child process\n"); 702 _exit(exitval); 703 } 704 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 705 706 printf("Before calling %s() for the child\n", TWAIT_FNAME); 707 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 708 709 validate_status_stopped(status, sigval); 710 711 printf("Preparing code watchpoint trap %d\n", i); 712 713 pw.pw_index = i; 714 pw.pw_lwpid = 0; 715 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 716 pw.pw_md.md_address = (void *)check_happy; 717 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 718 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 719 720 printf("struct ptrace {\n"); 721 printf("\t.pw_index=%d\n", pw.pw_index); 722 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 723 printf("\t.pw_type=%#x\n", pw.pw_type); 724 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 725 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 726 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 727 printf("}\n"); 728 729 printf("Before writing watchpoint %d\n", i); 730 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 731 732 printf("Before resuming the child process where it left off " 733 "and without signal to be sent\n"); 734 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 735 736 printf("Before calling %s() for the child\n", TWAIT_FNAME); 737 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 738 739 validate_status_stopped(status, SIGTRAP); 740 741 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 742 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 743 744 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 745 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 746 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 747 info.psi_siginfo.si_errno); 748 749 printf("Before checking siginfo_t\n"); 750 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 751 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 752 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3); 753 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 754 755 pw.pw_md.md_address = NULL; 756 printf("Before writing watchpoint %d (disable it)\n", i); 757 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 758 759 printf("Before resuming the child process where it left off and " 760 "without signal to be sent\n"); 761 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 762 763 printf("Before calling %s() for the child\n", TWAIT_FNAME); 764 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 765 766 validate_status_exited(status, exitval); 767 768 printf("Before calling %s() for the child\n", TWAIT_FNAME); 769 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 770 } 771 #endif 772 773 #if defined(__HAVE_PTRACE_WATCHPOINTS) 774 ATF_TC(watchpoint_trap_data_write0); 775 ATF_TC_HEAD(watchpoint_trap_data_write0, tc) 776 { 777 atf_tc_set_md_var(tc, "descr", 778 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0"); 779 } 780 781 ATF_TC_BODY(watchpoint_trap_data_write0, tc) 782 { 783 const int exitval = 5; 784 const int sigval = SIGSTOP; 785 pid_t child, wpid; 786 #if defined(TWAIT_HAVE_STATUS) 787 int status; 788 #endif 789 const int i = 0; 790 struct ptrace_watchpoint pw; 791 int len = sizeof(pw); 792 int watchme = 1234; 793 struct ptrace_siginfo info; 794 memset(&info, 0, sizeof(info)); 795 796 printf("Before forking process PID=%d\n", getpid()); 797 ATF_REQUIRE((child = fork()) != -1); 798 if (child == 0) { 799 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 800 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 801 802 printf("Before raising %s from child\n", strsignal(sigval)); 803 FORKEE_ASSERT(raise(sigval) == 0); 804 805 ++watchme; 806 807 printf("Before exiting of the child process\n"); 808 _exit(exitval); 809 } 810 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 811 812 printf("Before calling %s() for the child\n", TWAIT_FNAME); 813 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 814 815 validate_status_stopped(status, sigval); 816 817 printf("Preparing code watchpoint trap %d\n", i); 818 819 pw.pw_index = 0; 820 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 821 pw.pw_md.md_address = &watchme; 822 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 823 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 824 825 printf("struct ptrace {\n"); 826 printf("\t.pw_index=%d\n", pw.pw_index); 827 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 828 printf("\t.pw_type=%#x\n", pw.pw_type); 829 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 830 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 831 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 832 printf("}\n"); 833 834 printf("Before writing watchpoint %d\n", i); 835 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 836 837 printf("Before resuming the child process where it left off " 838 "and without signal to be sent\n"); 839 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 840 841 printf("Before calling %s() for the child\n", TWAIT_FNAME); 842 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 843 844 validate_status_stopped(status, SIGTRAP); 845 846 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 847 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 848 849 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 850 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 851 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 852 info.psi_siginfo.si_errno); 853 854 printf("Before checking siginfo_t\n"); 855 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 856 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 857 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0); 858 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 859 860 printf("Before resuming the child process where it left off and " 861 "without signal to be sent\n"); 862 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 863 864 printf("Before calling %s() for the child\n", TWAIT_FNAME); 865 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 866 867 validate_status_exited(status, exitval); 868 869 printf("Before calling %s() for the child\n", TWAIT_FNAME); 870 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 871 } 872 #endif 873 874 #if defined(__HAVE_PTRACE_WATCHPOINTS) 875 ATF_TC(watchpoint_trap_data_write1); 876 ATF_TC_HEAD(watchpoint_trap_data_write1, tc) 877 { 878 atf_tc_set_md_var(tc, "descr", 879 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1"); 880 } 881 882 ATF_TC_BODY(watchpoint_trap_data_write1, tc) 883 { 884 const int exitval = 5; 885 const int sigval = SIGSTOP; 886 pid_t child, wpid; 887 #if defined(TWAIT_HAVE_STATUS) 888 int status; 889 #endif 890 const int i = 1; 891 struct ptrace_watchpoint pw; 892 int len = sizeof(pw); 893 int watchme = 1234; 894 struct ptrace_siginfo info; 895 memset(&info, 0, sizeof(info)); 896 897 printf("Before forking process PID=%d\n", getpid()); 898 ATF_REQUIRE((child = fork()) != -1); 899 if (child == 0) { 900 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 901 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 902 903 printf("Before raising %s from child\n", strsignal(sigval)); 904 FORKEE_ASSERT(raise(sigval) == 0); 905 906 ++watchme; 907 908 printf("Before exiting of the child process\n"); 909 _exit(exitval); 910 } 911 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 912 913 printf("Before calling %s() for the child\n", TWAIT_FNAME); 914 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 915 916 validate_status_stopped(status, sigval); 917 918 printf("Preparing code watchpoint trap %d\n", i); 919 920 pw.pw_index = i; 921 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 922 pw.pw_md.md_address = &watchme; 923 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 924 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 925 926 printf("struct ptrace {\n"); 927 printf("\t.pw_index=%d\n", pw.pw_index); 928 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 929 printf("\t.pw_type=%#x\n", pw.pw_type); 930 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 931 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 932 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 933 printf("}\n"); 934 935 printf("Before writing watchpoint %d\n", i); 936 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 937 938 printf("Before resuming the child process where it left off " 939 "and without signal to be sent\n"); 940 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 941 942 printf("Before calling %s() for the child\n", TWAIT_FNAME); 943 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 944 945 validate_status_stopped(status, SIGTRAP); 946 947 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 948 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 949 950 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 951 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 952 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 953 info.psi_siginfo.si_errno); 954 955 printf("Before checking siginfo_t\n"); 956 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 957 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 958 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1); 959 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 960 961 printf("Before resuming the child process where it left off and " 962 "without signal to be sent\n"); 963 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 964 965 printf("Before calling %s() for the child\n", TWAIT_FNAME); 966 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 967 968 validate_status_exited(status, exitval); 969 970 printf("Before calling %s() for the child\n", TWAIT_FNAME); 971 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 972 } 973 #endif 974 975 #if defined(__HAVE_PTRACE_WATCHPOINTS) 976 ATF_TC(watchpoint_trap_data_write2); 977 ATF_TC_HEAD(watchpoint_trap_data_write2, tc) 978 { 979 atf_tc_set_md_var(tc, "descr", 980 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2"); 981 } 982 983 ATF_TC_BODY(watchpoint_trap_data_write2, tc) 984 { 985 const int exitval = 5; 986 const int sigval = SIGSTOP; 987 pid_t child, wpid; 988 #if defined(TWAIT_HAVE_STATUS) 989 int status; 990 #endif 991 const int i = 2; 992 struct ptrace_watchpoint pw; 993 int len = sizeof(pw); 994 int watchme = 1234; 995 struct ptrace_siginfo info; 996 memset(&info, 0, sizeof(info)); 997 998 printf("Before forking process PID=%d\n", getpid()); 999 ATF_REQUIRE((child = fork()) != -1); 1000 if (child == 0) { 1001 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1002 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1003 1004 printf("Before raising %s from child\n", strsignal(sigval)); 1005 FORKEE_ASSERT(raise(sigval) == 0); 1006 1007 ++watchme; 1008 1009 printf("Before exiting of the child process\n"); 1010 _exit(exitval); 1011 } 1012 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1013 1014 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1015 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1016 1017 validate_status_stopped(status, sigval); 1018 1019 printf("Preparing code watchpoint trap %d\n", i); 1020 1021 pw.pw_index = i; 1022 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 1023 pw.pw_md.md_address = &watchme; 1024 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 1025 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1026 1027 printf("struct ptrace {\n"); 1028 printf("\t.pw_index=%d\n", pw.pw_index); 1029 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1030 printf("\t.pw_type=%#x\n", pw.pw_type); 1031 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1032 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1033 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1034 printf("}\n"); 1035 1036 printf("Before writing watchpoint %d\n", i); 1037 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1038 1039 printf("Before resuming the child process where it left off " 1040 "and without signal to be sent\n"); 1041 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1042 1043 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1044 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1045 1046 validate_status_stopped(status, SIGTRAP); 1047 1048 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1049 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1050 1051 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 1052 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1053 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1054 info.psi_siginfo.si_errno); 1055 1056 printf("Before checking siginfo_t\n"); 1057 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1058 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 1059 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2); 1060 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 1061 1062 printf("Before resuming the child process where it left off and " 1063 "without signal to be sent\n"); 1064 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1065 1066 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1067 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1068 1069 validate_status_exited(status, exitval); 1070 1071 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1072 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1073 } 1074 #endif 1075 1076 1077 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1078 ATF_TC(watchpoint_trap_data_write3); 1079 ATF_TC_HEAD(watchpoint_trap_data_write3, tc) 1080 { 1081 atf_tc_set_md_var(tc, "descr", 1082 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3"); 1083 } 1084 1085 ATF_TC_BODY(watchpoint_trap_data_write3, tc) 1086 { 1087 const int exitval = 5; 1088 const int sigval = SIGSTOP; 1089 pid_t child, wpid; 1090 #if defined(TWAIT_HAVE_STATUS) 1091 int status; 1092 #endif 1093 const int i = 3; 1094 struct ptrace_watchpoint pw; 1095 int len = sizeof(pw); 1096 int watchme = 1234; 1097 struct ptrace_siginfo info; 1098 memset(&info, 0, sizeof(info)); 1099 1100 printf("Before forking process PID=%d\n", getpid()); 1101 ATF_REQUIRE((child = fork()) != -1); 1102 if (child == 0) { 1103 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1104 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1105 1106 printf("Before raising %s from child\n", strsignal(sigval)); 1107 FORKEE_ASSERT(raise(sigval) == 0); 1108 1109 ++watchme; 1110 1111 printf("Before exiting of the child process\n"); 1112 _exit(exitval); 1113 } 1114 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1115 1116 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1117 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1118 1119 validate_status_stopped(status, sigval); 1120 1121 printf("Preparing code watchpoint trap %d\n", i); 1122 1123 pw.pw_index = i; 1124 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 1125 pw.pw_md.md_address = &watchme; 1126 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 1127 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1128 1129 printf("struct ptrace {\n"); 1130 printf("\t.pw_index=%d\n", pw.pw_index); 1131 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1132 printf("\t.pw_type=%#x\n", pw.pw_type); 1133 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1134 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1135 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1136 printf("}\n"); 1137 1138 printf("Before writing watchpoint %d\n", i); 1139 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1140 1141 printf("Before resuming the child process where it left off " 1142 "and without signal to be sent\n"); 1143 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1144 1145 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1146 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1147 1148 validate_status_stopped(status, SIGTRAP); 1149 1150 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1151 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1152 1153 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 1154 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1155 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1156 info.psi_siginfo.si_errno); 1157 1158 printf("Before checking siginfo_t\n"); 1159 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1160 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 1161 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3); 1162 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 1163 1164 printf("Before resuming the child process where it left off and " 1165 "without signal to be sent\n"); 1166 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1167 1168 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1169 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1170 1171 validate_status_exited(status, exitval); 1172 1173 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1174 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1175 } 1176 #endif 1177 1178 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1179 ATF_TC(watchpoint_trap_data_rw0); 1180 ATF_TC_HEAD(watchpoint_trap_data_rw0, tc) 1181 { 1182 atf_tc_set_md_var(tc, "descr", 1183 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0"); 1184 } 1185 1186 ATF_TC_BODY(watchpoint_trap_data_rw0, tc) 1187 { 1188 const int exitval = 5; 1189 const int sigval = SIGSTOP; 1190 pid_t child, wpid; 1191 #if defined(TWAIT_HAVE_STATUS) 1192 int status; 1193 #endif 1194 const int i = 0; 1195 struct ptrace_watchpoint pw; 1196 int len = sizeof(pw); 1197 int watchme = 1234; 1198 struct ptrace_siginfo info; 1199 memset(&info, 0, sizeof(info)); 1200 1201 printf("Before forking process PID=%d\n", getpid()); 1202 ATF_REQUIRE((child = fork()) != -1); 1203 if (child == 0) { 1204 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1205 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1206 1207 printf("Before raising %s from child\n", strsignal(sigval)); 1208 FORKEE_ASSERT(raise(sigval) == 0); 1209 1210 printf("watchme=%d\n", watchme); 1211 1212 printf("Before exiting of the child process\n"); 1213 _exit(exitval); 1214 } 1215 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1216 1217 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1218 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1219 1220 validate_status_stopped(status, sigval); 1221 1222 printf("Preparing code watchpoint trap %d\n", i); 1223 1224 pw.pw_index = i; 1225 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 1226 pw.pw_md.md_address = &watchme; 1227 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1228 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1229 1230 printf("struct ptrace {\n"); 1231 printf("\t.pw_index=%d\n", pw.pw_index); 1232 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1233 printf("\t.pw_type=%#x\n", pw.pw_type); 1234 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1235 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1236 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1237 printf("}\n"); 1238 1239 printf("Before writing watchpoint %d\n", i); 1240 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1241 1242 printf("Before resuming the child process where it left off " 1243 "and without signal to be sent\n"); 1244 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1245 1246 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1247 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1248 1249 validate_status_stopped(status, SIGTRAP); 1250 1251 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1252 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1253 1254 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 1255 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1256 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1257 info.psi_siginfo.si_errno); 1258 1259 printf("Before checking siginfo_t\n"); 1260 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1261 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 1262 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0); 1263 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 1264 1265 printf("Before resuming the child process where it left off and " 1266 "without signal to be sent\n"); 1267 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1268 1269 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1270 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1271 1272 validate_status_exited(status, exitval); 1273 1274 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1275 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1276 } 1277 #endif 1278 1279 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1280 ATF_TC(watchpoint_trap_data_rw1); 1281 ATF_TC_HEAD(watchpoint_trap_data_rw1, tc) 1282 { 1283 atf_tc_set_md_var(tc, "descr", 1284 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1"); 1285 } 1286 1287 ATF_TC_BODY(watchpoint_trap_data_rw1, tc) 1288 { 1289 const int exitval = 5; 1290 const int sigval = SIGSTOP; 1291 pid_t child, wpid; 1292 #if defined(TWAIT_HAVE_STATUS) 1293 int status; 1294 #endif 1295 const int i = 1; 1296 struct ptrace_watchpoint pw; 1297 int len = sizeof(pw); 1298 int watchme = 1234; 1299 struct ptrace_siginfo info; 1300 memset(&info, 0, sizeof(info)); 1301 1302 printf("Before forking process PID=%d\n", getpid()); 1303 ATF_REQUIRE((child = fork()) != -1); 1304 if (child == 0) { 1305 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1306 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1307 1308 printf("Before raising %s from child\n", strsignal(sigval)); 1309 FORKEE_ASSERT(raise(sigval) == 0); 1310 1311 printf("watchme=%d\n", watchme); 1312 1313 printf("Before exiting of the child process\n"); 1314 _exit(exitval); 1315 } 1316 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1317 1318 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1319 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1320 1321 validate_status_stopped(status, sigval); 1322 1323 printf("Preparing code watchpoint trap %d\n", i); 1324 1325 pw.pw_index = i; 1326 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 1327 pw.pw_md.md_address = &watchme; 1328 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1329 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1330 1331 printf("struct ptrace {\n"); 1332 printf("\t.pw_index=%d\n", pw.pw_index); 1333 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1334 printf("\t.pw_type=%#x\n", pw.pw_type); 1335 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1336 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1337 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1338 printf("}\n"); 1339 1340 printf("Before writing watchpoint %d\n", i); 1341 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1342 1343 printf("Before resuming the child process where it left off " 1344 "and without signal to be sent\n"); 1345 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1346 1347 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1348 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1349 1350 validate_status_stopped(status, SIGTRAP); 1351 1352 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1353 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1354 1355 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 1356 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1357 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1358 info.psi_siginfo.si_errno); 1359 1360 printf("Before checking siginfo_t\n"); 1361 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1362 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 1363 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1); 1364 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 1365 1366 printf("Before resuming the child process where it left off and " 1367 "without signal to be sent\n"); 1368 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1369 1370 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1371 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1372 1373 validate_status_exited(status, exitval); 1374 1375 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1376 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1377 } 1378 #endif 1379 1380 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1381 ATF_TC(watchpoint_trap_data_rw2); 1382 ATF_TC_HEAD(watchpoint_trap_data_rw2, tc) 1383 { 1384 atf_tc_set_md_var(tc, "descr", 1385 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2"); 1386 } 1387 1388 ATF_TC_BODY(watchpoint_trap_data_rw2, tc) 1389 { 1390 const int exitval = 5; 1391 const int sigval = SIGSTOP; 1392 pid_t child, wpid; 1393 #if defined(TWAIT_HAVE_STATUS) 1394 int status; 1395 #endif 1396 const int i = 2; 1397 struct ptrace_watchpoint pw; 1398 int len = sizeof(pw); 1399 int watchme = 1234; 1400 struct ptrace_siginfo info; 1401 memset(&info, 0, sizeof(info)); 1402 1403 printf("Before forking process PID=%d\n", getpid()); 1404 ATF_REQUIRE((child = fork()) != -1); 1405 if (child == 0) { 1406 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1407 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1408 1409 printf("Before raising %s from child\n", strsignal(sigval)); 1410 FORKEE_ASSERT(raise(sigval) == 0); 1411 1412 printf("watchme=%d\n", watchme); 1413 1414 printf("Before exiting of the child process\n"); 1415 _exit(exitval); 1416 } 1417 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1418 1419 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1420 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1421 1422 validate_status_stopped(status, sigval); 1423 1424 printf("Preparing code watchpoint trap %d\n", i); 1425 1426 pw.pw_index = i; 1427 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 1428 pw.pw_md.md_address = &watchme; 1429 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1430 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1431 1432 printf("struct ptrace {\n"); 1433 printf("\t.pw_index=%d\n", pw.pw_index); 1434 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1435 printf("\t.pw_type=%#x\n", pw.pw_type); 1436 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1437 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1438 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1439 printf("}\n"); 1440 1441 printf("Before writing watchpoint %d\n", i); 1442 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1443 1444 printf("Before resuming the child process where it left off " 1445 "and without signal to be sent\n"); 1446 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1447 1448 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1449 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1450 1451 validate_status_stopped(status, SIGTRAP); 1452 1453 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1454 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1455 1456 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 1457 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1458 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1459 info.psi_siginfo.si_errno); 1460 1461 printf("Before checking siginfo_t\n"); 1462 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1463 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 1464 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2); 1465 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 1466 1467 printf("Before resuming the child process where it left off and " 1468 "without signal to be sent\n"); 1469 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1470 1471 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1472 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1473 1474 validate_status_exited(status, exitval); 1475 1476 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1477 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1478 } 1479 #endif 1480 1481 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1482 ATF_TC(watchpoint_trap_data_rw3); 1483 ATF_TC_HEAD(watchpoint_trap_data_rw3, tc) 1484 { 1485 atf_tc_set_md_var(tc, "descr", 1486 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3"); 1487 } 1488 1489 ATF_TC_BODY(watchpoint_trap_data_rw3, tc) 1490 { 1491 const int exitval = 5; 1492 const int sigval = SIGSTOP; 1493 pid_t child, wpid; 1494 #if defined(TWAIT_HAVE_STATUS) 1495 int status; 1496 #endif 1497 const int i = 3; 1498 struct ptrace_watchpoint pw; 1499 int len = sizeof(pw); 1500 int watchme = 1234; 1501 struct ptrace_siginfo info; 1502 memset(&info, 0, sizeof(info)); 1503 1504 printf("Before forking process PID=%d\n", getpid()); 1505 ATF_REQUIRE((child = fork()) != -1); 1506 if (child == 0) { 1507 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1508 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1509 1510 printf("Before raising %s from child\n", strsignal(sigval)); 1511 FORKEE_ASSERT(raise(sigval) == 0); 1512 1513 printf("watchme=%d\n", watchme); 1514 1515 printf("Before exiting of the child process\n"); 1516 _exit(exitval); 1517 } 1518 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1519 1520 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1521 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1522 1523 validate_status_stopped(status, sigval); 1524 1525 printf("Preparing code watchpoint trap %d\n", i); 1526 1527 pw.pw_index = i; 1528 pw.pw_type = PTRACE_PW_TYPE_DBREGS; 1529 pw.pw_md.md_address = &watchme; 1530 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1531 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1532 1533 printf("struct ptrace {\n"); 1534 printf("\t.pw_index=%d\n", pw.pw_index); 1535 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1536 printf("\t.pw_type=%#x\n", pw.pw_type); 1537 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1538 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1539 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1540 printf("}\n"); 1541 1542 printf("Before writing watchpoint %d\n", i); 1543 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1544 1545 printf("Before resuming the child process where it left off " 1546 "and without signal to be sent\n"); 1547 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1548 1549 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1550 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1551 1552 validate_status_stopped(status, SIGTRAP); 1553 1554 printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1555 ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1556 1557 printf("Signal traced to lwpid=%d\n", info.psi_lwpid); 1558 printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1559 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1560 info.psi_siginfo.si_errno); 1561 1562 printf("Before checking siginfo_t\n"); 1563 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1564 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); 1565 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3); 1566 ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); 1567 1568 printf("Before resuming the child process where it left off and " 1569 "without signal to be sent\n"); 1570 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1571 1572 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1573 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1574 1575 validate_status_exited(status, exitval); 1576 1577 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1578 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1579 } 1580 #endif 1581 1582 ATF_TP_ADD_TCS(tp) 1583 { 1584 setvbuf(stdout, NULL, _IONBF, 0); 1585 setvbuf(stderr, NULL, _IONBF, 0); 1586 1587 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); 1588 1589 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_count); 1590 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_read); 1591 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_write_unmodified); 1592 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code0); 1593 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code1); 1594 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code2); 1595 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code3); 1596 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write0); 1597 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write1); 1598 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write2); 1599 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write3); 1600 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw0); 1601 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw1); 1602 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw2); 1603 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw3); 1604 1605 return atf_no_error(); 1606 } 1607