1c209e3e2SJohn Baldwin /*- 2c209e3e2SJohn Baldwin * Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org> 3c209e3e2SJohn Baldwin * 4c209e3e2SJohn Baldwin * Redistribution and use in source and binary forms, with or without 5c209e3e2SJohn Baldwin * modification, are permitted provided that the following conditions 6c209e3e2SJohn Baldwin * are met: 7c209e3e2SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 8c209e3e2SJohn Baldwin * notice, this list of conditions and the following disclaimer. 9c209e3e2SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 10c209e3e2SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 11c209e3e2SJohn Baldwin * documentation and/or other materials provided with the distribution. 12c209e3e2SJohn Baldwin * 13c209e3e2SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14c209e3e2SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15c209e3e2SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16c209e3e2SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17c209e3e2SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18c209e3e2SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19c209e3e2SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20c209e3e2SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21c209e3e2SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22c209e3e2SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23c209e3e2SJohn Baldwin * SUCH DAMAGE. 24c209e3e2SJohn Baldwin */ 25c209e3e2SJohn Baldwin 26c209e3e2SJohn Baldwin #include <sys/cdefs.h> 27c209e3e2SJohn Baldwin __FBSDID("$FreeBSD$"); 28c209e3e2SJohn Baldwin 29c209e3e2SJohn Baldwin #include <sys/types.h> 3082a4538fSEric Badger #include <sys/cpuset.h> 3182a4538fSEric Badger #include <sys/event.h> 32d74da94cSMark Johnston #include <sys/file.h> 3382a4538fSEric Badger #include <sys/time.h> 34b38bd91fSEric Badger #include <sys/procctl.h> 35fd631bcdSMariusz Zaborski #include <sys/procdesc.h> 36e21f96a8SKyle Evans #define _WANT_MIPS_REGNUM 37c209e3e2SJohn Baldwin #include <sys/ptrace.h> 38bc2be1d3SEric Badger #include <sys/queue.h> 39bc2be1d3SEric Badger #include <sys/runq.h> 40189ac973SJohn Baldwin #include <sys/syscall.h> 4157c74f5bSJohn Baldwin #include <sys/sysctl.h> 4257c74f5bSJohn Baldwin #include <sys/user.h> 43c209e3e2SJohn Baldwin #include <sys/wait.h> 44c209e3e2SJohn Baldwin #include <errno.h> 459e0d1159SEric Badger #include <machine/cpufunc.h> 46189ac973SJohn Baldwin #include <pthread.h> 47bc2be1d3SEric Badger #include <sched.h> 4882a4538fSEric Badger #include <semaphore.h> 49c209e3e2SJohn Baldwin #include <signal.h> 5096a9e50eSAlex Richardson #include <stdarg.h> 51dfa8ba12SJohn Baldwin #include <stdio.h> 52c209e3e2SJohn Baldwin #include <stdlib.h> 53c209e3e2SJohn Baldwin #include <unistd.h> 54c209e3e2SJohn Baldwin #include <atf-c.h> 55c209e3e2SJohn Baldwin 56c209e3e2SJohn Baldwin /* 57403e331dSJohn Baldwin * Architectures with a user-visible breakpoint(). 58403e331dSJohn Baldwin */ 59a9c91abdSJohn Baldwin #if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \ 60a9c91abdSJohn Baldwin defined(__i386__) || defined(__mips__) || defined(__riscv) || \ 61a9c91abdSJohn Baldwin defined(__sparc64__) 62403e331dSJohn Baldwin #define HAVE_BREAKPOINT 63403e331dSJohn Baldwin #endif 64403e331dSJohn Baldwin 65403e331dSJohn Baldwin /* 66403e331dSJohn Baldwin * Adjust PC to skip over a breakpoint when stopped for a breakpoint trap. 67403e331dSJohn Baldwin */ 68403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 69a9c91abdSJohn Baldwin #if defined(__aarch64__) 70a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->elr += 4) 71a9c91abdSJohn Baldwin #elif defined(__amd64__) || defined(__i386__) 72403e331dSJohn Baldwin #define SKIP_BREAK(reg) 73a9c91abdSJohn Baldwin #elif defined(__arm__) 74a9c91abdSJohn Baldwin #define SKIP_BREAK(reg) ((reg)->r_pc += 4) 75bd061c39SJohn Baldwin #elif defined(__mips__) 76bd061c39SJohn Baldwin #define SKIP_BREAK(reg) ((reg)->r_regs[PC] += 4) 77ca75fa17SJohn Baldwin #elif defined(__riscv) 78ca75fa17SJohn Baldwin #define SKIP_BREAK(reg) ((reg)->sepc += 4) 79403e331dSJohn Baldwin #elif defined(__sparc64__) 80403e331dSJohn Baldwin #define SKIP_BREAK(reg) do { \ 81403e331dSJohn Baldwin (reg)->r_tpc = (reg)->r_tnpc + 4; \ 82403e331dSJohn Baldwin (reg)->r_tnpc += 8; \ 83403e331dSJohn Baldwin } while (0) 84403e331dSJohn Baldwin #endif 85403e331dSJohn Baldwin #endif 86403e331dSJohn Baldwin 87403e331dSJohn Baldwin /* 88dfa8ba12SJohn Baldwin * A variant of ATF_REQUIRE that is suitable for use in child 89dfa8ba12SJohn Baldwin * processes. This only works if the parent process is tripped up by 90dfa8ba12SJohn Baldwin * the early exit and fails some requirement itself. 91dfa8ba12SJohn Baldwin */ 92dfa8ba12SJohn Baldwin #define CHILD_REQUIRE(exp) do { \ 93dfa8ba12SJohn Baldwin if (!(exp)) \ 94dfa8ba12SJohn Baldwin child_fail_require(__FILE__, __LINE__, \ 9596a9e50eSAlex Richardson #exp " not met\n"); \ 9696a9e50eSAlex Richardson } while (0) 9796a9e50eSAlex Richardson 9896a9e50eSAlex Richardson #define CHILD_REQUIRE_EQ(actual, expected) do { \ 9996a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 10096a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 10196a9e50eSAlex Richardson if (_e != _a) \ 10296a9e50eSAlex Richardson child_fail_require(__FILE__, __LINE__, #actual \ 10396a9e50eSAlex Richardson " (%jd) == " #expected " (%jd) not met\n", \ 10496a9e50eSAlex Richardson (intmax_t)_a, (intmax_t)_e); \ 105dfa8ba12SJohn Baldwin } while (0) 106dfa8ba12SJohn Baldwin 10798685dc8SJohn Baldwin static __dead2 void 10896a9e50eSAlex Richardson child_fail_require(const char *file, int line, const char *fmt, ...) 109dfa8ba12SJohn Baldwin { 11096a9e50eSAlex Richardson va_list ap; 11196a9e50eSAlex Richardson char buf[1024]; 112dfa8ba12SJohn Baldwin 11396a9e50eSAlex Richardson /* Use write() not fprintf() to avoid possible duplicate output. */ 11496a9e50eSAlex Richardson snprintf(buf, sizeof(buf), "%s:%d: ", file, line); 11596a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 11696a9e50eSAlex Richardson va_start(ap, fmt); 11796a9e50eSAlex Richardson vsnprintf(buf, sizeof(buf), fmt, ap); 11896a9e50eSAlex Richardson write(STDERR_FILENO, buf, strlen(buf)); 11996a9e50eSAlex Richardson va_end(ap); 12096a9e50eSAlex Richardson 121dfa8ba12SJohn Baldwin _exit(32); 122dfa8ba12SJohn Baldwin } 123dfa8ba12SJohn Baldwin 12496a9e50eSAlex Richardson #define REQUIRE_EQ(actual, expected) do { \ 12596a9e50eSAlex Richardson __typeof__(expected) _e = expected; \ 12696a9e50eSAlex Richardson __typeof__(actual) _a = actual; \ 12796a9e50eSAlex Richardson ATF_REQUIRE_MSG(_e == _a, #actual " (%jd) == " \ 12896a9e50eSAlex Richardson #expected " (%jd) not met", (intmax_t)_a, (intmax_t)_e); \ 12996a9e50eSAlex Richardson } while (0) 13096a9e50eSAlex Richardson 13198685dc8SJohn Baldwin static void 13298685dc8SJohn Baldwin trace_me(void) 13398685dc8SJohn Baldwin { 13498685dc8SJohn Baldwin 13598685dc8SJohn Baldwin /* Attach the parent process as a tracer of this process. */ 13698685dc8SJohn Baldwin CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 13798685dc8SJohn Baldwin 13898685dc8SJohn Baldwin /* Trigger a stop. */ 13998685dc8SJohn Baldwin raise(SIGSTOP); 14098685dc8SJohn Baldwin } 14198685dc8SJohn Baldwin 14298685dc8SJohn Baldwin static void 14398685dc8SJohn Baldwin attach_child(pid_t pid) 14498685dc8SJohn Baldwin { 14598685dc8SJohn Baldwin pid_t wpid; 14698685dc8SJohn Baldwin int status; 14798685dc8SJohn Baldwin 14896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, pid, NULL, 0), 0); 14998685dc8SJohn Baldwin 15098685dc8SJohn Baldwin wpid = waitpid(pid, &status, 0); 15196a9e50eSAlex Richardson REQUIRE_EQ(wpid, pid); 15298685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 15396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15498685dc8SJohn Baldwin } 15598685dc8SJohn Baldwin 15698685dc8SJohn Baldwin static void 15798685dc8SJohn Baldwin wait_for_zombie(pid_t pid) 15898685dc8SJohn Baldwin { 15998685dc8SJohn Baldwin 16098685dc8SJohn Baldwin /* 16198685dc8SJohn Baldwin * Wait for a process to exit. This is kind of gross, but 16298685dc8SJohn Baldwin * there is not a better way. 1633a014c56SJohn Baldwin * 1643a014c56SJohn Baldwin * Prior to r325719, the kern.proc.pid.<pid> sysctl failed 1653a014c56SJohn Baldwin * with ESRCH. After that change, a valid struct kinfo_proc 1663a014c56SJohn Baldwin * is returned for zombies with ki_stat set to SZOMB. 16798685dc8SJohn Baldwin */ 16898685dc8SJohn Baldwin for (;;) { 16998685dc8SJohn Baldwin struct kinfo_proc kp; 17098685dc8SJohn Baldwin size_t len; 17198685dc8SJohn Baldwin int mib[4]; 17298685dc8SJohn Baldwin 17398685dc8SJohn Baldwin mib[0] = CTL_KERN; 17498685dc8SJohn Baldwin mib[1] = KERN_PROC; 17598685dc8SJohn Baldwin mib[2] = KERN_PROC_PID; 17698685dc8SJohn Baldwin mib[3] = pid; 17798685dc8SJohn Baldwin len = sizeof(kp); 17898685dc8SJohn Baldwin if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { 17996a9e50eSAlex Richardson REQUIRE_EQ(errno, ESRCH); 18098685dc8SJohn Baldwin break; 18198685dc8SJohn Baldwin } 1823a014c56SJohn Baldwin if (kp.ki_stat == SZOMB) 1833a014c56SJohn Baldwin break; 18498685dc8SJohn Baldwin usleep(5000); 18598685dc8SJohn Baldwin } 18698685dc8SJohn Baldwin } 18798685dc8SJohn Baldwin 188dfa8ba12SJohn Baldwin /* 189c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 190c209e3e2SJohn Baldwin * process exactly once when attached via PT_TRACE_ME. 191c209e3e2SJohn Baldwin */ 192c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_trace_me); 193c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_trace_me, tc) 194c209e3e2SJohn Baldwin { 195c209e3e2SJohn Baldwin pid_t child, wpid; 196c209e3e2SJohn Baldwin int status; 197c209e3e2SJohn Baldwin 198c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 199c209e3e2SJohn Baldwin if (child == 0) { 200c209e3e2SJohn Baldwin /* Child process. */ 20198685dc8SJohn Baldwin trace_me(); 202c209e3e2SJohn Baldwin 203b98cb919SJohn Baldwin _exit(1); 204c209e3e2SJohn Baldwin } 205c209e3e2SJohn Baldwin 206c209e3e2SJohn Baldwin /* Parent process. */ 207c209e3e2SJohn Baldwin 208c209e3e2SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 209c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 21096a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 211c209e3e2SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 21296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 213c209e3e2SJohn Baldwin 214c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 215c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 216c209e3e2SJohn Baldwin 217c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 218c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 21996a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 220c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 22196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 222c209e3e2SJohn Baldwin 223c209e3e2SJohn Baldwin /* The child should no longer exist. */ 224c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 22596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 22696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 227c209e3e2SJohn Baldwin } 228c209e3e2SJohn Baldwin 229c209e3e2SJohn Baldwin /* 230c209e3e2SJohn Baldwin * Verify that a parent debugger process "sees" the exit of a debugged 231c209e3e2SJohn Baldwin * process exactly once when attached via PT_ATTACH. 232c209e3e2SJohn Baldwin */ 233c209e3e2SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_wait_after_attach); 234c209e3e2SJohn Baldwin ATF_TC_BODY(ptrace__parent_wait_after_attach, tc) 235c209e3e2SJohn Baldwin { 236c209e3e2SJohn Baldwin pid_t child, wpid; 237c209e3e2SJohn Baldwin int cpipe[2], status; 238c209e3e2SJohn Baldwin char c; 239c209e3e2SJohn Baldwin 24096a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 241c209e3e2SJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 242c209e3e2SJohn Baldwin if (child == 0) { 243c209e3e2SJohn Baldwin /* Child process. */ 244c209e3e2SJohn Baldwin close(cpipe[0]); 245c209e3e2SJohn Baldwin 246c209e3e2SJohn Baldwin /* Wait for the parent to attach. */ 24796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(0, read(cpipe[1], &c, sizeof(c))); 248c209e3e2SJohn Baldwin 249b98cb919SJohn Baldwin _exit(1); 250c209e3e2SJohn Baldwin } 251c209e3e2SJohn Baldwin close(cpipe[1]); 252c209e3e2SJohn Baldwin 253c209e3e2SJohn Baldwin /* Parent process. */ 254c209e3e2SJohn Baldwin 255c209e3e2SJohn Baldwin /* Attach to the child process. */ 25698685dc8SJohn Baldwin attach_child(child); 257c209e3e2SJohn Baldwin 258c209e3e2SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 259c209e3e2SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 260c209e3e2SJohn Baldwin 261c209e3e2SJohn Baldwin /* Signal the child to exit. */ 262c209e3e2SJohn Baldwin close(cpipe[0]); 263c209e3e2SJohn Baldwin 264c209e3e2SJohn Baldwin /* The second wait() should report the exit status. */ 265c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 26696a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 267c209e3e2SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 26896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 269c209e3e2SJohn Baldwin 270c209e3e2SJohn Baldwin /* The child should no longer exist. */ 271c209e3e2SJohn Baldwin wpid = waitpid(child, &status, 0); 27296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 27396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 274c209e3e2SJohn Baldwin } 275c209e3e2SJohn Baldwin 27657c74f5bSJohn Baldwin /* 27757c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process only 27857c74f5bSJohn Baldwin * after the debugger has seen it. 27957c74f5bSJohn Baldwin */ 28057c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_child_debugger); 28157c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc) 28257c74f5bSJohn Baldwin { 28357c74f5bSJohn Baldwin pid_t child, debugger, wpid; 28457c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 28557c74f5bSJohn Baldwin char c; 28657c74f5bSJohn Baldwin 28796a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 28857c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 28957c74f5bSJohn Baldwin 29057c74f5bSJohn Baldwin if (child == 0) { 29157c74f5bSJohn Baldwin /* Child process. */ 29257c74f5bSJohn Baldwin close(cpipe[0]); 29357c74f5bSJohn Baldwin 29457c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 295*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 296*1fcbddecSAlex Richardson (ssize_t)sizeof(c)); 29757c74f5bSJohn Baldwin 298b98cb919SJohn Baldwin _exit(1); 29957c74f5bSJohn Baldwin } 30057c74f5bSJohn Baldwin close(cpipe[1]); 30157c74f5bSJohn Baldwin 30296a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 30357c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 30457c74f5bSJohn Baldwin 30557c74f5bSJohn Baldwin if (debugger == 0) { 30657c74f5bSJohn Baldwin /* Debugger process. */ 30757c74f5bSJohn Baldwin close(dpipe[0]); 30857c74f5bSJohn Baldwin 309dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 31057c74f5bSJohn Baldwin 31157c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 31296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 313dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 31496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 31557c74f5bSJohn Baldwin 316dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 31757c74f5bSJohn Baldwin 31857c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 319*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 320*1fcbddecSAlex Richardson (ssize_t)sizeof(c)); 32157c74f5bSJohn Baldwin 32257c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 32396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), 0); 32457c74f5bSJohn Baldwin 32557c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 32696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 327dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 32896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 32957c74f5bSJohn Baldwin 330b98cb919SJohn Baldwin _exit(0); 33157c74f5bSJohn Baldwin } 33257c74f5bSJohn Baldwin close(dpipe[1]); 33357c74f5bSJohn Baldwin 33457c74f5bSJohn Baldwin /* Parent process. */ 33557c74f5bSJohn Baldwin 33657c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 337*1fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 33857c74f5bSJohn Baldwin 33957c74f5bSJohn Baldwin /* Release the child. */ 340*1fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 34196a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 34257c74f5bSJohn Baldwin close(cpipe[0]); 34357c74f5bSJohn Baldwin 34498685dc8SJohn Baldwin wait_for_zombie(child); 34557c74f5bSJohn Baldwin 34657c74f5bSJohn Baldwin /* 3472f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 3482f021998SJohn Baldwin * report. The parent should see the child as non-exited 3492f021998SJohn Baldwin * until the debugger sees the exit. 35057c74f5bSJohn Baldwin */ 35157c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 35296a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 35357c74f5bSJohn Baldwin 35457c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 35557c74f5bSJohn Baldwin close(dpipe[0]); 35657c74f5bSJohn Baldwin 35757c74f5bSJohn Baldwin /* Wait for the debugger. */ 35857c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 35996a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 36057c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 36196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 36257c74f5bSJohn Baldwin 36357c74f5bSJohn Baldwin /* The child process should now be ready. */ 36457c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 36596a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 36657c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 36796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 36857c74f5bSJohn Baldwin } 36957c74f5bSJohn Baldwin 37057c74f5bSJohn Baldwin /* 37157c74f5bSJohn Baldwin * Verify that a parent process "sees" the exit of a debugged process 37257c74f5bSJohn Baldwin * only after a non-direct-child debugger has seen it. In particular, 37357c74f5bSJohn Baldwin * various wait() calls in the parent must avoid failing with ESRCH by 37457c74f5bSJohn Baldwin * checking the parent's orphan list for the debugee. 37557c74f5bSJohn Baldwin */ 37657c74f5bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__parent_sees_exit_after_unrelated_debugger); 37757c74f5bSJohn Baldwin ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) 37857c74f5bSJohn Baldwin { 37957c74f5bSJohn Baldwin pid_t child, debugger, fpid, wpid; 38057c74f5bSJohn Baldwin int cpipe[2], dpipe[2], status; 38157c74f5bSJohn Baldwin char c; 38257c74f5bSJohn Baldwin 38396a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 38457c74f5bSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 38557c74f5bSJohn Baldwin 38657c74f5bSJohn Baldwin if (child == 0) { 38757c74f5bSJohn Baldwin /* Child process. */ 38857c74f5bSJohn Baldwin close(cpipe[0]); 38957c74f5bSJohn Baldwin 39057c74f5bSJohn Baldwin /* Wait for parent to be ready. */ 391*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 392*1fcbddecSAlex Richardson (ssize_t)sizeof(c)); 39357c74f5bSJohn Baldwin 394b98cb919SJohn Baldwin _exit(1); 39557c74f5bSJohn Baldwin } 39657c74f5bSJohn Baldwin close(cpipe[1]); 39757c74f5bSJohn Baldwin 39896a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 39957c74f5bSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 40057c74f5bSJohn Baldwin 40157c74f5bSJohn Baldwin if (debugger == 0) { 40257c74f5bSJohn Baldwin /* Debugger parent. */ 40357c74f5bSJohn Baldwin 40457c74f5bSJohn Baldwin /* 40557c74f5bSJohn Baldwin * Fork again and drop the debugger parent so that the 40657c74f5bSJohn Baldwin * debugger is not a child of the main parent. 40757c74f5bSJohn Baldwin */ 408dfa8ba12SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 40957c74f5bSJohn Baldwin if (fpid != 0) 410b98cb919SJohn Baldwin _exit(2); 41157c74f5bSJohn Baldwin 41257c74f5bSJohn Baldwin /* Debugger process. */ 41357c74f5bSJohn Baldwin close(dpipe[0]); 41457c74f5bSJohn Baldwin 415dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 41657c74f5bSJohn Baldwin 41757c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 41896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 419dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 42096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42157c74f5bSJohn Baldwin 422dfa8ba12SJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 42357c74f5bSJohn Baldwin 42457c74f5bSJohn Baldwin /* Signal parent that debugger is attached. */ 425*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 426*1fcbddecSAlex Richardson (ssize_t)sizeof(c)); 42757c74f5bSJohn Baldwin 42857c74f5bSJohn Baldwin /* Wait for parent's failed wait. */ 429*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(dpipe[1], &c, sizeof(c)), 430*1fcbddecSAlex Richardson (ssize_t)sizeof(c)); 43157c74f5bSJohn Baldwin 43257c74f5bSJohn Baldwin wpid = waitpid(child, &status, 0); 43396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 434dfa8ba12SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 43596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 43657c74f5bSJohn Baldwin 437b98cb919SJohn Baldwin _exit(0); 43857c74f5bSJohn Baldwin } 439eddb85c6SJohn Baldwin close(dpipe[1]); 44057c74f5bSJohn Baldwin 44157c74f5bSJohn Baldwin /* Parent process. */ 44257c74f5bSJohn Baldwin 44357c74f5bSJohn Baldwin /* Wait for the debugger parent process to exit. */ 44457c74f5bSJohn Baldwin wpid = waitpid(debugger, &status, 0); 44596a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 44657c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 44796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 44857c74f5bSJohn Baldwin 44957c74f5bSJohn Baldwin /* A WNOHANG wait here should see the non-exited child. */ 45057c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 45196a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 45257c74f5bSJohn Baldwin 45357c74f5bSJohn Baldwin /* Wait for the debugger to attach to the child. */ 454*1fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 45557c74f5bSJohn Baldwin 45657c74f5bSJohn Baldwin /* Release the child. */ 457*1fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 45896a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &c, sizeof(c)), 0); 45957c74f5bSJohn Baldwin close(cpipe[0]); 46057c74f5bSJohn Baldwin 46198685dc8SJohn Baldwin wait_for_zombie(child); 46257c74f5bSJohn Baldwin 46357c74f5bSJohn Baldwin /* 4642f021998SJohn Baldwin * This wait should return a pid of 0 to indicate no status to 4652f021998SJohn Baldwin * report. The parent should see the child as non-exited 4662f021998SJohn Baldwin * until the debugger sees the exit. 46757c74f5bSJohn Baldwin */ 46857c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 46996a9e50eSAlex Richardson REQUIRE_EQ(wpid, 0); 47057c74f5bSJohn Baldwin 47157c74f5bSJohn Baldwin /* Signal the debugger to wait for the child. */ 472*1fcbddecSAlex Richardson REQUIRE_EQ(write(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 47357c74f5bSJohn Baldwin 47457c74f5bSJohn Baldwin /* Wait for the debugger. */ 47596a9e50eSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), 0); 476eddb85c6SJohn Baldwin close(dpipe[0]); 47757c74f5bSJohn Baldwin 47857c74f5bSJohn Baldwin /* The child process should now be ready. */ 47957c74f5bSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 48096a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 48157c74f5bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 48296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 48357c74f5bSJohn Baldwin } 48457c74f5bSJohn Baldwin 48598685dc8SJohn Baldwin /* 486128c9bc0SMark Johnston * Make sure that we can collect the exit status of an orphaned process. 487128c9bc0SMark Johnston */ 488128c9bc0SMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__parent_exits_before_child); 489128c9bc0SMark Johnston ATF_TC_BODY(ptrace__parent_exits_before_child, tc) 490128c9bc0SMark Johnston { 491128c9bc0SMark Johnston ssize_t n; 492128c9bc0SMark Johnston int cpipe1[2], cpipe2[2], gcpipe[2], status; 493128c9bc0SMark Johnston pid_t child, gchild; 494128c9bc0SMark Johnston 49596a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe1), 0); 49696a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe2), 0); 49796a9e50eSAlex Richardson REQUIRE_EQ(pipe(gcpipe), 0); 498128c9bc0SMark Johnston 49996a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 500128c9bc0SMark Johnston 501128c9bc0SMark Johnston ATF_REQUIRE((child = fork()) != -1); 502128c9bc0SMark Johnston if (child == 0) { 503128c9bc0SMark Johnston CHILD_REQUIRE((gchild = fork()) != -1); 504128c9bc0SMark Johnston if (gchild == 0) { 505128c9bc0SMark Johnston status = 1; 506128c9bc0SMark Johnston do { 507128c9bc0SMark Johnston n = read(gcpipe[0], &status, sizeof(status)); 508128c9bc0SMark Johnston } while (n == -1 && errno == EINTR); 509128c9bc0SMark Johnston _exit(status); 510128c9bc0SMark Johnston } 511128c9bc0SMark Johnston 512*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe1[1], &gchild, sizeof(gchild)), 513*1fcbddecSAlex Richardson (ssize_t)sizeof(gchild)); 514*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe2[0], &status, sizeof(status)), 515*1fcbddecSAlex Richardson (ssize_t)sizeof(status)); 516128c9bc0SMark Johnston _exit(status); 517128c9bc0SMark Johnston } 518128c9bc0SMark Johnston 519*1fcbddecSAlex Richardson REQUIRE_EQ(read(cpipe1[0], &gchild, sizeof(gchild)), 520*1fcbddecSAlex Richardson (ssize_t)sizeof(gchild)); 521128c9bc0SMark Johnston 52296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, gchild, NULL, 0), 0); 523128c9bc0SMark Johnston 524128c9bc0SMark Johnston status = 0; 525*1fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe2[1], &status, sizeof(status)), 526*1fcbddecSAlex Richardson (ssize_t)sizeof(status)); 52796a9e50eSAlex Richardson REQUIRE_EQ(waitpid(child, &status, 0), child); 52896a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 52996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 530128c9bc0SMark Johnston 531128c9bc0SMark Johnston status = 0; 532*1fcbddecSAlex Richardson REQUIRE_EQ(write(gcpipe[1], &status, sizeof(status)), 533*1fcbddecSAlex Richardson (ssize_t)sizeof(status)); 53496a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 535128c9bc0SMark Johnston ATF_REQUIRE(WIFSTOPPED(status)); 53696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, gchild, (caddr_t)1, 0), 0); 53796a9e50eSAlex Richardson REQUIRE_EQ(waitpid(gchild, &status, 0), gchild); 53896a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 53996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 540128c9bc0SMark Johnston 54196a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[0]), 0); 54296a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe1[1]), 0); 54396a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[0]), 0); 54496a9e50eSAlex Richardson REQUIRE_EQ(close(cpipe2[1]), 0); 54596a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[0]), 0); 54696a9e50eSAlex Richardson REQUIRE_EQ(close(gcpipe[1]), 0); 547128c9bc0SMark Johnston } 548128c9bc0SMark Johnston 549128c9bc0SMark Johnston /* 55098685dc8SJohn Baldwin * The parent process should always act the same regardless of how the 55198685dc8SJohn Baldwin * debugger is attached to it. 55298685dc8SJohn Baldwin */ 55398685dc8SJohn Baldwin static __dead2 void 554189ac973SJohn Baldwin follow_fork_parent(bool use_vfork) 55598685dc8SJohn Baldwin { 55698685dc8SJohn Baldwin pid_t fpid, wpid; 55798685dc8SJohn Baldwin int status; 55898685dc8SJohn Baldwin 559189ac973SJohn Baldwin if (use_vfork) 560189ac973SJohn Baldwin CHILD_REQUIRE((fpid = vfork()) != -1); 561189ac973SJohn Baldwin else 56298685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 56398685dc8SJohn Baldwin 56498685dc8SJohn Baldwin if (fpid == 0) 56598685dc8SJohn Baldwin /* Child */ 566b98cb919SJohn Baldwin _exit(2); 56798685dc8SJohn Baldwin 56898685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 56996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 57098685dc8SJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 57196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 2); 57298685dc8SJohn Baldwin 573b98cb919SJohn Baldwin _exit(1); 57498685dc8SJohn Baldwin } 57598685dc8SJohn Baldwin 57698685dc8SJohn Baldwin /* 57798685dc8SJohn Baldwin * Helper routine for follow fork tests. This waits for two stops 57898685dc8SJohn Baldwin * that report both "sides" of a fork. It returns the pid of the new 57998685dc8SJohn Baldwin * child process. 58098685dc8SJohn Baldwin */ 58198685dc8SJohn Baldwin static pid_t 582189ac973SJohn Baldwin handle_fork_events(pid_t parent, struct ptrace_lwpinfo *ppl) 58398685dc8SJohn Baldwin { 58498685dc8SJohn Baldwin struct ptrace_lwpinfo pl; 58598685dc8SJohn Baldwin bool fork_reported[2]; 58698685dc8SJohn Baldwin pid_t child, wpid; 58798685dc8SJohn Baldwin int i, status; 58898685dc8SJohn Baldwin 58998685dc8SJohn Baldwin fork_reported[0] = false; 59098685dc8SJohn Baldwin fork_reported[1] = false; 59198685dc8SJohn Baldwin child = -1; 59298685dc8SJohn Baldwin 59398685dc8SJohn Baldwin /* 59498685dc8SJohn Baldwin * Each process should report a fork event. The parent should 59598685dc8SJohn Baldwin * report a PL_FLAG_FORKED event, and the child should report 59698685dc8SJohn Baldwin * a PL_FLAG_CHILD event. 59798685dc8SJohn Baldwin */ 59898685dc8SJohn Baldwin for (i = 0; i < 2; i++) { 59998685dc8SJohn Baldwin wpid = wait(&status); 60098685dc8SJohn Baldwin ATF_REQUIRE(wpid > 0); 60198685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 60298685dc8SJohn Baldwin 60398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 60498685dc8SJohn Baldwin sizeof(pl)) != -1); 60598685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 60698685dc8SJohn Baldwin 0); 60798685dc8SJohn Baldwin ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != 60898685dc8SJohn Baldwin (PL_FLAG_FORKED | PL_FLAG_CHILD)); 60998685dc8SJohn Baldwin if (pl.pl_flags & PL_FLAG_CHILD) { 61098685dc8SJohn Baldwin ATF_REQUIRE(wpid != parent); 61196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 61298685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[1]); 61398685dc8SJohn Baldwin if (child == -1) 61498685dc8SJohn Baldwin child = wpid; 61598685dc8SJohn Baldwin else 61696a9e50eSAlex Richardson REQUIRE_EQ(child, wpid); 617189ac973SJohn Baldwin if (ppl != NULL) 618189ac973SJohn Baldwin ppl[1] = pl; 61998685dc8SJohn Baldwin fork_reported[1] = true; 62098685dc8SJohn Baldwin } else { 62196a9e50eSAlex Richardson REQUIRE_EQ(wpid, parent); 62296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 62398685dc8SJohn Baldwin ATF_REQUIRE(!fork_reported[0]); 62498685dc8SJohn Baldwin if (child == -1) 62598685dc8SJohn Baldwin child = pl.pl_child_pid; 62698685dc8SJohn Baldwin else 62796a9e50eSAlex Richardson REQUIRE_EQ(child, pl.pl_child_pid); 628189ac973SJohn Baldwin if (ppl != NULL) 629189ac973SJohn Baldwin ppl[0] = pl; 63098685dc8SJohn Baldwin fork_reported[0] = true; 63198685dc8SJohn Baldwin } 63298685dc8SJohn Baldwin } 63398685dc8SJohn Baldwin 63498685dc8SJohn Baldwin return (child); 63598685dc8SJohn Baldwin } 63698685dc8SJohn Baldwin 63798685dc8SJohn Baldwin /* 63898685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 63998685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 64098685dc8SJohn Baldwin * when both processes remain attached to the debugger. 64198685dc8SJohn Baldwin */ 64298685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached); 64398685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached, tc) 64498685dc8SJohn Baldwin { 645479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 64698685dc8SJohn Baldwin int status; 64798685dc8SJohn Baldwin 64898685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 64998685dc8SJohn Baldwin if (fpid == 0) { 65098685dc8SJohn Baldwin trace_me(); 651189ac973SJohn Baldwin follow_fork_parent(false); 65298685dc8SJohn Baldwin } 65398685dc8SJohn Baldwin 65498685dc8SJohn Baldwin /* Parent process. */ 65598685dc8SJohn Baldwin children[0] = fpid; 65698685dc8SJohn Baldwin 65798685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 65898685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 65996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 66098685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 66196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 66298685dc8SJohn Baldwin 66398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 66498685dc8SJohn Baldwin 66598685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 66698685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 66798685dc8SJohn Baldwin 668189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 66998685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 67098685dc8SJohn Baldwin 67198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 67298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 67398685dc8SJohn Baldwin 67498685dc8SJohn Baldwin /* 67598685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 67698685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 67798685dc8SJohn Baldwin */ 67898685dc8SJohn Baldwin wpid = wait(&status); 67996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 68098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 68196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 68298685dc8SJohn Baldwin 68398685dc8SJohn Baldwin wpid = wait(&status); 68496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 68598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 68696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 68798685dc8SJohn Baldwin 68898685dc8SJohn Baldwin wpid = wait(&status); 68996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 69096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 69198685dc8SJohn Baldwin } 69298685dc8SJohn Baldwin 69398685dc8SJohn Baldwin /* 69498685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 69598685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 69698685dc8SJohn Baldwin * child process is detached after it reports its fork. 69798685dc8SJohn Baldwin */ 69898685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached); 69998685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached, tc) 70098685dc8SJohn Baldwin { 701479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 70298685dc8SJohn Baldwin int status; 70398685dc8SJohn Baldwin 70498685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 70598685dc8SJohn Baldwin if (fpid == 0) { 70698685dc8SJohn Baldwin trace_me(); 707189ac973SJohn Baldwin follow_fork_parent(false); 70898685dc8SJohn Baldwin } 70998685dc8SJohn Baldwin 71098685dc8SJohn Baldwin /* Parent process. */ 71198685dc8SJohn Baldwin children[0] = fpid; 71298685dc8SJohn Baldwin 71398685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 71498685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 71596a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 71698685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 71796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 71898685dc8SJohn Baldwin 71998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 72098685dc8SJohn Baldwin 72198685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 72298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 72398685dc8SJohn Baldwin 724189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 72598685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 72698685dc8SJohn Baldwin 72798685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 72898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 72998685dc8SJohn Baldwin 73098685dc8SJohn Baldwin /* 73198685dc8SJohn Baldwin * Should not see any status from the grandchild now, only the 73298685dc8SJohn Baldwin * child. 73398685dc8SJohn Baldwin */ 73498685dc8SJohn Baldwin wpid = wait(&status); 73596a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 73698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 73796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 73898685dc8SJohn Baldwin 73998685dc8SJohn Baldwin wpid = wait(&status); 74096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 74196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 74298685dc8SJohn Baldwin } 74398685dc8SJohn Baldwin 74498685dc8SJohn Baldwin /* 74598685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 74698685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 74798685dc8SJohn Baldwin * traced parent is detached after the fork. 74898685dc8SJohn Baldwin */ 74998685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached); 75098685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc) 75198685dc8SJohn Baldwin { 752479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 75398685dc8SJohn Baldwin int status; 75498685dc8SJohn Baldwin 75598685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 75698685dc8SJohn Baldwin if (fpid == 0) { 75798685dc8SJohn Baldwin trace_me(); 758189ac973SJohn Baldwin follow_fork_parent(false); 75998685dc8SJohn Baldwin } 76098685dc8SJohn Baldwin 76198685dc8SJohn Baldwin /* Parent process. */ 76298685dc8SJohn Baldwin children[0] = fpid; 76398685dc8SJohn Baldwin 76498685dc8SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 76598685dc8SJohn Baldwin wpid = waitpid(children[0], &status, 0); 76696a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 76798685dc8SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 76896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 76998685dc8SJohn Baldwin 77098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 77198685dc8SJohn Baldwin 77298685dc8SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 77398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 77498685dc8SJohn Baldwin 775189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 77698685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 77798685dc8SJohn Baldwin 77898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 77998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 78098685dc8SJohn Baldwin 78198685dc8SJohn Baldwin /* 78298685dc8SJohn Baldwin * The child can't exit until the grandchild reports status, so the 78398685dc8SJohn Baldwin * grandchild should report its exit first to the debugger. 78498685dc8SJohn Baldwin * 78598685dc8SJohn Baldwin * Even though the child process is detached, it is still a 78698685dc8SJohn Baldwin * child of the debugger, so it will still report it's exit 78798685dc8SJohn Baldwin * after the grandchild. 78898685dc8SJohn Baldwin */ 78998685dc8SJohn Baldwin wpid = wait(&status); 79096a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 79198685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 79296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 79398685dc8SJohn Baldwin 79498685dc8SJohn Baldwin wpid = wait(&status); 79596a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 79698685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 79796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 79898685dc8SJohn Baldwin 79998685dc8SJohn Baldwin wpid = wait(&status); 80096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 80196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 80298685dc8SJohn Baldwin } 80398685dc8SJohn Baldwin 80498685dc8SJohn Baldwin static void 80598685dc8SJohn Baldwin attach_fork_parent(int cpipe[2]) 80698685dc8SJohn Baldwin { 80798685dc8SJohn Baldwin pid_t fpid; 80898685dc8SJohn Baldwin 80998685dc8SJohn Baldwin close(cpipe[0]); 81098685dc8SJohn Baldwin 81198685dc8SJohn Baldwin /* Double-fork to disassociate from the debugger. */ 81298685dc8SJohn Baldwin CHILD_REQUIRE((fpid = fork()) != -1); 81398685dc8SJohn Baldwin if (fpid != 0) 814b98cb919SJohn Baldwin _exit(3); 81598685dc8SJohn Baldwin 81698685dc8SJohn Baldwin /* Send the pid of the disassociated child to the debugger. */ 81798685dc8SJohn Baldwin fpid = getpid(); 818*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe[1], &fpid, sizeof(fpid)), 819*1fcbddecSAlex Richardson (ssize_t)sizeof(fpid)); 82098685dc8SJohn Baldwin 82198685dc8SJohn Baldwin /* Wait for the debugger to attach. */ 82296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &fpid, sizeof(fpid)), 0); 82398685dc8SJohn Baldwin } 82498685dc8SJohn Baldwin 82598685dc8SJohn Baldwin /* 82698685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork and 82798685dc8SJohn Baldwin * that the traced parent sees the exit of the child after the debugger 82898685dc8SJohn Baldwin * when both processes remain attached to the debugger. In this test 82998685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 83098685dc8SJohn Baldwin */ 83198685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached_unrelated_debugger); 83298685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_both_attached_unrelated_debugger, tc) 83398685dc8SJohn Baldwin { 834479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 83598685dc8SJohn Baldwin int cpipe[2], status; 83698685dc8SJohn Baldwin 83796a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 83898685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 83998685dc8SJohn Baldwin if (fpid == 0) { 84098685dc8SJohn Baldwin attach_fork_parent(cpipe); 841189ac973SJohn Baldwin follow_fork_parent(false); 84298685dc8SJohn Baldwin } 84398685dc8SJohn Baldwin 84498685dc8SJohn Baldwin /* Parent process. */ 84598685dc8SJohn Baldwin close(cpipe[1]); 84698685dc8SJohn Baldwin 84798685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 84898685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 84996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 85098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 85196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 85298685dc8SJohn Baldwin 85398685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 85496a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 855*1fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 85698685dc8SJohn Baldwin 85798685dc8SJohn Baldwin /* Attach to the fork parent. */ 85898685dc8SJohn Baldwin attach_child(children[0]); 85998685dc8SJohn Baldwin 86098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 86198685dc8SJohn Baldwin 86298685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 86398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 86498685dc8SJohn Baldwin 86598685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 86698685dc8SJohn Baldwin close(cpipe[0]); 86798685dc8SJohn Baldwin 868189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 86998685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 87098685dc8SJohn Baldwin 87198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 87298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 87398685dc8SJohn Baldwin 87498685dc8SJohn Baldwin /* 87598685dc8SJohn Baldwin * The fork parent can't exit until the child reports status, 87698685dc8SJohn Baldwin * so the child should report its exit first to the debugger. 87798685dc8SJohn Baldwin */ 87898685dc8SJohn Baldwin wpid = wait(&status); 87996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 88098685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 88196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 88298685dc8SJohn Baldwin 88398685dc8SJohn Baldwin wpid = wait(&status); 88496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 88598685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 88696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 88798685dc8SJohn Baldwin 88898685dc8SJohn Baldwin wpid = wait(&status); 88996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 89096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 89198685dc8SJohn Baldwin } 89298685dc8SJohn Baldwin 89398685dc8SJohn Baldwin /* 89498685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 89598685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the new 89698685dc8SJohn Baldwin * child process is detached after it reports its fork. In this test 89798685dc8SJohn Baldwin * the parent that forks is not a direct child of the debugger. 89898685dc8SJohn Baldwin */ 89998685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger); 90098685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc) 90198685dc8SJohn Baldwin { 902479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 90398685dc8SJohn Baldwin int cpipe[2], status; 90498685dc8SJohn Baldwin 90596a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 90698685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 90798685dc8SJohn Baldwin if (fpid == 0) { 90898685dc8SJohn Baldwin attach_fork_parent(cpipe); 909189ac973SJohn Baldwin follow_fork_parent(false); 91098685dc8SJohn Baldwin } 91198685dc8SJohn Baldwin 91298685dc8SJohn Baldwin /* Parent process. */ 91398685dc8SJohn Baldwin close(cpipe[1]); 91498685dc8SJohn Baldwin 91598685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 91698685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 91796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 91898685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 91996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 92098685dc8SJohn Baldwin 92198685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 92296a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 923*1fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 92498685dc8SJohn Baldwin 92598685dc8SJohn Baldwin /* Attach to the fork parent. */ 92698685dc8SJohn Baldwin attach_child(children[0]); 92798685dc8SJohn Baldwin 92898685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 92998685dc8SJohn Baldwin 93098685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 93198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 93298685dc8SJohn Baldwin 93398685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 93498685dc8SJohn Baldwin close(cpipe[0]); 93598685dc8SJohn Baldwin 936189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 93798685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 93898685dc8SJohn Baldwin 93998685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 94098685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); 94198685dc8SJohn Baldwin 94298685dc8SJohn Baldwin /* 94398685dc8SJohn Baldwin * Should not see any status from the child now, only the fork 94498685dc8SJohn Baldwin * parent. 94598685dc8SJohn Baldwin */ 94698685dc8SJohn Baldwin wpid = wait(&status); 94796a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 94898685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 94996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 95098685dc8SJohn Baldwin 95198685dc8SJohn Baldwin wpid = wait(&status); 95296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 95396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 95498685dc8SJohn Baldwin } 95598685dc8SJohn Baldwin 95698685dc8SJohn Baldwin /* 95798685dc8SJohn Baldwin * Verify that a new child process is stopped after a followed fork 95898685dc8SJohn Baldwin * and that the traced parent sees the exit of the child when the 95998685dc8SJohn Baldwin * traced parent is detached after the fork. In this test the parent 96098685dc8SJohn Baldwin * that forks is not a direct child of the debugger. 96198685dc8SJohn Baldwin */ 96298685dc8SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger); 96398685dc8SJohn Baldwin ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc) 96498685dc8SJohn Baldwin { 965479b610dSJohn Baldwin pid_t children[2], fpid, wpid; 96698685dc8SJohn Baldwin int cpipe[2], status; 96798685dc8SJohn Baldwin 96896a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 96998685dc8SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 97098685dc8SJohn Baldwin if (fpid == 0) { 97198685dc8SJohn Baldwin attach_fork_parent(cpipe); 972189ac973SJohn Baldwin follow_fork_parent(false); 97398685dc8SJohn Baldwin } 97498685dc8SJohn Baldwin 97598685dc8SJohn Baldwin /* Parent process. */ 97698685dc8SJohn Baldwin close(cpipe[1]); 97798685dc8SJohn Baldwin 97898685dc8SJohn Baldwin /* Wait for the direct child to exit. */ 97998685dc8SJohn Baldwin wpid = waitpid(fpid, &status, 0); 98096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 98198685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 98296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 3); 98398685dc8SJohn Baldwin 98498685dc8SJohn Baldwin /* Read the pid of the fork parent. */ 98596a9e50eSAlex Richardson REQUIRE_EQ(read(cpipe[0], &children[0], sizeof(children[0])), 986*1fcbddecSAlex Richardson (ssize_t)sizeof(children[0])); 98798685dc8SJohn Baldwin 98898685dc8SJohn Baldwin /* Attach to the fork parent. */ 98998685dc8SJohn Baldwin attach_child(children[0]); 99098685dc8SJohn Baldwin 99198685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 99298685dc8SJohn Baldwin 99398685dc8SJohn Baldwin /* Continue the fork parent ignoring the SIGSTOP. */ 99498685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 99598685dc8SJohn Baldwin 99698685dc8SJohn Baldwin /* Signal the fork parent to continue. */ 99798685dc8SJohn Baldwin close(cpipe[0]); 99898685dc8SJohn Baldwin 999189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], NULL); 100098685dc8SJohn Baldwin ATF_REQUIRE(children[1] > 0); 100198685dc8SJohn Baldwin 100298685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); 100398685dc8SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 100498685dc8SJohn Baldwin 100598685dc8SJohn Baldwin /* 100698685dc8SJohn Baldwin * Should not see any status from the fork parent now, only 100798685dc8SJohn Baldwin * the child. 100898685dc8SJohn Baldwin */ 100998685dc8SJohn Baldwin wpid = wait(&status); 101096a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 101198685dc8SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 101296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 101398685dc8SJohn Baldwin 101498685dc8SJohn Baldwin wpid = wait(&status); 101596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 101696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 101798685dc8SJohn Baldwin } 101898685dc8SJohn Baldwin 1019368b2b1cSJohn Baldwin /* 1020368b2b1cSJohn Baldwin * Verify that a child process does not see an unrelated debugger as its 1021368b2b1cSJohn Baldwin * parent but sees its original parent process. 1022368b2b1cSJohn Baldwin */ 1023368b2b1cSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__getppid); 1024368b2b1cSJohn Baldwin ATF_TC_BODY(ptrace__getppid, tc) 1025368b2b1cSJohn Baldwin { 1026368b2b1cSJohn Baldwin pid_t child, debugger, ppid, wpid; 1027368b2b1cSJohn Baldwin int cpipe[2], dpipe[2], status; 1028368b2b1cSJohn Baldwin char c; 1029368b2b1cSJohn Baldwin 103096a9e50eSAlex Richardson REQUIRE_EQ(pipe(cpipe), 0); 1031368b2b1cSJohn Baldwin ATF_REQUIRE((child = fork()) != -1); 1032368b2b1cSJohn Baldwin 1033368b2b1cSJohn Baldwin if (child == 0) { 1034368b2b1cSJohn Baldwin /* Child process. */ 1035368b2b1cSJohn Baldwin close(cpipe[0]); 1036368b2b1cSJohn Baldwin 1037368b2b1cSJohn Baldwin /* Wait for parent to be ready. */ 1038*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(read(cpipe[1], &c, sizeof(c)), 1039*1fcbddecSAlex Richardson (ssize_t)sizeof(c)); 1040368b2b1cSJohn Baldwin 1041368b2b1cSJohn Baldwin /* Report the parent PID to the parent. */ 1042368b2b1cSJohn Baldwin ppid = getppid(); 1043*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(cpipe[1], &ppid, sizeof(ppid)), 1044*1fcbddecSAlex Richardson (ssize_t)sizeof(ppid)); 1045368b2b1cSJohn Baldwin 1046368b2b1cSJohn Baldwin _exit(1); 1047368b2b1cSJohn Baldwin } 1048368b2b1cSJohn Baldwin close(cpipe[1]); 1049368b2b1cSJohn Baldwin 105096a9e50eSAlex Richardson REQUIRE_EQ(pipe(dpipe), 0); 1051368b2b1cSJohn Baldwin ATF_REQUIRE((debugger = fork()) != -1); 1052368b2b1cSJohn Baldwin 1053368b2b1cSJohn Baldwin if (debugger == 0) { 1054368b2b1cSJohn Baldwin /* Debugger process. */ 1055368b2b1cSJohn Baldwin close(dpipe[0]); 1056368b2b1cSJohn Baldwin 1057368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); 1058368b2b1cSJohn Baldwin 1059368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 106096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1061368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFSTOPPED(status)); 106296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1063368b2b1cSJohn Baldwin 1064368b2b1cSJohn Baldwin CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 1065368b2b1cSJohn Baldwin 1066368b2b1cSJohn Baldwin /* Signal parent that debugger is attached. */ 1067*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(write(dpipe[1], &c, sizeof(c)), 1068*1fcbddecSAlex Richardson (ssize_t)sizeof(c)); 1069368b2b1cSJohn Baldwin 1070368b2b1cSJohn Baldwin /* Wait for traced child to exit. */ 1071368b2b1cSJohn Baldwin wpid = waitpid(child, &status, 0); 107296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, child); 1073368b2b1cSJohn Baldwin CHILD_REQUIRE(WIFEXITED(status)); 107496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WEXITSTATUS(status), 1); 1075368b2b1cSJohn Baldwin 1076368b2b1cSJohn Baldwin _exit(0); 1077368b2b1cSJohn Baldwin } 1078368b2b1cSJohn Baldwin close(dpipe[1]); 1079368b2b1cSJohn Baldwin 1080368b2b1cSJohn Baldwin /* Parent process. */ 1081368b2b1cSJohn Baldwin 1082368b2b1cSJohn Baldwin /* Wait for the debugger to attach to the child. */ 1083*1fcbddecSAlex Richardson REQUIRE_EQ(read(dpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 1084368b2b1cSJohn Baldwin 1085368b2b1cSJohn Baldwin /* Release the child. */ 1086*1fcbddecSAlex Richardson REQUIRE_EQ(write(cpipe[0], &c, sizeof(c)), (ssize_t)sizeof(c)); 1087368b2b1cSJohn Baldwin 1088368b2b1cSJohn Baldwin /* Read the parent PID from the child. */ 1089*1fcbddecSAlex Richardson REQUIRE_EQ(read(cpipe[0], &ppid, sizeof(ppid)), (ssize_t)sizeof(ppid)); 1090368b2b1cSJohn Baldwin close(cpipe[0]); 1091368b2b1cSJohn Baldwin 109296a9e50eSAlex Richardson REQUIRE_EQ(ppid, getpid()); 1093368b2b1cSJohn Baldwin 1094368b2b1cSJohn Baldwin /* Wait for the debugger. */ 1095368b2b1cSJohn Baldwin wpid = waitpid(debugger, &status, 0); 109696a9e50eSAlex Richardson REQUIRE_EQ(wpid, debugger); 1097368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 109896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 1099368b2b1cSJohn Baldwin 1100368b2b1cSJohn Baldwin /* The child process should now be ready. */ 1101368b2b1cSJohn Baldwin wpid = waitpid(child, &status, WNOHANG); 110296a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 1103368b2b1cSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 110496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1105368b2b1cSJohn Baldwin } 1106368b2b1cSJohn Baldwin 1107189ac973SJohn Baldwin /* 1108189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1109189ac973SJohn Baldwin * child process created via fork() reports the correct value. 1110189ac973SJohn Baldwin */ 1111189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_fork); 1112189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_fork, tc) 1113189ac973SJohn Baldwin { 1114189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1115189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1116189ac973SJohn Baldwin int status; 1117189ac973SJohn Baldwin 1118189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1119189ac973SJohn Baldwin if (fpid == 0) { 1120189ac973SJohn Baldwin trace_me(); 1121189ac973SJohn Baldwin follow_fork_parent(false); 1122189ac973SJohn Baldwin } 1123189ac973SJohn Baldwin 1124189ac973SJohn Baldwin /* Parent process. */ 1125189ac973SJohn Baldwin children[0] = fpid; 1126189ac973SJohn Baldwin 1127189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1128189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 112996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1130189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 113196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1132189ac973SJohn Baldwin 1133189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1134189ac973SJohn Baldwin 1135189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1136189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1137189ac973SJohn Baldwin 1138189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1139189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1140189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1141189ac973SJohn Baldwin 1142189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1143189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1144*1fcbddecSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, (unsigned)SYS_fork); 114596a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 114696a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1147189ac973SJohn Baldwin 1148189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1149189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1150189ac973SJohn Baldwin 1151189ac973SJohn Baldwin /* 1152189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1153189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1154189ac973SJohn Baldwin */ 1155189ac973SJohn Baldwin wpid = wait(&status); 115696a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1157189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 115896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1159189ac973SJohn Baldwin 1160189ac973SJohn Baldwin wpid = wait(&status); 116196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1162189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 116396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1164189ac973SJohn Baldwin 1165189ac973SJohn Baldwin wpid = wait(&status); 116696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 116796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1168189ac973SJohn Baldwin } 1169189ac973SJohn Baldwin 1170189ac973SJohn Baldwin /* 1171189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1172189ac973SJohn Baldwin * child process created via vfork() reports the correct value. 1173189ac973SJohn Baldwin */ 1174189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_vfork); 1175189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_vfork, tc) 1176189ac973SJohn Baldwin { 1177189ac973SJohn Baldwin struct ptrace_lwpinfo pl[2]; 1178189ac973SJohn Baldwin pid_t children[2], fpid, wpid; 1179189ac973SJohn Baldwin int status; 1180189ac973SJohn Baldwin 1181189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1182189ac973SJohn Baldwin if (fpid == 0) { 1183189ac973SJohn Baldwin trace_me(); 1184189ac973SJohn Baldwin follow_fork_parent(true); 1185189ac973SJohn Baldwin } 1186189ac973SJohn Baldwin 1187189ac973SJohn Baldwin /* Parent process. */ 1188189ac973SJohn Baldwin children[0] = fpid; 1189189ac973SJohn Baldwin 1190189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1191189ac973SJohn Baldwin wpid = waitpid(children[0], &status, 0); 119296a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1193189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 119496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1195189ac973SJohn Baldwin 1196189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); 1197189ac973SJohn Baldwin 1198189ac973SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1199189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1200189ac973SJohn Baldwin 1201189ac973SJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1202189ac973SJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1203189ac973SJohn Baldwin ATF_REQUIRE(children[1] > 0); 1204189ac973SJohn Baldwin 1205189ac973SJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_SCX) != 0); 1206189ac973SJohn Baldwin ATF_REQUIRE((pl[1].pl_flags & PL_FLAG_SCX) != 0); 1207*1fcbddecSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, (unsigned)SYS_vfork); 120896a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_code, pl[1].pl_syscall_code); 120996a9e50eSAlex Richardson REQUIRE_EQ(pl[0].pl_syscall_narg, pl[1].pl_syscall_narg); 1210189ac973SJohn Baldwin 1211189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1212189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1213189ac973SJohn Baldwin 1214189ac973SJohn Baldwin /* 1215189ac973SJohn Baldwin * The child can't exit until the grandchild reports status, so the 1216189ac973SJohn Baldwin * grandchild should report its exit first to the debugger. 1217189ac973SJohn Baldwin */ 1218189ac973SJohn Baldwin wpid = wait(&status); 121996a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1220189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 122196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1222189ac973SJohn Baldwin 1223189ac973SJohn Baldwin wpid = wait(&status); 122496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1225189ac973SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 122696a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1227189ac973SJohn Baldwin 1228189ac973SJohn Baldwin wpid = wait(&status); 122996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 123096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1231189ac973SJohn Baldwin } 1232189ac973SJohn Baldwin 1233189ac973SJohn Baldwin static void * 1234189ac973SJohn Baldwin simple_thread(void *arg __unused) 1235189ac973SJohn Baldwin { 1236189ac973SJohn Baldwin 1237189ac973SJohn Baldwin pthread_exit(NULL); 1238189ac973SJohn Baldwin } 1239189ac973SJohn Baldwin 12405fcfab6eSJohn Baldwin static __dead2 void 12415fcfab6eSJohn Baldwin simple_thread_main(void) 12425fcfab6eSJohn Baldwin { 12435fcfab6eSJohn Baldwin pthread_t thread; 12445fcfab6eSJohn Baldwin 124596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, simple_thread, NULL), 0); 124696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(thread, NULL), 0); 12475fcfab6eSJohn Baldwin exit(1); 12485fcfab6eSJohn Baldwin } 12495fcfab6eSJohn Baldwin 1250189ac973SJohn Baldwin /* 1251189ac973SJohn Baldwin * Verify that pl_syscall_code in struct ptrace_lwpinfo for a new 1252189ac973SJohn Baldwin * thread reports the correct value. 1253189ac973SJohn Baldwin */ 1254189ac973SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__new_child_pl_syscall_code_thread); 1255189ac973SJohn Baldwin ATF_TC_BODY(ptrace__new_child_pl_syscall_code_thread, tc) 1256189ac973SJohn Baldwin { 1257189ac973SJohn Baldwin struct ptrace_lwpinfo pl; 1258189ac973SJohn Baldwin pid_t fpid, wpid; 1259e72879e5SJohn Baldwin lwpid_t mainlwp; 1260189ac973SJohn Baldwin int status; 1261189ac973SJohn Baldwin 1262189ac973SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1263189ac973SJohn Baldwin if (fpid == 0) { 1264189ac973SJohn Baldwin trace_me(); 12655fcfab6eSJohn Baldwin simple_thread_main(); 1266189ac973SJohn Baldwin } 1267189ac973SJohn Baldwin 1268189ac973SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1269189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 127096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1271189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 127296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1273189ac973SJohn Baldwin 1274189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1275189ac973SJohn Baldwin sizeof(pl)) != -1); 1276e72879e5SJohn Baldwin mainlwp = pl.pl_lwpid; 1277189ac973SJohn Baldwin 1278189ac973SJohn Baldwin /* 1279189ac973SJohn Baldwin * Continue the child ignoring the SIGSTOP and tracing all 1280189ac973SJohn Baldwin * system call exits. 1281189ac973SJohn Baldwin */ 1282189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_TO_SCX, fpid, (caddr_t)1, 0) != -1); 1283189ac973SJohn Baldwin 1284189ac973SJohn Baldwin /* 1285189ac973SJohn Baldwin * Wait for the new thread to arrive. pthread_create() might 1286189ac973SJohn Baldwin * invoke any number of system calls. For now we just wait 1287189ac973SJohn Baldwin * for the new thread to arrive and make sure it reports a 1288189ac973SJohn Baldwin * valid system call code. If ptrace grows thread event 1289189ac973SJohn Baldwin * reporting then this test can be made more precise. 1290189ac973SJohn Baldwin */ 1291189ac973SJohn Baldwin for (;;) { 1292189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 129396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1294189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 129596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1296189ac973SJohn Baldwin 1297189ac973SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 1298189ac973SJohn Baldwin sizeof(pl)) != -1); 1299189ac973SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SCX) != 0); 1300189ac973SJohn Baldwin ATF_REQUIRE(pl.pl_syscall_code != 0); 1301e72879e5SJohn Baldwin if (pl.pl_lwpid != mainlwp) 1302189ac973SJohn Baldwin /* New thread seen. */ 1303189ac973SJohn Baldwin break; 1304189ac973SJohn Baldwin 130596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1306189ac973SJohn Baldwin } 1307189ac973SJohn Baldwin 1308189ac973SJohn Baldwin /* Wait for the child to exit. */ 130996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1310189ac973SJohn Baldwin for (;;) { 1311189ac973SJohn Baldwin wpid = waitpid(fpid, &status, 0); 131296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1313189ac973SJohn Baldwin if (WIFEXITED(status)) 1314189ac973SJohn Baldwin break; 1315189ac973SJohn Baldwin 1316189ac973SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 131796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 131896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 1319189ac973SJohn Baldwin } 1320189ac973SJohn Baldwin 132196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1322189ac973SJohn Baldwin 1323189ac973SJohn Baldwin wpid = wait(&status); 132496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 132596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1326189ac973SJohn Baldwin } 1327189ac973SJohn Baldwin 13285fcfab6eSJohn Baldwin /* 13295fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a child thread. 13305fcfab6eSJohn Baldwin */ 13315fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events); 13325fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events, tc) 13335fcfab6eSJohn Baldwin { 13345fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 13355fcfab6eSJohn Baldwin pid_t fpid, wpid; 13365fcfab6eSJohn Baldwin lwpid_t lwps[2]; 13375fcfab6eSJohn Baldwin int status; 13385fcfab6eSJohn Baldwin 13395fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 13405fcfab6eSJohn Baldwin if (fpid == 0) { 13415fcfab6eSJohn Baldwin trace_me(); 13425fcfab6eSJohn Baldwin simple_thread_main(); 13435fcfab6eSJohn Baldwin } 13445fcfab6eSJohn Baldwin 13455fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 13465fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 134796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13485fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 134996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 13505fcfab6eSJohn Baldwin 13515fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 13525fcfab6eSJohn Baldwin sizeof(pl)) != -1); 13535fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 13545fcfab6eSJohn Baldwin 135596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 13565fcfab6eSJohn Baldwin 13575fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 135896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13595fcfab6eSJohn Baldwin 13605fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 13615fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 136296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13635fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 136496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13655fcfab6eSJohn Baldwin 13665fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 136796a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 13685fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 13695fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 13705fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 13715fcfab6eSJohn Baldwin 137296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13735fcfab6eSJohn Baldwin 13745fcfab6eSJohn Baldwin /* The next event should be for the child thread's death. */ 13755fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 137696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 13775fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 137896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 13795fcfab6eSJohn Baldwin 13805fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 138196a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 13825fcfab6eSJohn Baldwin (PL_FLAG_EXITED | PL_FLAG_SCE)); 138396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 13845fcfab6eSJohn Baldwin 138596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 13865fcfab6eSJohn Baldwin 13875fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 13885fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 13895fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 139096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 13915fcfab6eSJohn Baldwin 13925fcfab6eSJohn Baldwin wpid = wait(&status); 139396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 139496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 13955fcfab6eSJohn Baldwin } 13965fcfab6eSJohn Baldwin 13975fcfab6eSJohn Baldwin static void * 13985fcfab6eSJohn Baldwin exec_thread(void *arg __unused) 13995fcfab6eSJohn Baldwin { 14005fcfab6eSJohn Baldwin 14015fcfab6eSJohn Baldwin execl("/usr/bin/true", "true", NULL); 14025fcfab6eSJohn Baldwin exit(127); 14035fcfab6eSJohn Baldwin } 14045fcfab6eSJohn Baldwin 14055fcfab6eSJohn Baldwin static __dead2 void 14065fcfab6eSJohn Baldwin exec_thread_main(void) 14075fcfab6eSJohn Baldwin { 14085fcfab6eSJohn Baldwin pthread_t thread; 14095fcfab6eSJohn Baldwin 141096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&thread, NULL, exec_thread, NULL), 0); 14115fcfab6eSJohn Baldwin for (;;) 14125fcfab6eSJohn Baldwin sleep(60); 14135fcfab6eSJohn Baldwin exit(1); 14145fcfab6eSJohn Baldwin } 14155fcfab6eSJohn Baldwin 14165fcfab6eSJohn Baldwin /* 14175fcfab6eSJohn Baldwin * Verify that the expected LWP events are reported for a multithreaded 14185fcfab6eSJohn Baldwin * process that calls execve(2). 14195fcfab6eSJohn Baldwin */ 14205fcfab6eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__lwp_events_exec); 14215fcfab6eSJohn Baldwin ATF_TC_BODY(ptrace__lwp_events_exec, tc) 14225fcfab6eSJohn Baldwin { 14235fcfab6eSJohn Baldwin struct ptrace_lwpinfo pl; 14245fcfab6eSJohn Baldwin pid_t fpid, wpid; 14255fcfab6eSJohn Baldwin lwpid_t lwps[2]; 14265fcfab6eSJohn Baldwin int status; 14275fcfab6eSJohn Baldwin 14285fcfab6eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 14295fcfab6eSJohn Baldwin if (fpid == 0) { 14305fcfab6eSJohn Baldwin trace_me(); 14315fcfab6eSJohn Baldwin exec_thread_main(); 14325fcfab6eSJohn Baldwin } 14335fcfab6eSJohn Baldwin 14345fcfab6eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 14355fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 143696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14375fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 143896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 14395fcfab6eSJohn Baldwin 14405fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 14415fcfab6eSJohn Baldwin sizeof(pl)) != -1); 14425fcfab6eSJohn Baldwin lwps[0] = pl.pl_lwpid; 14435fcfab6eSJohn Baldwin 144496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 14455fcfab6eSJohn Baldwin 14465fcfab6eSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 144796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14485fcfab6eSJohn Baldwin 14495fcfab6eSJohn Baldwin /* The first event should be for the child thread's birth. */ 14505fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 145196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14525fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 145396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14545fcfab6eSJohn Baldwin 14555fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 145696a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 14575fcfab6eSJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 14585fcfab6eSJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 14595fcfab6eSJohn Baldwin lwps[1] = pl.pl_lwpid; 14605fcfab6eSJohn Baldwin 146196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14625fcfab6eSJohn Baldwin 14635fcfab6eSJohn Baldwin /* 14645fcfab6eSJohn Baldwin * The next event should be for the main thread's death due to 14655fcfab6eSJohn Baldwin * single threading from execve(). 14665fcfab6eSJohn Baldwin */ 14675fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 146896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 14695fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 147096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14715fcfab6eSJohn Baldwin 14725fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 147396a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXITED | PL_FLAG_SCE)), 14745fcfab6eSJohn Baldwin (PL_FLAG_EXITED)); 147596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[0]); 14765fcfab6eSJohn Baldwin 147796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14785fcfab6eSJohn Baldwin 14795fcfab6eSJohn Baldwin /* The next event should be for the child process's exec. */ 14805fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14815fcfab6eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 148296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 14835fcfab6eSJohn Baldwin 14845fcfab6eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 148596a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 14865fcfab6eSJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 148796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, lwps[1]); 14885fcfab6eSJohn Baldwin 148996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 14905fcfab6eSJohn Baldwin 14915fcfab6eSJohn Baldwin /* The last event should be for the child process's exit. */ 14925fcfab6eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 14935fcfab6eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 149496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 14955fcfab6eSJohn Baldwin 14965fcfab6eSJohn Baldwin wpid = wait(&status); 149796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 149896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 14995fcfab6eSJohn Baldwin } 15005fcfab6eSJohn Baldwin 15013340c45bSJohn Baldwin static void 15023340c45bSJohn Baldwin handler(int sig __unused) 15033340c45bSJohn Baldwin { 15043340c45bSJohn Baldwin } 15053340c45bSJohn Baldwin 15063340c45bSJohn Baldwin static void 15073340c45bSJohn Baldwin signal_main(void) 15083340c45bSJohn Baldwin { 15093340c45bSJohn Baldwin 15103340c45bSJohn Baldwin signal(SIGINFO, handler); 15113340c45bSJohn Baldwin raise(SIGINFO); 15123340c45bSJohn Baldwin exit(0); 15133340c45bSJohn Baldwin } 15143340c45bSJohn Baldwin 15153340c45bSJohn Baldwin /* 15163340c45bSJohn Baldwin * Verify that the expected ptrace event is reported for a signal. 15173340c45bSJohn Baldwin */ 15183340c45bSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__siginfo); 15193340c45bSJohn Baldwin ATF_TC_BODY(ptrace__siginfo, tc) 15203340c45bSJohn Baldwin { 15213340c45bSJohn Baldwin struct ptrace_lwpinfo pl; 15223340c45bSJohn Baldwin pid_t fpid, wpid; 15233340c45bSJohn Baldwin int status; 15243340c45bSJohn Baldwin 15253340c45bSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15263340c45bSJohn Baldwin if (fpid == 0) { 15273340c45bSJohn Baldwin trace_me(); 15283340c45bSJohn Baldwin signal_main(); 15293340c45bSJohn Baldwin } 15303340c45bSJohn Baldwin 15313340c45bSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15323340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 153396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15343340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 153596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15363340c45bSJohn Baldwin 153796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15383340c45bSJohn Baldwin 15393340c45bSJohn Baldwin /* The next event should be for the SIGINFO. */ 15403340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15413340c45bSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 154296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINFO); 15433340c45bSJohn Baldwin 15443340c45bSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 154596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 15463340c45bSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 154796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, SI_LWP); 154896a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_pid, wpid); 15493340c45bSJohn Baldwin 155096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15513340c45bSJohn Baldwin 15523340c45bSJohn Baldwin /* The last event should be for the child process's exit. */ 15533340c45bSJohn Baldwin wpid = waitpid(fpid, &status, 0); 15543340c45bSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 155596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15563340c45bSJohn Baldwin 15573340c45bSJohn Baldwin wpid = wait(&status); 155896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 155996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15603340c45bSJohn Baldwin } 15613340c45bSJohn Baldwin 15628d570f64SJohn Baldwin /* 15638d570f64SJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_EXEC. 15648d570f64SJohn Baldwin */ 15658d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable); 15668d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_disable, tc) 15678d570f64SJohn Baldwin { 15688d570f64SJohn Baldwin pid_t fpid, wpid; 15698d570f64SJohn Baldwin int events, status; 15708d570f64SJohn Baldwin 15718d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 15728d570f64SJohn Baldwin if (fpid == 0) { 15738d570f64SJohn Baldwin trace_me(); 15748d570f64SJohn Baldwin exec_thread(NULL); 15758d570f64SJohn Baldwin } 15768d570f64SJohn Baldwin 15778d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 15788d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 157996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 15808d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 158196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 15828d570f64SJohn Baldwin 15838d570f64SJohn Baldwin events = 0; 15848d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 15858d570f64SJohn Baldwin sizeof(events)) == 0); 15868d570f64SJohn Baldwin 158796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 15888d570f64SJohn Baldwin 15898d570f64SJohn Baldwin /* Should get one event at exit. */ 15908d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 15918d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 159296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 15938d570f64SJohn Baldwin 15948d570f64SJohn Baldwin wpid = wait(&status); 159596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 159696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 15978d570f64SJohn Baldwin } 15988d570f64SJohn Baldwin 15998d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable); 16008d570f64SJohn Baldwin ATF_TC_BODY(ptrace__ptrace_exec_enable, tc) 16018d570f64SJohn Baldwin { 16028d570f64SJohn Baldwin struct ptrace_lwpinfo pl; 16038d570f64SJohn Baldwin pid_t fpid, wpid; 16048d570f64SJohn Baldwin int events, status; 16058d570f64SJohn Baldwin 16068d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16078d570f64SJohn Baldwin if (fpid == 0) { 16088d570f64SJohn Baldwin trace_me(); 16098d570f64SJohn Baldwin exec_thread(NULL); 16108d570f64SJohn Baldwin } 16118d570f64SJohn Baldwin 16128d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16138d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 161496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16158d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 161696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16178d570f64SJohn Baldwin 16188d570f64SJohn Baldwin events = PTRACE_EXEC; 16198d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 16208d570f64SJohn Baldwin sizeof(events)) == 0); 16218d570f64SJohn Baldwin 162296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16238d570f64SJohn Baldwin 16248d570f64SJohn Baldwin /* The next event should be for the child process's exec. */ 16258d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16268d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 162796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 16288d570f64SJohn Baldwin 16298d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 163096a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)), 16318d570f64SJohn Baldwin (PL_FLAG_EXEC | PL_FLAG_SCX)); 16328d570f64SJohn Baldwin 163396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16348d570f64SJohn Baldwin 16358d570f64SJohn Baldwin /* The last event should be for the child process's exit. */ 16368d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16378d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 163896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16398d570f64SJohn Baldwin 16408d570f64SJohn Baldwin wpid = wait(&status); 164196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 164296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16438d570f64SJohn Baldwin } 16448d570f64SJohn Baldwin 16458d570f64SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__event_mask); 16468d570f64SJohn Baldwin ATF_TC_BODY(ptrace__event_mask, tc) 16478d570f64SJohn Baldwin { 16488d570f64SJohn Baldwin pid_t fpid, wpid; 16498d570f64SJohn Baldwin int events, status; 16508d570f64SJohn Baldwin 16518d570f64SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 16528d570f64SJohn Baldwin if (fpid == 0) { 16538d570f64SJohn Baldwin trace_me(); 16548d570f64SJohn Baldwin exit(0); 16558d570f64SJohn Baldwin } 16568d570f64SJohn Baldwin 16578d570f64SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 16588d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 165996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 16608d570f64SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 166196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 16628d570f64SJohn Baldwin 16638d570f64SJohn Baldwin /* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */ 16648d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 1) != -1); 16658d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16668d570f64SJohn Baldwin sizeof(events)) == 0); 16678d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_FORK); 16688d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 0) != -1); 16698d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16708d570f64SJohn Baldwin sizeof(events)) == 0); 16718d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_FORK)); 16728d570f64SJohn Baldwin 16738d570f64SJohn Baldwin /* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */ 16748d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1); 16758d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16768d570f64SJohn Baldwin sizeof(events)) == 0); 16778d570f64SJohn Baldwin ATF_REQUIRE(events & PTRACE_LWP); 16788d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1); 16798d570f64SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 16808d570f64SJohn Baldwin sizeof(events)) == 0); 16818d570f64SJohn Baldwin ATF_REQUIRE(!(events & PTRACE_LWP)); 16828d570f64SJohn Baldwin 168396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 16848d570f64SJohn Baldwin 16858d570f64SJohn Baldwin /* Should get one event at exit. */ 16868d570f64SJohn Baldwin wpid = waitpid(fpid, &status, 0); 16878d570f64SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 168896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 16898d570f64SJohn Baldwin 16908d570f64SJohn Baldwin wpid = wait(&status); 169196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 169296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 16938d570f64SJohn Baldwin } 16948d570f64SJohn Baldwin 1695fc4f075aSJohn Baldwin /* 1696fc4f075aSJohn Baldwin * Verify that the expected ptrace events are reported for PTRACE_VFORK. 1697fc4f075aSJohn Baldwin */ 1698fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork); 1699fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork, tc) 1700fc4f075aSJohn Baldwin { 1701fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl; 1702fc4f075aSJohn Baldwin pid_t fpid, wpid; 1703fc4f075aSJohn Baldwin int events, status; 1704fc4f075aSJohn Baldwin 1705fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1706fc4f075aSJohn Baldwin if (fpid == 0) { 1707fc4f075aSJohn Baldwin trace_me(); 1708fc4f075aSJohn Baldwin follow_fork_parent(true); 1709fc4f075aSJohn Baldwin } 1710fc4f075aSJohn Baldwin 1711fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1712fc4f075aSJohn Baldwin wpid = waitpid(fpid, &status, 0); 171396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1714fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 171596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1716fc4f075aSJohn Baldwin 1717fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 1718fc4f075aSJohn Baldwin sizeof(events)) == 0); 1719fc4f075aSJohn Baldwin events |= PTRACE_VFORK; 1720fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 1721fc4f075aSJohn Baldwin sizeof(events)) == 0); 1722fc4f075aSJohn Baldwin 1723fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1724fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1725fc4f075aSJohn Baldwin 1726fc4f075aSJohn Baldwin /* The next event should report the end of the vfork. */ 1727fc4f075aSJohn Baldwin wpid = wait(&status); 172896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1729fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 173096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1731fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 1732fc4f075aSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_VFORK_DONE) != 0); 1733fc4f075aSJohn Baldwin 1734fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) != -1); 1735fc4f075aSJohn Baldwin 1736fc4f075aSJohn Baldwin wpid = wait(&status); 173796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 1738fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 173996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1740fc4f075aSJohn Baldwin 1741fc4f075aSJohn Baldwin wpid = wait(&status); 174296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 174396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1744fc4f075aSJohn Baldwin } 1745fc4f075aSJohn Baldwin 1746fc4f075aSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__ptrace_vfork_follow); 1747fc4f075aSJohn Baldwin ATF_TC_BODY(ptrace__ptrace_vfork_follow, tc) 1748fc4f075aSJohn Baldwin { 1749fc4f075aSJohn Baldwin struct ptrace_lwpinfo pl[2]; 1750fc4f075aSJohn Baldwin pid_t children[2], fpid, wpid; 1751fc4f075aSJohn Baldwin int events, status; 1752fc4f075aSJohn Baldwin 1753fc4f075aSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 1754fc4f075aSJohn Baldwin if (fpid == 0) { 1755fc4f075aSJohn Baldwin trace_me(); 1756fc4f075aSJohn Baldwin follow_fork_parent(true); 1757fc4f075aSJohn Baldwin } 1758fc4f075aSJohn Baldwin 1759fc4f075aSJohn Baldwin /* Parent process. */ 1760fc4f075aSJohn Baldwin children[0] = fpid; 1761fc4f075aSJohn Baldwin 1762fc4f075aSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 1763fc4f075aSJohn Baldwin wpid = waitpid(children[0], &status, 0); 176496a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1765fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 176696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 1767fc4f075aSJohn Baldwin 1768fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, children[0], (caddr_t)&events, 1769fc4f075aSJohn Baldwin sizeof(events)) == 0); 1770fc4f075aSJohn Baldwin events |= PTRACE_FORK | PTRACE_VFORK; 1771fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, children[0], (caddr_t)&events, 1772fc4f075aSJohn Baldwin sizeof(events)) == 0); 1773fc4f075aSJohn Baldwin 1774fc4f075aSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 1775fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1776fc4f075aSJohn Baldwin 1777fc4f075aSJohn Baldwin /* Wait for both halves of the fork event to get reported. */ 1778fc4f075aSJohn Baldwin children[1] = handle_fork_events(children[0], pl); 1779fc4f075aSJohn Baldwin ATF_REQUIRE(children[1] > 0); 1780fc4f075aSJohn Baldwin 1781fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORKED) != 0); 1782fc4f075aSJohn Baldwin 1783fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1784fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); 1785fc4f075aSJohn Baldwin 1786fc4f075aSJohn Baldwin /* 1787fc4f075aSJohn Baldwin * The child can't exit until the grandchild reports status, so the 1788fc4f075aSJohn Baldwin * grandchild should report its exit first to the debugger. 1789fc4f075aSJohn Baldwin */ 1790fc4f075aSJohn Baldwin wpid = waitpid(children[1], &status, 0); 179196a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[1]); 1792fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 179396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 1794fc4f075aSJohn Baldwin 1795fc4f075aSJohn Baldwin /* 1796fc4f075aSJohn Baldwin * The child should report it's vfork() completion before it 1797fc4f075aSJohn Baldwin * exits. 1798fc4f075aSJohn Baldwin */ 1799fc4f075aSJohn Baldwin wpid = wait(&status); 180096a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1801fc4f075aSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 180296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 1803fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl[0], sizeof(pl[0])) != 1804fc4f075aSJohn Baldwin -1); 1805fc4f075aSJohn Baldwin ATF_REQUIRE((pl[0].pl_flags & PL_FLAG_VFORK_DONE) != 0); 1806fc4f075aSJohn Baldwin 1807fc4f075aSJohn Baldwin ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); 1808fc4f075aSJohn Baldwin 1809fc4f075aSJohn Baldwin wpid = wait(&status); 181096a9e50eSAlex Richardson REQUIRE_EQ(wpid, children[0]); 1811fc4f075aSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 181296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 1813fc4f075aSJohn Baldwin 1814fc4f075aSJohn Baldwin wpid = wait(&status); 181596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 181696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 1817fc4f075aSJohn Baldwin } 1818fc4f075aSJohn Baldwin 1819403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 1820e2ebfbbfSEric Badger /* 182182a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 182282a4538fSEric Badger * process exit when stopped due to a breakpoint trap. 182382a4538fSEric Badger */ 182482a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_breakpoint); 182582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_breakpoint, tc) 182682a4538fSEric Badger { 182782a4538fSEric Badger pid_t fpid, wpid; 182882a4538fSEric Badger int status; 182982a4538fSEric Badger 183082a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 183182a4538fSEric Badger if (fpid == 0) { 183282a4538fSEric Badger trace_me(); 18339e0d1159SEric Badger breakpoint(); 183482a4538fSEric Badger exit(1); 183582a4538fSEric Badger } 183682a4538fSEric Badger 183782a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 183882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 183996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 184082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 184196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 184282a4538fSEric Badger 184382a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 184496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 184582a4538fSEric Badger 184682a4538fSEric Badger /* The second wait() should report hitting the breakpoint. */ 184782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 184896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 184982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 185096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 185182a4538fSEric Badger 185282a4538fSEric Badger /* Kill the child process. */ 185396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 185482a4538fSEric Badger 185582a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 185682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 185796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 185882a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 185996a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 186082a4538fSEric Badger 186182a4538fSEric Badger wpid = wait(&status); 186296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 186396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 186482a4538fSEric Badger } 1865403e331dSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 186682a4538fSEric Badger 186782a4538fSEric Badger /* 186882a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 186982a4538fSEric Badger * process exit when stopped inside of a system call. 187082a4538fSEric Badger */ 187182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_system_call); 187282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_system_call, tc) 187382a4538fSEric Badger { 187482a4538fSEric Badger struct ptrace_lwpinfo pl; 187582a4538fSEric Badger pid_t fpid, wpid; 187682a4538fSEric Badger int status; 187782a4538fSEric Badger 187882a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 187982a4538fSEric Badger if (fpid == 0) { 188082a4538fSEric Badger trace_me(); 188182a4538fSEric Badger getpid(); 188282a4538fSEric Badger exit(1); 188382a4538fSEric Badger } 188482a4538fSEric Badger 188582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 188682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 188796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 188882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 188996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 189082a4538fSEric Badger 189182a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 189296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 189382a4538fSEric Badger 189482a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 189582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 189696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 189782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 189896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 189982a4538fSEric Badger 190082a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 190182a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 190282a4538fSEric Badger 190382a4538fSEric Badger /* Kill the child process. */ 190496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 190582a4538fSEric Badger 190682a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 190782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 190896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 190982a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 191096a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 191182a4538fSEric Badger 191282a4538fSEric Badger wpid = wait(&status); 191396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 191496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 191582a4538fSEric Badger } 191682a4538fSEric Badger 191782a4538fSEric Badger /* 191882a4538fSEric Badger * Verify that no more events are reported after PT_KILL except for the 191982a4538fSEric Badger * process exit when killing a multithreaded process. 192082a4538fSEric Badger */ 192182a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_threads); 192282a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_threads, tc) 192382a4538fSEric Badger { 192482a4538fSEric Badger struct ptrace_lwpinfo pl; 192582a4538fSEric Badger pid_t fpid, wpid; 192682a4538fSEric Badger lwpid_t main_lwp; 192782a4538fSEric Badger int status; 192882a4538fSEric Badger 192982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 193082a4538fSEric Badger if (fpid == 0) { 193182a4538fSEric Badger trace_me(); 193282a4538fSEric Badger simple_thread_main(); 193382a4538fSEric Badger } 193482a4538fSEric Badger 193582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 193682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 193796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 193882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 193996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 194082a4538fSEric Badger 194182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 194282a4538fSEric Badger sizeof(pl)) != -1); 194382a4538fSEric Badger main_lwp = pl.pl_lwpid; 194482a4538fSEric Badger 194596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 194682a4538fSEric Badger 194782a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 194896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 194982a4538fSEric Badger 195082a4538fSEric Badger /* The first event should be for the child thread's birth. */ 195182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 195296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 195382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 195496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 195582a4538fSEric Badger 195682a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 195796a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 195882a4538fSEric Badger (PL_FLAG_BORN | PL_FLAG_SCX)); 195982a4538fSEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 196082a4538fSEric Badger 196182a4538fSEric Badger /* Kill the child process. */ 196296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 196382a4538fSEric Badger 196482a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 196582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 196696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 196782a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 196896a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 196982a4538fSEric Badger 197082a4538fSEric Badger wpid = wait(&status); 197196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 197296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 197382a4538fSEric Badger } 197482a4538fSEric Badger 197582a4538fSEric Badger static void * 197682a4538fSEric Badger mask_usr1_thread(void *arg) 197782a4538fSEric Badger { 197882a4538fSEric Badger pthread_barrier_t *pbarrier; 197982a4538fSEric Badger sigset_t sigmask; 198082a4538fSEric Badger 198182a4538fSEric Badger pbarrier = (pthread_barrier_t*)arg; 198282a4538fSEric Badger 198382a4538fSEric Badger sigemptyset(&sigmask); 198482a4538fSEric Badger sigaddset(&sigmask, SIGUSR1); 198596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 198682a4538fSEric Badger 198782a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 198882a4538fSEric Badger pthread_barrier_wait(pbarrier); 198982a4538fSEric Badger 199082a4538fSEric Badger for (;;) 199182a4538fSEric Badger sleep(60); 199282a4538fSEric Badger 199382a4538fSEric Badger return (NULL); 199482a4538fSEric Badger } 199582a4538fSEric Badger 199682a4538fSEric Badger /* 199782a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other signals 199882a4538fSEric Badger * and prevents spurious stops due to those other signals. 199982a4538fSEric Badger */ 20003cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_signal); 20013cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_signal, tc) 20023cf56bb4SEnji Cooper { 20033cf56bb4SEnji Cooper 20043cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 20053cf56bb4SEnji Cooper } 200682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_signal, tc) 200782a4538fSEric Badger { 200882a4538fSEric Badger pid_t fpid, wpid; 200982a4538fSEric Badger int status; 201082a4538fSEric Badger cpuset_t setmask; 201182a4538fSEric Badger pthread_t t; 201282a4538fSEric Badger pthread_barrier_t barrier; 2013bc2be1d3SEric Badger struct sched_param sched_param; 201482a4538fSEric Badger 201582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 201682a4538fSEric Badger if (fpid == 0) { 2017bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 201882a4538fSEric Badger CPU_ZERO(&setmask); 201982a4538fSEric Badger CPU_SET(0, &setmask); 202082a4538fSEric Badger cpusetid_t setid; 202196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 202282a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 202382a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 202482a4538fSEric Badger 202596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 202682a4538fSEric Badger 202782a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 202882a4538fSEric Badger (void*)&barrier) == 0); 202982a4538fSEric Badger 2030bc2be1d3SEric Badger /* 2031bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2032bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2033bc2be1d3SEric Badger * thread runs first. 2034bc2be1d3SEric Badger */ 2035bc2be1d3SEric Badger sched_param.sched_priority = 2036bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2037bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2038bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2039bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2040bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2041bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2042bc2be1d3SEric Badger &sched_param) == 0); 2043bc2be1d3SEric Badger 204482a4538fSEric Badger sigset_t sigmask; 204582a4538fSEric Badger sigemptyset(&sigmask); 204682a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 204796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 204882a4538fSEric Badger 204982a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 205082a4538fSEric Badger pthread_barrier_wait(&barrier); 205182a4538fSEric Badger 205282a4538fSEric Badger trace_me(); 205382a4538fSEric Badger 205482a4538fSEric Badger for (;;) 205582a4538fSEric Badger sleep(60); 205682a4538fSEric Badger 205782a4538fSEric Badger exit(1); 205882a4538fSEric Badger } 205982a4538fSEric Badger 206082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 206182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 206296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 206382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 206496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 206582a4538fSEric Badger 206682a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 206796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 206882a4538fSEric Badger 206982a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 207096a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 207182a4538fSEric Badger 207282a4538fSEric Badger /* The second wait() should report the SIGUSR2. */ 207382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 207496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 207582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 207696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 207782a4538fSEric Badger 207882a4538fSEric Badger /* Send a signal that only the first thread can handle. */ 207996a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 208082a4538fSEric Badger 208182a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 208296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 208382a4538fSEric Badger 208482a4538fSEric Badger /* The last wait() should report the SIGKILL (not the SIGUSR signal). */ 208582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 208696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 208782a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 208896a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 208982a4538fSEric Badger 209082a4538fSEric Badger wpid = wait(&status); 209196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 209296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 209382a4538fSEric Badger } 209482a4538fSEric Badger 209582a4538fSEric Badger /* 209682a4538fSEric Badger * Verify that the SIGKILL from PT_KILL takes priority over other stop events 209782a4538fSEric Badger * and prevents spurious stops caused by those events. 209882a4538fSEric Badger */ 20993cf56bb4SEnji Cooper ATF_TC(ptrace__PT_KILL_competing_stop); 21003cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__PT_KILL_competing_stop, tc) 21013cf56bb4SEnji Cooper { 21023cf56bb4SEnji Cooper 21033cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 21043cf56bb4SEnji Cooper } 210582a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_competing_stop, tc) 210682a4538fSEric Badger { 210782a4538fSEric Badger pid_t fpid, wpid; 2108bc2be1d3SEric Badger int status; 210982a4538fSEric Badger cpuset_t setmask; 211082a4538fSEric Badger pthread_t t; 211182a4538fSEric Badger pthread_barrier_t barrier; 211282a4538fSEric Badger lwpid_t main_lwp; 211382a4538fSEric Badger struct ptrace_lwpinfo pl; 2114bc2be1d3SEric Badger struct sched_param sched_param; 211582a4538fSEric Badger 211682a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 211782a4538fSEric Badger if (fpid == 0) { 211882a4538fSEric Badger trace_me(); 211982a4538fSEric Badger 2120bc2be1d3SEric Badger /* Bind to one CPU so only one thread at a time will run. */ 212182a4538fSEric Badger CPU_ZERO(&setmask); 212282a4538fSEric Badger CPU_SET(0, &setmask); 212382a4538fSEric Badger cpusetid_t setid; 212496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 212582a4538fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 212682a4538fSEric Badger CPU_WHICH_CPUSET, setid, sizeof(setmask), &setmask) == 0); 212782a4538fSEric Badger 212896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 212982a4538fSEric Badger 213082a4538fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, 213182a4538fSEric Badger (void*)&barrier) == 0); 213282a4538fSEric Badger 2133bc2be1d3SEric Badger /* 2134bc2be1d3SEric Badger * Give the main thread higher priority. The test always 2135bc2be1d3SEric Badger * assumes that, if both threads are able to run, the main 2136bc2be1d3SEric Badger * thread runs first. 2137bc2be1d3SEric Badger */ 2138bc2be1d3SEric Badger sched_param.sched_priority = 2139bc2be1d3SEric Badger (sched_get_priority_max(SCHED_FIFO) + 2140bc2be1d3SEric Badger sched_get_priority_min(SCHED_FIFO)) / 2; 2141bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(pthread_self(), 2142bc2be1d3SEric Badger SCHED_FIFO, &sched_param) == 0); 2143bc2be1d3SEric Badger sched_param.sched_priority -= RQ_PPQ; 2144bc2be1d3SEric Badger CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, 2145bc2be1d3SEric Badger &sched_param) == 0); 2146bc2be1d3SEric Badger 214782a4538fSEric Badger sigset_t sigmask; 214882a4538fSEric Badger sigemptyset(&sigmask); 214982a4538fSEric Badger sigaddset(&sigmask, SIGUSR2); 215096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 215182a4538fSEric Badger 215282a4538fSEric Badger /* Sync up with other thread after sigmask updated. */ 215382a4538fSEric Badger pthread_barrier_wait(&barrier); 215482a4538fSEric Badger 215582a4538fSEric Badger /* Sync up with the test before doing the getpid(). */ 215682a4538fSEric Badger raise(SIGSTOP); 215782a4538fSEric Badger 215882a4538fSEric Badger getpid(); 215982a4538fSEric Badger exit(1); 216082a4538fSEric Badger } 216182a4538fSEric Badger 216282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 216382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 216496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 216582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 216696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 216782a4538fSEric Badger 216882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 216982a4538fSEric Badger main_lwp = pl.pl_lwpid; 217082a4538fSEric Badger 217182a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 217296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 217382a4538fSEric Badger 217482a4538fSEric Badger /* 217582a4538fSEric Badger * Continue until child is done with setup, which is indicated with 217682a4538fSEric Badger * SIGSTOP. Ignore system calls in the meantime. 217782a4538fSEric Badger */ 217882a4538fSEric Badger for (;;) { 217982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 218096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 218182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 218282a4538fSEric Badger if (WSTOPSIG(status) == SIGTRAP) { 218382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 218482a4538fSEric Badger sizeof(pl)) != -1); 218582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 218682a4538fSEric Badger } else { 218796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 218882a4538fSEric Badger break; 218982a4538fSEric Badger } 219096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 219182a4538fSEric Badger } 219282a4538fSEric Badger 2193bc2be1d3SEric Badger /* Proceed, allowing main thread to hit syscall entry for getpid(). */ 219496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 219582a4538fSEric Badger 219682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 219796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 219882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 219996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 220082a4538fSEric Badger 220182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 220282a4538fSEric Badger sizeof(pl)) != -1); 220396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_lwpid, main_lwp); 220482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 2205bc2be1d3SEric Badger /* Prevent the main thread from hitting its syscall exit for now. */ 220696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SUSPEND, main_lwp, 0, 0), 0); 220782a4538fSEric Badger 2208bc2be1d3SEric Badger /* 2209bc2be1d3SEric Badger * Proceed, allowing second thread to hit syscall exit for 2210bc2be1d3SEric Badger * pthread_barrier_wait(). 2211bc2be1d3SEric Badger */ 221296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 2213bc2be1d3SEric Badger 2214bc2be1d3SEric Badger wpid = waitpid(fpid, &status, 0); 221596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2216bc2be1d3SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 221796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 2218bc2be1d3SEric Badger 2219bc2be1d3SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 2220bc2be1d3SEric Badger sizeof(pl)) != -1); 2221bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_lwpid != main_lwp); 2222bc2be1d3SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 222382a4538fSEric Badger 222482a4538fSEric Badger /* Send a signal that only the second thread can handle. */ 222596a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 222682a4538fSEric Badger 222796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 222882a4538fSEric Badger 2229bc2be1d3SEric Badger /* The next wait() should report the SIGUSR2. */ 223082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 223196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 223282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 223396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 223482a4538fSEric Badger 223582a4538fSEric Badger /* Allow the main thread to try to finish its system call. */ 223696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_RESUME, main_lwp, 0, 0), 0); 223782a4538fSEric Badger 223882a4538fSEric Badger /* 223982a4538fSEric Badger * At this point, the main thread is in the middle of a system call and 2240bc2be1d3SEric Badger * has been resumed. The second thread has taken a SIGUSR2 which will 2241bc2be1d3SEric Badger * be replaced with a SIGKILL below. The main thread will get to run 2242bc2be1d3SEric Badger * first. It should notice the kill request (even though the signal 2243bc2be1d3SEric Badger * replacement occurred in the other thread) and exit accordingly. It 2244bc2be1d3SEric Badger * should not stop for the system call exit event. 224582a4538fSEric Badger */ 224682a4538fSEric Badger 224782a4538fSEric Badger /* Replace the SIGUSR2 with a kill. */ 224896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 224982a4538fSEric Badger 225082a4538fSEric Badger /* The last wait() should report the SIGKILL (not a syscall exit). */ 225182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 225296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 225382a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 225496a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 225582a4538fSEric Badger 225682a4538fSEric Badger wpid = wait(&status); 225796a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 225896a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 225982a4538fSEric Badger } 226082a4538fSEric Badger 226182a4538fSEric Badger static void 226282a4538fSEric Badger sigusr1_handler(int sig) 226382a4538fSEric Badger { 226482a4538fSEric Badger 226596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 226682a4538fSEric Badger _exit(2); 226782a4538fSEric Badger } 226882a4538fSEric Badger 226982a4538fSEric Badger /* 227082a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 227182a4538fSEric Badger * a PT_KILL will kill the process. 227282a4538fSEric Badger */ 227382a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_KILL_with_signal_full_sigqueue); 227482a4538fSEric Badger ATF_TC_BODY(ptrace__PT_KILL_with_signal_full_sigqueue, tc) 227582a4538fSEric Badger { 227682a4538fSEric Badger pid_t fpid, wpid; 227782a4538fSEric Badger int status; 227882a4538fSEric Badger int max_pending_per_proc; 227982a4538fSEric Badger size_t len; 228082a4538fSEric Badger int i; 228182a4538fSEric Badger 228282a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 228382a4538fSEric Badger 228482a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 228582a4538fSEric Badger if (fpid == 0) { 228682a4538fSEric Badger trace_me(); 228782a4538fSEric Badger exit(1); 228882a4538fSEric Badger } 228982a4538fSEric Badger 229082a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 229182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 229296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 229382a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 229496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 229582a4538fSEric Badger 229682a4538fSEric Badger len = sizeof(max_pending_per_proc); 229782a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 229882a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 229982a4538fSEric Badger 230082a4538fSEric Badger /* Fill the signal queue. */ 230182a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 230296a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 230382a4538fSEric Badger 230482a4538fSEric Badger /* Kill the child process. */ 230596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 230682a4538fSEric Badger 230782a4538fSEric Badger /* The last wait() should report the SIGKILL. */ 230882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 230996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 231082a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 231196a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 231282a4538fSEric Badger 231382a4538fSEric Badger wpid = wait(&status); 231496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 231596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 231682a4538fSEric Badger } 231782a4538fSEric Badger 231882a4538fSEric Badger /* 231982a4538fSEric Badger * Verify that when stopped at a system call entry, a signal can be 232082a4538fSEric Badger * requested with PT_CONTINUE which will be delivered once the system 232182a4538fSEric Badger * call is complete. 232282a4538fSEric Badger */ 232382a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry); 232482a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry, tc) 232582a4538fSEric Badger { 232682a4538fSEric Badger struct ptrace_lwpinfo pl; 232782a4538fSEric Badger pid_t fpid, wpid; 232882a4538fSEric Badger int status; 232982a4538fSEric Badger 233082a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 233182a4538fSEric Badger 233282a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 233382a4538fSEric Badger if (fpid == 0) { 233482a4538fSEric Badger trace_me(); 233582a4538fSEric Badger getpid(); 233682a4538fSEric Badger exit(1); 233782a4538fSEric Badger } 233882a4538fSEric Badger 233982a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 234082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 234196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 234282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 234396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 234482a4538fSEric Badger 234582a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 234696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 234782a4538fSEric Badger 234882a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 234982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 235096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 235182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 235296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 235382a4538fSEric Badger 235482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 235582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 235682a4538fSEric Badger 235782a4538fSEric Badger /* Continue the child process with a signal. */ 235896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 235982a4538fSEric Badger 236082a4538fSEric Badger for (;;) { 236182a4538fSEric Badger /* 236282a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 236382a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 236482a4538fSEric Badger * past any syscall stops. 236582a4538fSEric Badger */ 236682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 236796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 236882a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 236982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 237082a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 237196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 237282a4538fSEric Badger } else { 237382a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 237496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 237582a4538fSEric Badger break; 237682a4538fSEric Badger } 237782a4538fSEric Badger } 237882a4538fSEric Badger 237982a4538fSEric Badger wpid = wait(&status); 238096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 238196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 238282a4538fSEric Badger } 238382a4538fSEric Badger 238482a4538fSEric Badger static void 238582a4538fSEric Badger sigusr1_counting_handler(int sig) 238682a4538fSEric Badger { 238782a4538fSEric Badger static int counter = 0; 238882a4538fSEric Badger 238996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 239082a4538fSEric Badger counter++; 239182a4538fSEric Badger if (counter == 2) 239282a4538fSEric Badger _exit(2); 239382a4538fSEric Badger } 239482a4538fSEric Badger 239582a4538fSEric Badger /* 239682a4538fSEric Badger * Verify that, when continuing from a stop at system call entry and exit, 239782a4538fSEric Badger * a signal can be requested from both stops, and both will be delivered when 239882a4538fSEric Badger * the system call is complete. 239982a4538fSEric Badger */ 240082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 240182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit, tc) 240282a4538fSEric Badger { 240382a4538fSEric Badger struct ptrace_lwpinfo pl; 240482a4538fSEric Badger pid_t fpid, wpid; 240582a4538fSEric Badger int status; 240682a4538fSEric Badger 240782a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 240882a4538fSEric Badger 240982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 241082a4538fSEric Badger if (fpid == 0) { 241182a4538fSEric Badger trace_me(); 241282a4538fSEric Badger getpid(); 241382a4538fSEric Badger exit(1); 241482a4538fSEric Badger } 241582a4538fSEric Badger 241682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 241782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 241896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 241982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 242096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 242182a4538fSEric Badger 242282a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 242396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 242482a4538fSEric Badger 242582a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 242682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 242796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 242882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 242996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 243082a4538fSEric Badger 243182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 243282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 243382a4538fSEric Badger 243482a4538fSEric Badger /* Continue the child process with a signal. */ 243596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 243682a4538fSEric Badger 243782a4538fSEric Badger /* The third wait() should report a system call exit for getpid(). */ 243882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 243996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 244082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 244196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 244282a4538fSEric Badger 244382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 244482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 244582a4538fSEric Badger 244682a4538fSEric Badger /* Continue the child process with a signal. */ 244796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 244882a4538fSEric Badger 244982a4538fSEric Badger for (;;) { 245082a4538fSEric Badger /* 245182a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 245282a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 245382a4538fSEric Badger * past any syscall stops. 245482a4538fSEric Badger */ 245582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 245696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 245782a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 245882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 245982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 246096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 246182a4538fSEric Badger } else { 246282a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 246396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 246482a4538fSEric Badger break; 246582a4538fSEric Badger } 246682a4538fSEric Badger } 246782a4538fSEric Badger 246882a4538fSEric Badger wpid = wait(&status); 246996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 247096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 247182a4538fSEric Badger } 247282a4538fSEric Badger 247382a4538fSEric Badger /* 247482a4538fSEric Badger * Verify that even if the signal queue is full for a child process, 247582a4538fSEric Badger * a PT_CONTINUE with a signal will not result in loss of that signal. 247682a4538fSEric Badger */ 247782a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_full_sigqueue); 247882a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_full_sigqueue, tc) 247982a4538fSEric Badger { 248082a4538fSEric Badger pid_t fpid, wpid; 248182a4538fSEric Badger int status; 248282a4538fSEric Badger int max_pending_per_proc; 248382a4538fSEric Badger size_t len; 248482a4538fSEric Badger int i; 248582a4538fSEric Badger 248682a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 248782a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_handler) != SIG_ERR); 248882a4538fSEric Badger 248982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 249082a4538fSEric Badger if (fpid == 0) { 249182a4538fSEric Badger trace_me(); 249282a4538fSEric Badger exit(1); 249382a4538fSEric Badger } 249482a4538fSEric Badger 249582a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 249682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 249796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 249882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 249996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 250082a4538fSEric Badger 250182a4538fSEric Badger len = sizeof(max_pending_per_proc); 250282a4538fSEric Badger ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 250382a4538fSEric Badger &max_pending_per_proc, &len, NULL, 0) == 0); 250482a4538fSEric Badger 250582a4538fSEric Badger /* Fill the signal queue. */ 250682a4538fSEric Badger for (i = 0; i < max_pending_per_proc; ++i) 250796a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 250882a4538fSEric Badger 250982a4538fSEric Badger /* Continue with signal. */ 251096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 251182a4538fSEric Badger 251282a4538fSEric Badger for (;;) { 251382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 251496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 251582a4538fSEric Badger if (WIFSTOPPED(status)) { 251696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 251796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 251882a4538fSEric Badger } else { 251982a4538fSEric Badger /* 252082a4538fSEric Badger * The last wait() should report normal _exit from the 252182a4538fSEric Badger * SIGUSR1 handler. 252282a4538fSEric Badger */ 252382a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 252496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 252582a4538fSEric Badger break; 252682a4538fSEric Badger } 252782a4538fSEric Badger } 252882a4538fSEric Badger 252982a4538fSEric Badger wpid = wait(&status); 253096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 253196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 253282a4538fSEric Badger } 253382a4538fSEric Badger 2534753e2922SBryan Drewery static sem_t sigusr1_sem; 2535753e2922SBryan Drewery static int got_usr1; 2536753e2922SBryan Drewery 2537753e2922SBryan Drewery static void 2538753e2922SBryan Drewery sigusr1_sempost_handler(int sig __unused) 2539753e2922SBryan Drewery { 2540753e2922SBryan Drewery 2541753e2922SBryan Drewery got_usr1++; 254296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sem_post(&sigusr1_sem), 0); 2543753e2922SBryan Drewery } 2544753e2922SBryan Drewery 2545753e2922SBryan Drewery /* 2546753e2922SBryan Drewery * Verify that even if the signal queue is full for a child process, 2547753e2922SBryan Drewery * and the signal is masked, a PT_CONTINUE with a signal will not 2548753e2922SBryan Drewery * result in loss of that signal. 2549753e2922SBryan Drewery */ 2550753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 2551753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue, tc) 2552753e2922SBryan Drewery { 2553753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2554753e2922SBryan Drewery pid_t fpid, wpid; 2555753e2922SBryan Drewery int status, err; 2556753e2922SBryan Drewery int max_pending_per_proc; 2557753e2922SBryan Drewery size_t len; 2558753e2922SBryan Drewery int i; 2559753e2922SBryan Drewery sigset_t sigmask; 2560753e2922SBryan Drewery 2561753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR2, handler) != SIG_ERR); 256296a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2563753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2564753e2922SBryan Drewery 2565753e2922SBryan Drewery got_usr1 = 0; 2566753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2567753e2922SBryan Drewery if (fpid == 0) { 256896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 256996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 257096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2571753e2922SBryan Drewery 2572753e2922SBryan Drewery trace_me(); 257396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2574753e2922SBryan Drewery 2575753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 257696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2577753e2922SBryan Drewery /* Wait to receive the SIGUSR1. */ 2578753e2922SBryan Drewery do { 2579753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2580753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2581753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 258296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2583753e2922SBryan Drewery exit(1); 2584753e2922SBryan Drewery } 2585753e2922SBryan Drewery 2586753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2587753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 258896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2589753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 259096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2591753e2922SBryan Drewery 2592753e2922SBryan Drewery len = sizeof(max_pending_per_proc); 2593753e2922SBryan Drewery ATF_REQUIRE(sysctlbyname("kern.sigqueue.max_pending_per_proc", 2594753e2922SBryan Drewery &max_pending_per_proc, &len, NULL, 0) == 0); 2595753e2922SBryan Drewery 2596753e2922SBryan Drewery /* Fill the signal queue. */ 2597753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) 259896a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 2599753e2922SBryan Drewery 2600753e2922SBryan Drewery /* Continue with signal. */ 260196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 2602753e2922SBryan Drewery 2603753e2922SBryan Drewery /* Collect and ignore all of the SIGUSR2. */ 2604753e2922SBryan Drewery for (i = 0; i < max_pending_per_proc; ++i) { 2605753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 260696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2607753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 260896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 260996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2610753e2922SBryan Drewery } 2611753e2922SBryan Drewery 2612753e2922SBryan Drewery /* Now our PT_CONTINUE'd SIGUSR1 should cause a stop after unmask. */ 2613753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 261496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2615753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 261696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 2617753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 261896a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 2619753e2922SBryan Drewery 2620753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 262196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2622753e2922SBryan Drewery 2623753e2922SBryan Drewery /* The last wait() should report exit after receiving SIGUSR1. */ 2624753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 262596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2626753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 262796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 2628753e2922SBryan Drewery 2629753e2922SBryan Drewery wpid = wait(&status); 263096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 263196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 2632753e2922SBryan Drewery } 2633753e2922SBryan Drewery 263482a4538fSEric Badger /* 263582a4538fSEric Badger * Verify that, after stopping due to a signal, that signal can be 263682a4538fSEric Badger * replaced with another signal. 263782a4538fSEric Badger */ 263882a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_change_sig); 263982a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_change_sig, tc) 264082a4538fSEric Badger { 264182a4538fSEric Badger struct ptrace_lwpinfo pl; 264282a4538fSEric Badger pid_t fpid, wpid; 264382a4538fSEric Badger int status; 264482a4538fSEric Badger 264582a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 264682a4538fSEric Badger if (fpid == 0) { 264782a4538fSEric Badger trace_me(); 264882a4538fSEric Badger sleep(20); 264982a4538fSEric Badger exit(1); 265082a4538fSEric Badger } 265182a4538fSEric Badger 265282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 265382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 265496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 265582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 265696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 265782a4538fSEric Badger 265896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 265982a4538fSEric Badger 266082a4538fSEric Badger /* Send a signal without ptrace. */ 266196a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGINT), 0); 266282a4538fSEric Badger 266382a4538fSEric Badger /* The second wait() should report a SIGINT was received. */ 266482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 266596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 266682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 266796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGINT); 266882a4538fSEric Badger 266982a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 267082a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 267196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGINT); 267282a4538fSEric Badger 267382a4538fSEric Badger /* Continue the child process with a different signal. */ 267496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTERM), 0); 267582a4538fSEric Badger 267682a4538fSEric Badger /* 267782a4538fSEric Badger * The last wait() should report having died due to the new 267882a4538fSEric Badger * signal, SIGTERM. 267982a4538fSEric Badger */ 268082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 268196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 268282a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 268396a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTERM); 268482a4538fSEric Badger 268582a4538fSEric Badger wpid = wait(&status); 268696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 268796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 268882a4538fSEric Badger } 268982a4538fSEric Badger 269082a4538fSEric Badger /* 269182a4538fSEric Badger * Verify that a signal can be passed through to the child even when there 269282a4538fSEric Badger * was no true signal originally. Such cases arise when a SIGTRAP is 269382a4538fSEric Badger * invented for e.g, system call stops. 269482a4538fSEric Badger */ 269582a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 269682a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigtrap_system_call_entry, tc) 269782a4538fSEric Badger { 269882a4538fSEric Badger struct ptrace_lwpinfo pl; 2699fc1e29dcSBryan Drewery struct rlimit rl; 270082a4538fSEric Badger pid_t fpid, wpid; 270182a4538fSEric Badger int status; 270282a4538fSEric Badger 270382a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 270482a4538fSEric Badger if (fpid == 0) { 270582a4538fSEric Badger trace_me(); 2706fc1e29dcSBryan Drewery /* SIGTRAP expected to cause exit on syscall entry. */ 2707fc1e29dcSBryan Drewery rl.rlim_cur = rl.rlim_max = 0; 270896a9e50eSAlex Richardson REQUIRE_EQ(setrlimit(RLIMIT_CORE, &rl), 0); 270982a4538fSEric Badger getpid(); 271082a4538fSEric Badger exit(1); 271182a4538fSEric Badger } 271282a4538fSEric Badger 271382a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 271482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 271596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 271682a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 271796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 271882a4538fSEric Badger 271982a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 272096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 272182a4538fSEric Badger 272282a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 272382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 272496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 272582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 272696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 272782a4538fSEric Badger 272882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 272982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 273082a4538fSEric Badger 273182a4538fSEric Badger /* Continue the child process with a SIGTRAP. */ 273296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGTRAP), 0); 273382a4538fSEric Badger 273482a4538fSEric Badger for (;;) { 273582a4538fSEric Badger /* 273682a4538fSEric Badger * The last wait() should report exit due to SIGTRAP. In the 273782a4538fSEric Badger * meantime, catch and proceed past any syscall stops. 273882a4538fSEric Badger */ 273982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 274096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 274182a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 274282a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 274382a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 274496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 274582a4538fSEric Badger } else { 274682a4538fSEric Badger ATF_REQUIRE(WIFSIGNALED(status)); 274796a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGTRAP); 274882a4538fSEric Badger break; 274982a4538fSEric Badger } 275082a4538fSEric Badger } 275182a4538fSEric Badger 275282a4538fSEric Badger wpid = wait(&status); 275396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 275496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 275582a4538fSEric Badger } 275682a4538fSEric Badger 275782a4538fSEric Badger /* 275882a4538fSEric Badger * A mixed bag PT_CONTINUE with signal test. 275982a4538fSEric Badger */ 276082a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_mix); 276182a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_mix, tc) 276282a4538fSEric Badger { 276382a4538fSEric Badger struct ptrace_lwpinfo pl; 276482a4538fSEric Badger pid_t fpid, wpid; 276582a4538fSEric Badger int status; 276682a4538fSEric Badger 276782a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_counting_handler) != SIG_ERR); 276882a4538fSEric Badger 276982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 277082a4538fSEric Badger if (fpid == 0) { 277182a4538fSEric Badger trace_me(); 277282a4538fSEric Badger getpid(); 277382a4538fSEric Badger exit(1); 277482a4538fSEric Badger } 277582a4538fSEric Badger 277682a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 277782a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 277896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 277982a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 278096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 278182a4538fSEric Badger 278282a4538fSEric Badger /* Continue the child ignoring the SIGSTOP and tracing system calls. */ 278396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 278482a4538fSEric Badger 278582a4538fSEric Badger /* The second wait() should report a system call entry for getpid(). */ 278682a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 278796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 278882a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 278996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 279082a4538fSEric Badger 279182a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 279282a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 279382a4538fSEric Badger 279482a4538fSEric Badger /* Continue with the first SIGUSR1. */ 279596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 279682a4538fSEric Badger 279782a4538fSEric Badger /* The next wait() should report a system call exit for getpid(). */ 279882a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 279996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 280082a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 280196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 280282a4538fSEric Badger 280382a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 280482a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 280582a4538fSEric Badger 280682a4538fSEric Badger /* Send an ABRT without ptrace. */ 280796a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGABRT), 0); 280882a4538fSEric Badger 280982a4538fSEric Badger /* Continue normally. */ 281096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 281182a4538fSEric Badger 281282a4538fSEric Badger /* The next wait() should report the SIGABRT. */ 281382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 281496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 281582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 281696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 281782a4538fSEric Badger 281882a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 281982a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 282096a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 282182a4538fSEric Badger 282282a4538fSEric Badger /* Continue, replacing the SIGABRT with another SIGUSR1. */ 282396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 282482a4538fSEric Badger 282582a4538fSEric Badger for (;;) { 282682a4538fSEric Badger /* 282782a4538fSEric Badger * The last wait() should report exit 2, i.e., a normal _exit 282882a4538fSEric Badger * from the signal handler. In the meantime, catch and proceed 282982a4538fSEric Badger * past any syscall stops. 283082a4538fSEric Badger */ 283182a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 283296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 283382a4538fSEric Badger if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { 283482a4538fSEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 283582a4538fSEric Badger ATF_REQUIRE(pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)); 283696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 283782a4538fSEric Badger } else { 283882a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 283996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 2); 284082a4538fSEric Badger break; 284182a4538fSEric Badger } 284282a4538fSEric Badger } 284382a4538fSEric Badger 284482a4538fSEric Badger wpid = wait(&status); 284596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 284696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 284782a4538fSEric Badger } 284882a4538fSEric Badger 284982a4538fSEric Badger /* 285082a4538fSEric Badger * Verify a signal delivered by ptrace is noticed by kevent(2). 285182a4538fSEric Badger */ 285282a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_kqueue); 285382a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_kqueue, tc) 285482a4538fSEric Badger { 285582a4538fSEric Badger pid_t fpid, wpid; 285682a4538fSEric Badger int status, kq, nevents; 285782a4538fSEric Badger struct kevent kev; 285882a4538fSEric Badger 285982a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, SIG_IGN) != SIG_ERR); 286082a4538fSEric Badger 286182a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 286282a4538fSEric Badger if (fpid == 0) { 286382a4538fSEric Badger CHILD_REQUIRE((kq = kqueue()) > 0); 286482a4538fSEric Badger EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); 286596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kevent(kq, &kev, 1, NULL, 0, NULL), 0); 286682a4538fSEric Badger 286782a4538fSEric Badger trace_me(); 286882a4538fSEric Badger 286982a4538fSEric Badger for (;;) { 287082a4538fSEric Badger nevents = kevent(kq, NULL, 0, &kev, 1, NULL); 287182a4538fSEric Badger if (nevents == -1 && errno == EINTR) 287282a4538fSEric Badger continue; 287382a4538fSEric Badger CHILD_REQUIRE(nevents > 0); 287496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(kev.filter, EVFILT_SIGNAL); 2875*1fcbddecSAlex Richardson CHILD_REQUIRE_EQ(kev.ident, (uintptr_t)SIGUSR1); 287682a4538fSEric Badger break; 287782a4538fSEric Badger } 287882a4538fSEric Badger 287982a4538fSEric Badger exit(1); 288082a4538fSEric Badger } 288182a4538fSEric Badger 288282a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 288382a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 288496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 288582a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 288696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 288782a4538fSEric Badger 288882a4538fSEric Badger /* Continue with the SIGUSR1. */ 288996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 289082a4538fSEric Badger 289182a4538fSEric Badger /* 289282a4538fSEric Badger * The last wait() should report normal exit with code 1. 289382a4538fSEric Badger */ 289482a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 289596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 289682a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 289796a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 289882a4538fSEric Badger 289982a4538fSEric Badger wpid = wait(&status); 290096a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 290196a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 290282a4538fSEric Badger } 290382a4538fSEric Badger 290482a4538fSEric Badger static void * 290582a4538fSEric Badger signal_thread(void *arg) 290682a4538fSEric Badger { 290782a4538fSEric Badger int err; 290882a4538fSEric Badger sigset_t sigmask; 290982a4538fSEric Badger 291082a4538fSEric Badger pthread_barrier_t *pbarrier = (pthread_barrier_t*)arg; 291182a4538fSEric Badger 291282a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 291382a4538fSEric Badger do { 291482a4538fSEric Badger err = sem_wait(&sigusr1_sem); 291582a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 291682a4538fSEric Badger } while (err != 0 && errno == EINTR); 291782a4538fSEric Badger 291882a4538fSEric Badger /* Free our companion thread from the barrier. */ 291982a4538fSEric Badger pthread_barrier_wait(pbarrier); 292082a4538fSEric Badger 292182a4538fSEric Badger /* 292282a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to the 292382a4538fSEric Badger * other thread. 292482a4538fSEric Badger */ 292596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 292696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 292796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 292882a4538fSEric Badger 292982a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 293082a4538fSEric Badger pthread_barrier_wait(pbarrier); 293182a4538fSEric Badger 293282a4538fSEric Badger /* Wait until our companion has received its SIGUSR1. */ 293382a4538fSEric Badger pthread_barrier_wait(pbarrier); 293482a4538fSEric Badger 293582a4538fSEric Badger return (NULL); 293682a4538fSEric Badger } 293782a4538fSEric Badger 293882a4538fSEric Badger /* 2939753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 2940753e2922SBryan Drewery * signal from kill() once unmasked. 2941753e2922SBryan Drewery */ 2942753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__killed_with_sigmask); 2943753e2922SBryan Drewery ATF_TC_BODY(ptrace__killed_with_sigmask, tc) 2944753e2922SBryan Drewery { 2945753e2922SBryan Drewery struct ptrace_lwpinfo pl; 2946753e2922SBryan Drewery pid_t fpid, wpid; 2947753e2922SBryan Drewery int status, err; 2948753e2922SBryan Drewery sigset_t sigmask; 2949753e2922SBryan Drewery 295096a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 2951753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 2952753e2922SBryan Drewery got_usr1 = 0; 2953753e2922SBryan Drewery 2954753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 2955753e2922SBryan Drewery if (fpid == 0) { 295696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 295796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 295896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 2959753e2922SBryan Drewery 2960753e2922SBryan Drewery trace_me(); 296196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 2962753e2922SBryan Drewery 2963753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 296496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 2965753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 2966753e2922SBryan Drewery do { 2967753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 2968753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 2969753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 297096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 2971753e2922SBryan Drewery exit(1); 2972753e2922SBryan Drewery } 2973753e2922SBryan Drewery 2974753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 2975753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 297696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2977753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 297896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 2979753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 298096a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 2981753e2922SBryan Drewery 2982753e2922SBryan Drewery /* Send blocked SIGUSR1 which should cause a stop. */ 298396a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR1), 0); 2984753e2922SBryan Drewery 2985753e2922SBryan Drewery /* Continue the child ignoring the SIGSTOP. */ 298696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 2987753e2922SBryan Drewery 2988753e2922SBryan Drewery /* The next wait() should report the kill(SIGUSR1) was received. */ 2989753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 299096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 2991753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 299296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 2993753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 299496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 2995753e2922SBryan Drewery 2996753e2922SBryan Drewery /* Continue the child, allowing in the SIGUSR1. */ 299796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 2998753e2922SBryan Drewery 2999753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3000753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 300196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3002753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 300396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3004753e2922SBryan Drewery 3005753e2922SBryan Drewery wpid = wait(&status); 300696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 300796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3008753e2922SBryan Drewery } 3009753e2922SBryan Drewery 3010753e2922SBryan Drewery /* 3011753e2922SBryan Drewery * Verify that a traced process with blocked signal received the 3012753e2922SBryan Drewery * signal from PT_CONTINUE once unmasked. 3013753e2922SBryan Drewery */ 3014753e2922SBryan Drewery ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_sigmask); 3015753e2922SBryan Drewery ATF_TC_BODY(ptrace__PT_CONTINUE_with_sigmask, tc) 3016753e2922SBryan Drewery { 3017753e2922SBryan Drewery struct ptrace_lwpinfo pl; 3018753e2922SBryan Drewery pid_t fpid, wpid; 3019753e2922SBryan Drewery int status, err; 3020753e2922SBryan Drewery sigset_t sigmask; 3021753e2922SBryan Drewery 302296a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 3023753e2922SBryan Drewery ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 3024753e2922SBryan Drewery got_usr1 = 0; 3025753e2922SBryan Drewery 3026753e2922SBryan Drewery ATF_REQUIRE((fpid = fork()) != -1); 3027753e2922SBryan Drewery if (fpid == 0) { 302896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 302996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 303096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_BLOCK, &sigmask, NULL), 0); 3031753e2922SBryan Drewery 3032753e2922SBryan Drewery trace_me(); 303396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 0); 3034753e2922SBryan Drewery 3035753e2922SBryan Drewery /* Allow the pending SIGUSR1 in now. */ 303696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &sigmask, NULL), 0); 3037753e2922SBryan Drewery /* Wait to receive a SIGUSR1. */ 3038753e2922SBryan Drewery do { 3039753e2922SBryan Drewery err = sem_wait(&sigusr1_sem); 3040753e2922SBryan Drewery CHILD_REQUIRE(err == 0 || errno == EINTR); 3041753e2922SBryan Drewery } while (err != 0 && errno == EINTR); 3042753e2922SBryan Drewery 304396a9e50eSAlex Richardson CHILD_REQUIRE_EQ(got_usr1, 1); 3044753e2922SBryan Drewery exit(1); 3045753e2922SBryan Drewery } 3046753e2922SBryan Drewery 3047753e2922SBryan Drewery /* The first wait() should report the stop from SIGSTOP. */ 3048753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 304996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3050753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 305196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3052753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 305396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGSTOP); 3054753e2922SBryan Drewery 3055753e2922SBryan Drewery /* Continue the child replacing SIGSTOP with SIGUSR1. */ 305696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 3057753e2922SBryan Drewery 3058753e2922SBryan Drewery /* The next wait() should report the SIGUSR1 was received. */ 3059753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 306096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3061753e2922SBryan Drewery ATF_REQUIRE(WIFSTOPPED(status)); 306296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR1); 3063753e2922SBryan Drewery ATF_REQUIRE(ptrace(PT_LWPINFO, fpid, (caddr_t)&pl, sizeof(pl)) != -1); 306496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGUSR1); 3065753e2922SBryan Drewery 3066753e2922SBryan Drewery /* Continue the child, ignoring the SIGUSR1. */ 306796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3068753e2922SBryan Drewery 3069753e2922SBryan Drewery /* The last wait() should report normal exit with code 1. */ 3070753e2922SBryan Drewery wpid = waitpid(fpid, &status, 0); 307196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3072753e2922SBryan Drewery ATF_REQUIRE(WIFEXITED(status)); 307396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3074753e2922SBryan Drewery 3075753e2922SBryan Drewery wpid = wait(&status); 307696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 307796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3078753e2922SBryan Drewery } 3079753e2922SBryan Drewery 3080753e2922SBryan Drewery /* 308182a4538fSEric Badger * Verify that if ptrace stops due to a signal but continues with 308282a4538fSEric Badger * a different signal that the new signal is routed to a thread 308399144520SEitan Adler * that can accept it, and that the thread is awakened by the signal 308482a4538fSEric Badger * in a timely manner. 308582a4538fSEric Badger */ 308682a4538fSEric Badger ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_with_signal_thread_sigmask); 308782a4538fSEric Badger ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_thread_sigmask, tc) 308882a4538fSEric Badger { 308982a4538fSEric Badger pid_t fpid, wpid; 309082a4538fSEric Badger int status, err; 309182a4538fSEric Badger pthread_t t; 309282a4538fSEric Badger sigset_t sigmask; 309382a4538fSEric Badger pthread_barrier_t barrier; 309482a4538fSEric Badger 309596a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, NULL, 2), 0); 309696a9e50eSAlex Richardson REQUIRE_EQ(sem_init(&sigusr1_sem, 0, 0), 0); 309782a4538fSEric Badger ATF_REQUIRE(signal(SIGUSR1, sigusr1_sempost_handler) != SIG_ERR); 309882a4538fSEric Badger 309982a4538fSEric Badger ATF_REQUIRE((fpid = fork()) != -1); 310082a4538fSEric Badger if (fpid == 0) { 310196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_create(&t, NULL, signal_thread, 310296a9e50eSAlex Richardson (void *)&barrier), 0); 310382a4538fSEric Badger 310482a4538fSEric Badger /* The other thread should receive the first SIGUSR1. */ 310596a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigemptyset(&sigmask), 0); 310696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sigaddset(&sigmask, SIGUSR1), 0); 310796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_BLOCK, &sigmask, NULL), 0); 310882a4538fSEric Badger 310982a4538fSEric Badger trace_me(); 311082a4538fSEric Badger 311182a4538fSEric Badger /* Wait until other thread has received its SIGUSR1. */ 311282a4538fSEric Badger pthread_barrier_wait(&barrier); 311382a4538fSEric Badger 311482a4538fSEric Badger /* 311582a4538fSEric Badger * Swap ignore duties; the next SIGUSR1 should go to this 311682a4538fSEric Badger * thread. 311782a4538fSEric Badger */ 311896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL), 311996a9e50eSAlex Richardson 0); 312082a4538fSEric Badger 312182a4538fSEric Badger /* Sync up threads after swapping signal masks. */ 312282a4538fSEric Badger pthread_barrier_wait(&barrier); 312382a4538fSEric Badger 312482a4538fSEric Badger /* 312582a4538fSEric Badger * Sync up with test code; we're ready for the next SIGUSR1 312682a4538fSEric Badger * now. 312782a4538fSEric Badger */ 312882a4538fSEric Badger raise(SIGSTOP); 312982a4538fSEric Badger 313082a4538fSEric Badger /* Wait for this thread to receive a SIGUSR1. */ 313182a4538fSEric Badger do { 313282a4538fSEric Badger err = sem_wait(&sigusr1_sem); 313382a4538fSEric Badger CHILD_REQUIRE(err == 0 || errno == EINTR); 313482a4538fSEric Badger } while (err != 0 && errno == EINTR); 313582a4538fSEric Badger 313682a4538fSEric Badger /* Free the other thread from the barrier. */ 313782a4538fSEric Badger pthread_barrier_wait(&barrier); 313882a4538fSEric Badger 313996a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(t, NULL), 0); 314082a4538fSEric Badger 314182a4538fSEric Badger exit(1); 314282a4538fSEric Badger } 314382a4538fSEric Badger 314482a4538fSEric Badger /* The first wait() should report the stop from SIGSTOP. */ 314582a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 314696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 314782a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 314896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 314982a4538fSEric Badger 315082a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 315196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 315282a4538fSEric Badger 315382a4538fSEric Badger /* 315482a4538fSEric Badger * Send a signal without ptrace that either thread will accept (USR2, 315582a4538fSEric Badger * in this case). 315682a4538fSEric Badger */ 315796a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 315882a4538fSEric Badger 315982a4538fSEric Badger /* The second wait() should report a SIGUSR2 was received. */ 316082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 316196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 316282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 316396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 316482a4538fSEric Badger 316582a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 316696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 316782a4538fSEric Badger 316882a4538fSEric Badger /* The next wait() should report the stop from SIGSTOP. */ 316982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 317096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 317182a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 317296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 317382a4538fSEric Badger 317482a4538fSEric Badger /* Continue the child ignoring the SIGSTOP. */ 317596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 317682a4538fSEric Badger 317796a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGUSR2), 0); 317882a4538fSEric Badger 317982a4538fSEric Badger /* The next wait() should report a SIGUSR2 was received. */ 318082a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 318196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 318282a4538fSEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 318396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGUSR2); 318482a4538fSEric Badger 318582a4538fSEric Badger /* Continue the child, changing the signal to USR1. */ 318696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, SIGUSR1), 0); 318782a4538fSEric Badger 318882a4538fSEric Badger /* The last wait() should report normal exit with code 1. */ 318982a4538fSEric Badger wpid = waitpid(fpid, &status, 0); 319096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 319182a4538fSEric Badger ATF_REQUIRE(WIFEXITED(status)); 319296a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 319382a4538fSEric Badger 319482a4538fSEric Badger wpid = wait(&status); 319596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 319696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 319782a4538fSEric Badger } 319882a4538fSEric Badger 3199b38bd91fSEric Badger static void * 3200b38bd91fSEric Badger raise_sigstop_thread(void *arg __unused) 3201b38bd91fSEric Badger { 3202b38bd91fSEric Badger 3203b38bd91fSEric Badger raise(SIGSTOP); 3204b38bd91fSEric Badger return NULL; 3205b38bd91fSEric Badger } 3206b38bd91fSEric Badger 3207b38bd91fSEric Badger static void * 3208b38bd91fSEric Badger sleep_thread(void *arg __unused) 3209b38bd91fSEric Badger { 3210b38bd91fSEric Badger 3211b38bd91fSEric Badger sleep(60); 3212b38bd91fSEric Badger return NULL; 3213b38bd91fSEric Badger } 3214b38bd91fSEric Badger 3215b38bd91fSEric Badger static void 3216b38bd91fSEric Badger terminate_with_pending_sigstop(bool sigstop_from_main_thread) 3217b38bd91fSEric Badger { 3218b38bd91fSEric Badger pid_t fpid, wpid; 3219b38bd91fSEric Badger int status, i; 3220b38bd91fSEric Badger cpuset_t setmask; 3221b38bd91fSEric Badger cpusetid_t setid; 3222b38bd91fSEric Badger pthread_t t; 3223b38bd91fSEric Badger 3224b38bd91fSEric Badger /* 3225b38bd91fSEric Badger * Become the reaper for this process tree. We need to be able to check 3226b38bd91fSEric Badger * that both child and grandchild have died. 3227b38bd91fSEric Badger */ 322896a9e50eSAlex Richardson REQUIRE_EQ(procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL), 0); 3229b38bd91fSEric Badger 3230b38bd91fSEric Badger fpid = fork(); 3231b38bd91fSEric Badger ATF_REQUIRE(fpid >= 0); 3232b38bd91fSEric Badger if (fpid == 0) { 3233b38bd91fSEric Badger fpid = fork(); 3234b38bd91fSEric Badger CHILD_REQUIRE(fpid >= 0); 3235b38bd91fSEric Badger if (fpid == 0) { 3236b38bd91fSEric Badger trace_me(); 3237b38bd91fSEric Badger 3238b38bd91fSEric Badger /* Pin to CPU 0 to serialize thread execution. */ 3239b38bd91fSEric Badger CPU_ZERO(&setmask); 3240b38bd91fSEric Badger CPU_SET(0, &setmask); 324196a9e50eSAlex Richardson CHILD_REQUIRE_EQ(cpuset(&setid), 0); 3242b38bd91fSEric Badger CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_CPUSET, 3243b38bd91fSEric Badger CPU_WHICH_CPUSET, setid, 3244b38bd91fSEric Badger sizeof(setmask), &setmask) == 0); 3245b38bd91fSEric Badger 3246b38bd91fSEric Badger if (sigstop_from_main_thread) { 3247b38bd91fSEric Badger /* 3248b38bd91fSEric Badger * We expect the SIGKILL sent when our parent 3249b38bd91fSEric Badger * dies to be delivered to the new thread. 3250b38bd91fSEric Badger * Raise the SIGSTOP in this thread so the 3251b38bd91fSEric Badger * threads compete. 3252b38bd91fSEric Badger */ 3253b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3254b38bd91fSEric Badger sleep_thread, NULL) == 0); 3255b38bd91fSEric Badger raise(SIGSTOP); 3256b38bd91fSEric Badger } else { 3257b38bd91fSEric Badger /* 3258b38bd91fSEric Badger * We expect the SIGKILL to be delivered to 3259b38bd91fSEric Badger * this thread. After creating the new thread, 3260b38bd91fSEric Badger * just get off the CPU so the other thread can 3261b38bd91fSEric Badger * raise the SIGSTOP. 3262b38bd91fSEric Badger */ 3263b38bd91fSEric Badger CHILD_REQUIRE(pthread_create(&t, NULL, 3264b38bd91fSEric Badger raise_sigstop_thread, NULL) == 0); 3265b38bd91fSEric Badger sleep(60); 3266b38bd91fSEric Badger } 3267b38bd91fSEric Badger 3268b38bd91fSEric Badger exit(0); 3269b38bd91fSEric Badger } 3270b38bd91fSEric Badger /* First stop is trace_me() immediately after fork. */ 3271b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 327296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3273b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 327496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3275b38bd91fSEric Badger 327696a9e50eSAlex Richardson CHILD_REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3277b38bd91fSEric Badger 3278b38bd91fSEric Badger /* Second stop is from the raise(SIGSTOP). */ 3279b38bd91fSEric Badger wpid = waitpid(fpid, &status, 0); 328096a9e50eSAlex Richardson CHILD_REQUIRE_EQ(wpid, fpid); 3281b38bd91fSEric Badger CHILD_REQUIRE(WIFSTOPPED(status)); 328296a9e50eSAlex Richardson CHILD_REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3283b38bd91fSEric Badger 3284b38bd91fSEric Badger /* 3285b38bd91fSEric Badger * Terminate tracing process without detaching. Our child 3286b38bd91fSEric Badger * should be killed. 3287b38bd91fSEric Badger */ 3288b38bd91fSEric Badger exit(0); 3289b38bd91fSEric Badger } 3290b38bd91fSEric Badger 3291b38bd91fSEric Badger /* 3292b38bd91fSEric Badger * We should get a normal exit from our immediate child and a SIGKILL 3293b38bd91fSEric Badger * exit from our grandchild. The latter case is the interesting one. 3294b38bd91fSEric Badger * Our grandchild should not have stopped due to the SIGSTOP that was 3295b38bd91fSEric Badger * left dangling when its parent died. 3296b38bd91fSEric Badger */ 3297b38bd91fSEric Badger for (i = 0; i < 2; ++i) { 3298b38bd91fSEric Badger wpid = wait(&status); 329996a9e50eSAlex Richardson if (wpid == fpid) { 330096a9e50eSAlex Richardson ATF_REQUIRE(WIFEXITED(status)); 330196a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 330296a9e50eSAlex Richardson } else { 330396a9e50eSAlex Richardson ATF_REQUIRE(WIFSIGNALED(status)); 330496a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 330596a9e50eSAlex Richardson } 3306b38bd91fSEric Badger } 3307b38bd91fSEric Badger } 3308b38bd91fSEric Badger 3309b38bd91fSEric Badger /* 3310b38bd91fSEric Badger * These two tests ensure that if the tracing process exits without detaching 3311b38bd91fSEric Badger * just after the child received a SIGSTOP, the child is cleanly killed and 3312b38bd91fSEric Badger * doesn't go to sleep due to the SIGSTOP. The parent's death will send a 3313b38bd91fSEric Badger * SIGKILL to the child. If the SIGKILL and the SIGSTOP are handled by 3314b38bd91fSEric Badger * different threads, the SIGKILL must win. There are two variants of this 3315b38bd91fSEric Badger * test, designed to catch the case where the SIGKILL is delivered to the 3316b38bd91fSEric Badger * younger thread (the first test) and the case where the SIGKILL is delivered 3317b38bd91fSEric Badger * to the older thread (the second test). This behavior has changed in the 3318b38bd91fSEric Badger * past, so make no assumption. 3319b38bd91fSEric Badger */ 33203cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop1); 33213cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop1, tc) 33223cf56bb4SEnji Cooper { 33233cf56bb4SEnji Cooper 33243cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 33253cf56bb4SEnji Cooper } 3326b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop1, tc) 3327b38bd91fSEric Badger { 3328b38bd91fSEric Badger 3329b38bd91fSEric Badger terminate_with_pending_sigstop(true); 3330b38bd91fSEric Badger } 33313cf56bb4SEnji Cooper 33323cf56bb4SEnji Cooper ATF_TC(ptrace__parent_terminate_with_pending_sigstop2); 33333cf56bb4SEnji Cooper ATF_TC_HEAD(ptrace__parent_terminate_with_pending_sigstop2, tc) 33343cf56bb4SEnji Cooper { 33353cf56bb4SEnji Cooper 33363cf56bb4SEnji Cooper atf_tc_set_md_var(tc, "require.user", "root"); 33373cf56bb4SEnji Cooper } 3338b38bd91fSEric Badger ATF_TC_BODY(ptrace__parent_terminate_with_pending_sigstop2, tc) 3339b38bd91fSEric Badger { 3340b38bd91fSEric Badger 3341b38bd91fSEric Badger terminate_with_pending_sigstop(false); 3342b38bd91fSEric Badger } 3343b38bd91fSEric Badger 3344b4d33259SEric Badger /* 3345b4d33259SEric Badger * Verify that after ptrace() discards a SIGKILL signal, the event mask 3346b4d33259SEric Badger * is not modified. 3347b4d33259SEric Badger */ 3348b4d33259SEric Badger ATF_TC_WITHOUT_HEAD(ptrace__event_mask_sigkill_discard); 3349b4d33259SEric Badger ATF_TC_BODY(ptrace__event_mask_sigkill_discard, tc) 3350b4d33259SEric Badger { 3351b4d33259SEric Badger struct ptrace_lwpinfo pl; 3352b4d33259SEric Badger pid_t fpid, wpid; 3353b4d33259SEric Badger int status, event_mask, new_event_mask; 3354b4d33259SEric Badger 3355b4d33259SEric Badger ATF_REQUIRE((fpid = fork()) != -1); 3356b4d33259SEric Badger if (fpid == 0) { 3357b4d33259SEric Badger trace_me(); 3358b4d33259SEric Badger raise(SIGSTOP); 3359b4d33259SEric Badger exit(0); 3360b4d33259SEric Badger } 3361b4d33259SEric Badger 3362b4d33259SEric Badger /* The first wait() should report the stop from trace_me(). */ 3363b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 336496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3365b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 336696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3367b4d33259SEric Badger 3368b4d33259SEric Badger /* Set several unobtrusive event bits. */ 3369b4d33259SEric Badger event_mask = PTRACE_EXEC | PTRACE_FORK | PTRACE_LWP; 3370b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, wpid, (caddr_t)&event_mask, 3371b4d33259SEric Badger sizeof(event_mask)) == 0); 3372b4d33259SEric Badger 3373b4d33259SEric Badger /* Send a SIGKILL without using ptrace. */ 337496a9e50eSAlex Richardson REQUIRE_EQ(kill(fpid, SIGKILL), 0); 3375b4d33259SEric Badger 3376b4d33259SEric Badger /* Continue the child ignoring the SIGSTOP. */ 337796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3378b4d33259SEric Badger 3379b4d33259SEric Badger /* The next stop should be due to the SIGKILL. */ 3380b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 338196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3382b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 338396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGKILL); 3384b4d33259SEric Badger 3385b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3386b4d33259SEric Badger ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 338796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGKILL); 3388b4d33259SEric Badger 3389b4d33259SEric Badger /* Continue the child ignoring the SIGKILL. */ 339096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3391b4d33259SEric Badger 3392b4d33259SEric Badger /* The next wait() should report the stop from SIGSTOP. */ 3393b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 339496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3395b4d33259SEric Badger ATF_REQUIRE(WIFSTOPPED(status)); 339696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3397b4d33259SEric Badger 3398b4d33259SEric Badger /* Check the current event mask. It should not have changed. */ 3399b4d33259SEric Badger new_event_mask = 0; 3400b4d33259SEric Badger ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, wpid, (caddr_t)&new_event_mask, 3401b4d33259SEric Badger sizeof(new_event_mask)) == 0); 340296a9e50eSAlex Richardson REQUIRE_EQ(event_mask, new_event_mask); 3403b4d33259SEric Badger 3404b4d33259SEric Badger /* Continue the child to let it exit. */ 340596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3406b4d33259SEric Badger 3407b4d33259SEric Badger /* The last event should be for the child process's exit. */ 3408b4d33259SEric Badger wpid = waitpid(fpid, &status, 0); 3409b4d33259SEric Badger ATF_REQUIRE(WIFEXITED(status)); 341096a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 3411b4d33259SEric Badger 3412b4d33259SEric Badger wpid = wait(&status); 341396a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 341496a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3415b4d33259SEric Badger } 3416b4d33259SEric Badger 3417d74da94cSMark Johnston static void * 3418d74da94cSMark Johnston flock_thread(void *arg) 3419d74da94cSMark Johnston { 3420d74da94cSMark Johnston int fd; 3421d74da94cSMark Johnston 3422d74da94cSMark Johnston fd = *(int *)arg; 3423d74da94cSMark Johnston (void)flock(fd, LOCK_EX); 3424d74da94cSMark Johnston (void)flock(fd, LOCK_UN); 3425d74da94cSMark Johnston return (NULL); 3426d74da94cSMark Johnston } 3427d74da94cSMark Johnston 3428d74da94cSMark Johnston /* 3429d74da94cSMark Johnston * Verify that PT_ATTACH will suspend threads sleeping in an SBDRY section. 3430d74da94cSMark Johnston * We rely on the fact that the lockf implementation sets SBDRY before blocking 3431d74da94cSMark Johnston * on a lock. This is a regression test for r318191. 3432d74da94cSMark Johnston */ 3433d74da94cSMark Johnston ATF_TC_WITHOUT_HEAD(ptrace__PT_ATTACH_with_SBDRY_thread); 3434d74da94cSMark Johnston ATF_TC_BODY(ptrace__PT_ATTACH_with_SBDRY_thread, tc) 3435d74da94cSMark Johnston { 3436d74da94cSMark Johnston pthread_barrier_t barrier; 3437d74da94cSMark Johnston pthread_barrierattr_t battr; 3438d74da94cSMark Johnston char tmpfile[64]; 3439d74da94cSMark Johnston pid_t child, wpid; 3440d74da94cSMark Johnston int error, fd, i, status; 3441d74da94cSMark Johnston 344296a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrierattr_init(&battr), 0); 3443d74da94cSMark Johnston ATF_REQUIRE(pthread_barrierattr_setpshared(&battr, 3444d74da94cSMark Johnston PTHREAD_PROCESS_SHARED) == 0); 344596a9e50eSAlex Richardson REQUIRE_EQ(pthread_barrier_init(&barrier, &battr, 2), 0); 3446d74da94cSMark Johnston 3447d74da94cSMark Johnston (void)snprintf(tmpfile, sizeof(tmpfile), "./ptrace.XXXXXX"); 3448d74da94cSMark Johnston fd = mkstemp(tmpfile); 3449d74da94cSMark Johnston ATF_REQUIRE(fd >= 0); 3450d74da94cSMark Johnston 3451d74da94cSMark Johnston ATF_REQUIRE((child = fork()) != -1); 3452d74da94cSMark Johnston if (child == 0) { 3453d74da94cSMark Johnston pthread_t t[2]; 345496437391SBryan Drewery int cfd; 3455d74da94cSMark Johnston 3456d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3457d74da94cSMark Johnston if (error != 0 && error != PTHREAD_BARRIER_SERIAL_THREAD) 3458d74da94cSMark Johnston _exit(1); 3459d74da94cSMark Johnston 3460d74da94cSMark Johnston cfd = open(tmpfile, O_RDONLY); 3461d74da94cSMark Johnston if (cfd < 0) 3462d74da94cSMark Johnston _exit(1); 3463d74da94cSMark Johnston 3464d74da94cSMark Johnston /* 3465d74da94cSMark Johnston * We want at least two threads blocked on the file lock since 3466d74da94cSMark Johnston * the SIGSTOP from PT_ATTACH may kick one of them out of 3467d74da94cSMark Johnston * sleep. 3468d74da94cSMark Johnston */ 3469d74da94cSMark Johnston if (pthread_create(&t[0], NULL, flock_thread, &cfd) != 0) 3470d74da94cSMark Johnston _exit(1); 3471d74da94cSMark Johnston if (pthread_create(&t[1], NULL, flock_thread, &cfd) != 0) 3472d74da94cSMark Johnston _exit(1); 3473d74da94cSMark Johnston if (pthread_join(t[0], NULL) != 0) 3474d74da94cSMark Johnston _exit(1); 3475d74da94cSMark Johnston if (pthread_join(t[1], NULL) != 0) 3476d74da94cSMark Johnston _exit(1); 3477d74da94cSMark Johnston _exit(0); 3478d74da94cSMark Johnston } 3479d74da94cSMark Johnston 348096a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_EX), 0); 3481d74da94cSMark Johnston 3482d74da94cSMark Johnston error = pthread_barrier_wait(&barrier); 3483d74da94cSMark Johnston ATF_REQUIRE(error == 0 || error == PTHREAD_BARRIER_SERIAL_THREAD); 3484d74da94cSMark Johnston 3485d74da94cSMark Johnston /* 3486d74da94cSMark Johnston * Give the child some time to block. Is there a better way to do this? 3487d74da94cSMark Johnston */ 3488d74da94cSMark Johnston sleep(1); 3489d74da94cSMark Johnston 3490d74da94cSMark Johnston /* 3491d74da94cSMark Johnston * Attach and give the child 3 seconds to stop. 3492d74da94cSMark Johnston */ 349396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, child, NULL, 0), 0); 3494d74da94cSMark Johnston for (i = 0; i < 3; i++) { 3495d74da94cSMark Johnston wpid = waitpid(child, &status, WNOHANG); 3496d74da94cSMark Johnston if (wpid == child && WIFSTOPPED(status) && 3497d74da94cSMark Johnston WSTOPSIG(status) == SIGSTOP) 3498d74da94cSMark Johnston break; 3499d74da94cSMark Johnston sleep(1); 3500d74da94cSMark Johnston } 3501d74da94cSMark Johnston ATF_REQUIRE_MSG(i < 3, "failed to stop child process after PT_ATTACH"); 3502d74da94cSMark Johnston 350396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, child, NULL, 0), 0); 3504d74da94cSMark Johnston 350596a9e50eSAlex Richardson REQUIRE_EQ(flock(fd, LOCK_UN), 0); 350696a9e50eSAlex Richardson REQUIRE_EQ(unlink(tmpfile), 0); 350796a9e50eSAlex Richardson REQUIRE_EQ(close(fd), 0); 3508d74da94cSMark Johnston } 3509d74da94cSMark Johnston 351054cfb29eSJohn Baldwin static void 351154cfb29eSJohn Baldwin sigusr1_step_handler(int sig) 351254cfb29eSJohn Baldwin { 351354cfb29eSJohn Baldwin 351496a9e50eSAlex Richardson CHILD_REQUIRE_EQ(sig, SIGUSR1); 351554cfb29eSJohn Baldwin raise(SIGABRT); 351654cfb29eSJohn Baldwin } 351754cfb29eSJohn Baldwin 351854cfb29eSJohn Baldwin /* 351954cfb29eSJohn Baldwin * Verify that PT_STEP with a signal invokes the signal before 352054cfb29eSJohn Baldwin * stepping the next instruction (and that the next instruction is 352154cfb29eSJohn Baldwin * stepped correctly). 352254cfb29eSJohn Baldwin */ 352354cfb29eSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_STEP_with_signal); 352454cfb29eSJohn Baldwin ATF_TC_BODY(ptrace__PT_STEP_with_signal, tc) 352554cfb29eSJohn Baldwin { 352654cfb29eSJohn Baldwin struct ptrace_lwpinfo pl; 352754cfb29eSJohn Baldwin pid_t fpid, wpid; 352854cfb29eSJohn Baldwin int status; 352954cfb29eSJohn Baldwin 353054cfb29eSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 353154cfb29eSJohn Baldwin if (fpid == 0) { 353254cfb29eSJohn Baldwin trace_me(); 353354cfb29eSJohn Baldwin signal(SIGUSR1, sigusr1_step_handler); 353454cfb29eSJohn Baldwin raise(SIGABRT); 353554cfb29eSJohn Baldwin exit(1); 353654cfb29eSJohn Baldwin } 353754cfb29eSJohn Baldwin 353854cfb29eSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 353954cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 354096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 354154cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 354296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 354354cfb29eSJohn Baldwin 354496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 354554cfb29eSJohn Baldwin 354654cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 354754cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 354896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 354954cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 355096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 355154cfb29eSJohn Baldwin 355254cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 355354cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 355496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 355554cfb29eSJohn Baldwin 355654cfb29eSJohn Baldwin /* Step the child process inserting SIGUSR1. */ 355796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, SIGUSR1), 0); 355854cfb29eSJohn Baldwin 355954cfb29eSJohn Baldwin /* The next stop should report the SIGABRT in the signal handler. */ 356054cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 356196a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 356254cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 356396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 356454cfb29eSJohn Baldwin 356554cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 356654cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 356796a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 356854cfb29eSJohn Baldwin 356954cfb29eSJohn Baldwin /* Continue the child process discarding the signal. */ 357096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 357154cfb29eSJohn Baldwin 357254cfb29eSJohn Baldwin /* The next stop should report a trace trap from PT_STEP. */ 357354cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 357496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 357554cfb29eSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 357696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 357754cfb29eSJohn Baldwin 357854cfb29eSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 357954cfb29eSJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 358096a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 358196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 358254cfb29eSJohn Baldwin 358354cfb29eSJohn Baldwin /* Continue the child to let it exit. */ 358496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 358554cfb29eSJohn Baldwin 358654cfb29eSJohn Baldwin /* The last event should be for the child process's exit. */ 358754cfb29eSJohn Baldwin wpid = waitpid(fpid, &status, 0); 358854cfb29eSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 358996a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 359054cfb29eSJohn Baldwin 359154cfb29eSJohn Baldwin wpid = wait(&status); 359296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 359396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 359454cfb29eSJohn Baldwin } 359554cfb29eSJohn Baldwin 3596643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 3597643ce7deSJohn Baldwin /* 3598643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_BRKPT code is reported 3599643ce7deSJohn Baldwin * for a breakpoint trap. 3600643ce7deSJohn Baldwin */ 3601643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__breakpoint_siginfo); 3602643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__breakpoint_siginfo, tc) 3603643ce7deSJohn Baldwin { 3604643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3605643ce7deSJohn Baldwin pid_t fpid, wpid; 3606643ce7deSJohn Baldwin int status; 3607643ce7deSJohn Baldwin 3608643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3609643ce7deSJohn Baldwin if (fpid == 0) { 3610643ce7deSJohn Baldwin trace_me(); 3611643ce7deSJohn Baldwin breakpoint(); 3612643ce7deSJohn Baldwin exit(1); 3613643ce7deSJohn Baldwin } 3614643ce7deSJohn Baldwin 3615643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3616643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 361796a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3618643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 361996a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3620643ce7deSJohn Baldwin 3621643ce7deSJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 362296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3623643ce7deSJohn Baldwin 3624643ce7deSJohn Baldwin /* The second wait() should report hitting the breakpoint. */ 3625643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 362696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3627643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 362896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3629643ce7deSJohn Baldwin 3630643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3631643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 363296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 363396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3634643ce7deSJohn Baldwin 3635643ce7deSJohn Baldwin /* Kill the child process. */ 363696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_KILL, fpid, 0, 0), 0); 3637643ce7deSJohn Baldwin 3638643ce7deSJohn Baldwin /* The last wait() should report the SIGKILL. */ 3639643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 364096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3641643ce7deSJohn Baldwin ATF_REQUIRE(WIFSIGNALED(status)); 364296a9e50eSAlex Richardson REQUIRE_EQ(WTERMSIG(status), SIGKILL); 3643643ce7deSJohn Baldwin 3644643ce7deSJohn Baldwin wpid = wait(&status); 364596a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 364696a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3647643ce7deSJohn Baldwin } 3648643ce7deSJohn Baldwin #endif /* HAVE_BREAKPOINT */ 3649643ce7deSJohn Baldwin 3650643ce7deSJohn Baldwin /* 3651643ce7deSJohn Baldwin * Verify that a SIGTRAP event with the TRAP_TRACE code is reported 3652643ce7deSJohn Baldwin * for a single-step trap from PT_STEP. 3653643ce7deSJohn Baldwin */ 3654643ce7deSJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__step_siginfo); 3655643ce7deSJohn Baldwin ATF_TC_BODY(ptrace__step_siginfo, tc) 3656643ce7deSJohn Baldwin { 3657643ce7deSJohn Baldwin struct ptrace_lwpinfo pl; 3658643ce7deSJohn Baldwin pid_t fpid, wpid; 3659643ce7deSJohn Baldwin int status; 3660643ce7deSJohn Baldwin 3661643ce7deSJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3662643ce7deSJohn Baldwin if (fpid == 0) { 3663643ce7deSJohn Baldwin trace_me(); 3664643ce7deSJohn Baldwin exit(1); 3665643ce7deSJohn Baldwin } 3666643ce7deSJohn Baldwin 3667643ce7deSJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3668643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 366996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3670643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 367196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3672643ce7deSJohn Baldwin 3673643ce7deSJohn Baldwin /* Step the child ignoring the SIGSTOP. */ 367496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_STEP, fpid, (caddr_t)1, 0), 0); 3675643ce7deSJohn Baldwin 3676643ce7deSJohn Baldwin /* The second wait() should report a single-step trap. */ 3677643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 367896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3679643ce7deSJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 368096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3681643ce7deSJohn Baldwin 3682643ce7deSJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3683643ce7deSJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 368496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 368596a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_TRACE); 3686643ce7deSJohn Baldwin 3687643ce7deSJohn Baldwin /* Continue the child process. */ 368896a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3689643ce7deSJohn Baldwin 3690643ce7deSJohn Baldwin /* The last event should be for the child process's exit. */ 3691643ce7deSJohn Baldwin wpid = waitpid(fpid, &status, 0); 3692643ce7deSJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 369396a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3694643ce7deSJohn Baldwin 3695643ce7deSJohn Baldwin wpid = wait(&status); 369696a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 369796a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3698643ce7deSJohn Baldwin } 3699643ce7deSJohn Baldwin 3700403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 3701e012fe34SJohn Baldwin static void * 3702e0a40f30SJohn Baldwin continue_thread(void *arg __unused) 3703e012fe34SJohn Baldwin { 3704e012fe34SJohn Baldwin breakpoint(); 3705e012fe34SJohn Baldwin return (NULL); 3706e012fe34SJohn Baldwin } 3707e012fe34SJohn Baldwin 3708e012fe34SJohn Baldwin static __dead2 void 3709e012fe34SJohn Baldwin continue_thread_main(void) 3710e012fe34SJohn Baldwin { 3711e012fe34SJohn Baldwin pthread_t threads[2]; 3712e012fe34SJohn Baldwin 3713e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[0], NULL, continue_thread, 3714e012fe34SJohn Baldwin NULL) == 0); 3715e012fe34SJohn Baldwin CHILD_REQUIRE(pthread_create(&threads[1], NULL, continue_thread, 3716e012fe34SJohn Baldwin NULL) == 0); 371796a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[0], NULL), 0); 371896a9e50eSAlex Richardson CHILD_REQUIRE_EQ(pthread_join(threads[1], NULL), 0); 3719e012fe34SJohn Baldwin exit(1); 3720e012fe34SJohn Baldwin } 3721e012fe34SJohn Baldwin 3722e012fe34SJohn Baldwin /* 3723e012fe34SJohn Baldwin * Ensure that PT_CONTINUE clears the status of the thread that 3724e012fe34SJohn Baldwin * triggered the stop even if a different thread's LWP was passed to 3725e012fe34SJohn Baldwin * PT_CONTINUE. 3726e012fe34SJohn Baldwin */ 3727e012fe34SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_CONTINUE_different_thread); 3728e012fe34SJohn Baldwin ATF_TC_BODY(ptrace__PT_CONTINUE_different_thread, tc) 3729e012fe34SJohn Baldwin { 3730e012fe34SJohn Baldwin struct ptrace_lwpinfo pl; 3731e012fe34SJohn Baldwin pid_t fpid, wpid; 3732e012fe34SJohn Baldwin lwpid_t lwps[2]; 3733e012fe34SJohn Baldwin bool hit_break[2]; 3734403e331dSJohn Baldwin struct reg reg; 3735e012fe34SJohn Baldwin int i, j, status; 3736e012fe34SJohn Baldwin 3737e012fe34SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3738e012fe34SJohn Baldwin if (fpid == 0) { 3739e012fe34SJohn Baldwin trace_me(); 3740e012fe34SJohn Baldwin continue_thread_main(); 3741e012fe34SJohn Baldwin } 3742e012fe34SJohn Baldwin 3743e012fe34SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3744e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 374596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3746e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 374796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3748e012fe34SJohn Baldwin 3749e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3750e012fe34SJohn Baldwin sizeof(pl)) != -1); 3751e012fe34SJohn Baldwin 375296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_LWP_EVENTS, wpid, NULL, 1), 0); 3753e012fe34SJohn Baldwin 3754e012fe34SJohn Baldwin /* Continue the child ignoring the SIGSTOP. */ 375596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3756e012fe34SJohn Baldwin 3757e012fe34SJohn Baldwin /* One of the new threads should report it's birth. */ 3758e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 375996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3760e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 376196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3762e012fe34SJohn Baldwin 3763e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 376496a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3765e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3766e012fe34SJohn Baldwin lwps[0] = pl.pl_lwpid; 3767e012fe34SJohn Baldwin 3768e012fe34SJohn Baldwin /* 3769e012fe34SJohn Baldwin * Suspend this thread to ensure both threads are alive before 3770e012fe34SJohn Baldwin * hitting the breakpoint. 3771e012fe34SJohn Baldwin */ 3772e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_SUSPEND, lwps[0], NULL, 0) != -1); 3773e012fe34SJohn Baldwin 377496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3775e012fe34SJohn Baldwin 3776e012fe34SJohn Baldwin /* Second thread should report it's birth. */ 3777e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 377896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3779e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 378096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3781e012fe34SJohn Baldwin 3782e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 378396a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & (PL_FLAG_BORN | PL_FLAG_SCX)), 3784e012fe34SJohn Baldwin (PL_FLAG_BORN | PL_FLAG_SCX)); 3785e012fe34SJohn Baldwin ATF_REQUIRE(pl.pl_lwpid != lwps[0]); 3786e012fe34SJohn Baldwin lwps[1] = pl.pl_lwpid; 3787e012fe34SJohn Baldwin 3788e012fe34SJohn Baldwin /* Resume both threads waiting for breakpoint events. */ 3789e012fe34SJohn Baldwin hit_break[0] = hit_break[1] = false; 3790e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_RESUME, lwps[0], NULL, 0) != -1); 379196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3792e012fe34SJohn Baldwin 3793e012fe34SJohn Baldwin /* One thread should report a breakpoint. */ 3794e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 379596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3796e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 379796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3798e012fe34SJohn Baldwin 3799e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3800e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 380196a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 380296a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3803e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3804e012fe34SJohn Baldwin i = 0; 3805e012fe34SJohn Baldwin else 3806e012fe34SJohn Baldwin i = 1; 3807e012fe34SJohn Baldwin hit_break[i] = true; 3808403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3809403e331dSJohn Baldwin SKIP_BREAK(®); 3810403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 0) != -1); 3811e012fe34SJohn Baldwin 3812e012fe34SJohn Baldwin /* 3813e012fe34SJohn Baldwin * Resume both threads but pass the other thread's LWPID to 3814e012fe34SJohn Baldwin * PT_CONTINUE. 3815e012fe34SJohn Baldwin */ 381696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, lwps[i ^ 1], (caddr_t)1, 0), 0); 3817e012fe34SJohn Baldwin 3818e012fe34SJohn Baldwin /* 3819e012fe34SJohn Baldwin * Will now get two thread exit events and one more breakpoint 3820e012fe34SJohn Baldwin * event. 3821e012fe34SJohn Baldwin */ 3822e012fe34SJohn Baldwin for (j = 0; j < 3; j++) { 3823e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 382496a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3825e012fe34SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 382696a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3827e012fe34SJohn Baldwin 3828e012fe34SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, 3829e012fe34SJohn Baldwin sizeof(pl)) != -1); 3830e012fe34SJohn Baldwin 3831e012fe34SJohn Baldwin if (pl.pl_lwpid == lwps[0]) 3832e012fe34SJohn Baldwin i = 0; 3833e012fe34SJohn Baldwin else 3834e012fe34SJohn Baldwin i = 1; 3835e012fe34SJohn Baldwin 3836e012fe34SJohn Baldwin ATF_REQUIRE_MSG(lwps[i] != 0, "event for exited thread"); 3837e012fe34SJohn Baldwin if (pl.pl_flags & PL_FLAG_EXITED) { 3838e012fe34SJohn Baldwin ATF_REQUIRE_MSG(hit_break[i], 3839e012fe34SJohn Baldwin "exited thread did not report breakpoint"); 3840e012fe34SJohn Baldwin lwps[i] = 0; 3841e012fe34SJohn Baldwin } else { 3842e012fe34SJohn Baldwin ATF_REQUIRE((pl.pl_flags & PL_FLAG_SI) != 0); 384396a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGTRAP); 384496a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_code, TRAP_BRKPT); 3845e012fe34SJohn Baldwin ATF_REQUIRE_MSG(!hit_break[i], 3846e012fe34SJohn Baldwin "double breakpoint event"); 3847e012fe34SJohn Baldwin hit_break[i] = true; 3848403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_GETREGS, pl.pl_lwpid, (caddr_t)®, 3849403e331dSJohn Baldwin 0) != -1); 3850403e331dSJohn Baldwin SKIP_BREAK(®); 3851403e331dSJohn Baldwin ATF_REQUIRE(ptrace(PT_SETREGS, pl.pl_lwpid, (caddr_t)®, 3852403e331dSJohn Baldwin 0) != -1); 3853e012fe34SJohn Baldwin } 3854e012fe34SJohn Baldwin 385596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3856e012fe34SJohn Baldwin } 3857e012fe34SJohn Baldwin 3858e012fe34SJohn Baldwin /* Both threads should have exited. */ 385996a9e50eSAlex Richardson REQUIRE_EQ(lwps[0], 0); 386096a9e50eSAlex Richardson REQUIRE_EQ(lwps[1], 0); 3861e012fe34SJohn Baldwin 3862e012fe34SJohn Baldwin /* The last event should be for the child process's exit. */ 3863e012fe34SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3864e012fe34SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 386596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3866e012fe34SJohn Baldwin 3867e012fe34SJohn Baldwin wpid = wait(&status); 386896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 386996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3870e012fe34SJohn Baldwin } 3871e012fe34SJohn Baldwin #endif 3872e012fe34SJohn Baldwin 3873c5786670SJohn Baldwin /* 3874c5786670SJohn Baldwin * Verify that PT_LWPINFO doesn't return stale siginfo. 3875c5786670SJohn Baldwin */ 3876c5786670SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__PT_LWPINFO_stale_siginfo); 3877c5786670SJohn Baldwin ATF_TC_BODY(ptrace__PT_LWPINFO_stale_siginfo, tc) 3878c5786670SJohn Baldwin { 3879c5786670SJohn Baldwin struct ptrace_lwpinfo pl; 3880c5786670SJohn Baldwin pid_t fpid, wpid; 3881c5786670SJohn Baldwin int events, status; 3882c5786670SJohn Baldwin 3883c5786670SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3884c5786670SJohn Baldwin if (fpid == 0) { 3885c5786670SJohn Baldwin trace_me(); 3886c5786670SJohn Baldwin raise(SIGABRT); 3887c5786670SJohn Baldwin exit(1); 3888c5786670SJohn Baldwin } 3889c5786670SJohn Baldwin 3890c5786670SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3891c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 389296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3893c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 389496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3895c5786670SJohn Baldwin 389696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3897c5786670SJohn Baldwin 3898c5786670SJohn Baldwin /* The next stop should report the SIGABRT in the child body. */ 3899c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 390096a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3901c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 390296a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGABRT); 3903c5786670SJohn Baldwin 3904c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3905c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SI); 390696a9e50eSAlex Richardson REQUIRE_EQ(pl.pl_siginfo.si_signo, SIGABRT); 3907c5786670SJohn Baldwin 3908c5786670SJohn Baldwin /* 3909c5786670SJohn Baldwin * Continue the process ignoring the signal, but enabling 3910c5786670SJohn Baldwin * syscall traps. 3911c5786670SJohn Baldwin */ 391296a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 3913c5786670SJohn Baldwin 3914c5786670SJohn Baldwin /* 3915c5786670SJohn Baldwin * The next stop should report a system call entry from 3916c5786670SJohn Baldwin * exit(). PL_FLAGS_SI should not be set. 3917c5786670SJohn Baldwin */ 3918c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 391996a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3920c5786670SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 392196a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3922c5786670SJohn Baldwin 3923c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3924c5786670SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 392596a9e50eSAlex Richardson REQUIRE_EQ((pl.pl_flags & PL_FLAG_SI), 0); 3926c5786670SJohn Baldwin 3927c5786670SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 3928c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 3929c5786670SJohn Baldwin sizeof(events)) == 0); 3930c5786670SJohn Baldwin events &= ~PTRACE_SYSCALL; 3931c5786670SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 3932c5786670SJohn Baldwin sizeof(events)) == 0); 393396a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3934c5786670SJohn Baldwin 3935c5786670SJohn Baldwin /* The last event should be for the child process's exit. */ 3936c5786670SJohn Baldwin wpid = waitpid(fpid, &status, 0); 3937c5786670SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 393896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 3939c5786670SJohn Baldwin 3940c5786670SJohn Baldwin wpid = wait(&status); 394196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 394296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 3943c5786670SJohn Baldwin } 3944c5786670SJohn Baldwin 3945c8ea8731SJohn Baldwin /* 394632451fb9SJohn Baldwin * A simple test of PT_GET_SC_ARGS and PT_GET_SC_RET. 3947c8ea8731SJohn Baldwin */ 3948c8ea8731SJohn Baldwin ATF_TC_WITHOUT_HEAD(ptrace__syscall_args); 3949c8ea8731SJohn Baldwin ATF_TC_BODY(ptrace__syscall_args, tc) 3950c8ea8731SJohn Baldwin { 3951c8ea8731SJohn Baldwin struct ptrace_lwpinfo pl; 395232451fb9SJohn Baldwin struct ptrace_sc_ret psr; 3953c8ea8731SJohn Baldwin pid_t fpid, wpid; 3954c8ea8731SJohn Baldwin register_t args[2]; 3955c8ea8731SJohn Baldwin int events, status; 3956c8ea8731SJohn Baldwin 3957c8ea8731SJohn Baldwin ATF_REQUIRE((fpid = fork()) != -1); 3958c8ea8731SJohn Baldwin if (fpid == 0) { 3959c8ea8731SJohn Baldwin trace_me(); 3960c8ea8731SJohn Baldwin kill(getpid(), 0); 396117cc2009SAlex Richardson /* Close a fd that should not exist. */ 396217cc2009SAlex Richardson close(12345); 3963c8ea8731SJohn Baldwin exit(1); 3964c8ea8731SJohn Baldwin } 3965c8ea8731SJohn Baldwin 3966c8ea8731SJohn Baldwin /* The first wait() should report the stop from SIGSTOP. */ 3967c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 396896a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3969c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 397096a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 3971c8ea8731SJohn Baldwin 3972c8ea8731SJohn Baldwin /* 3973c8ea8731SJohn Baldwin * Continue the process ignoring the signal, but enabling 397432451fb9SJohn Baldwin * syscall traps. 3975c8ea8731SJohn Baldwin */ 397696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0), 0); 3977c8ea8731SJohn Baldwin 3978c8ea8731SJohn Baldwin /* 3979c8ea8731SJohn Baldwin * The next stop should be the syscall entry from getpid(). 3980c8ea8731SJohn Baldwin */ 3981c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 398296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 3983c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 398496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 3985c8ea8731SJohn Baldwin 3986c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 3987c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 3988*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_getpid); 3989c8ea8731SJohn Baldwin 399096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 3991c8ea8731SJohn Baldwin 3992c8ea8731SJohn Baldwin /* 399332451fb9SJohn Baldwin * The next stop should be the syscall exit from getpid(). 399432451fb9SJohn Baldwin */ 399532451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 399696a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 399732451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 399896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 399932451fb9SJohn Baldwin 400032451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 400132451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 4002*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_getpid); 400332451fb9SJohn Baldwin 400432451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 400532451fb9SJohn Baldwin sizeof(psr)) != -1); 400696a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 400796a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_retval[0], wpid); 400832451fb9SJohn Baldwin 400996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 401032451fb9SJohn Baldwin 401132451fb9SJohn Baldwin /* 4012c8ea8731SJohn Baldwin * The next stop should be the syscall entry from kill(). 4013c8ea8731SJohn Baldwin */ 4014c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 401596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 4016c8ea8731SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 401796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 4018c8ea8731SJohn Baldwin 4019c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 4020c8ea8731SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 4021*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_kill); 4022*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 2u); 4023c8ea8731SJohn Baldwin 4024c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 4025c8ea8731SJohn Baldwin sizeof(args)) != -1); 402696a9e50eSAlex Richardson REQUIRE_EQ(args[0], wpid); 402796a9e50eSAlex Richardson REQUIRE_EQ(args[1], 0); 4028c8ea8731SJohn Baldwin 402996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 403032451fb9SJohn Baldwin 403132451fb9SJohn Baldwin /* 403232451fb9SJohn Baldwin * The next stop should be the syscall exit from kill(). 403332451fb9SJohn Baldwin */ 403432451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 403596a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 403632451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 403796a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 403832451fb9SJohn Baldwin 403932451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 404032451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 4041*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_kill); 404232451fb9SJohn Baldwin 404332451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 404432451fb9SJohn Baldwin sizeof(psr)) != -1); 404596a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, 0); 404632451fb9SJohn Baldwin 404796a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 404832451fb9SJohn Baldwin 404932451fb9SJohn Baldwin /* 405032451fb9SJohn Baldwin * The next stop should be the syscall entry from close(). 405132451fb9SJohn Baldwin */ 405232451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 405396a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 405432451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 405596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 405632451fb9SJohn Baldwin 405732451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 405832451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); 4059*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_close); 4060*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_narg, 1u); 406132451fb9SJohn Baldwin 406232451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args, 406332451fb9SJohn Baldwin sizeof(args)) != -1); 406417cc2009SAlex Richardson REQUIRE_EQ(args[0], 12345); 406532451fb9SJohn Baldwin 406696a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 406732451fb9SJohn Baldwin 406832451fb9SJohn Baldwin /* 406932451fb9SJohn Baldwin * The next stop should be the syscall exit from close(). 407032451fb9SJohn Baldwin */ 407132451fb9SJohn Baldwin wpid = waitpid(fpid, &status, 0); 407296a9e50eSAlex Richardson REQUIRE_EQ(wpid, fpid); 407332451fb9SJohn Baldwin ATF_REQUIRE(WIFSTOPPED(status)); 407496a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGTRAP); 407532451fb9SJohn Baldwin 407632451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); 407732451fb9SJohn Baldwin ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); 4078*1fcbddecSAlex Richardson REQUIRE_EQ(pl.pl_syscall_code, (unsigned)SYS_close); 407932451fb9SJohn Baldwin 408032451fb9SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr, 408132451fb9SJohn Baldwin sizeof(psr)) != -1); 408296a9e50eSAlex Richardson REQUIRE_EQ(psr.sr_error, EBADF); 408332451fb9SJohn Baldwin 4084c8ea8731SJohn Baldwin /* Disable syscall tracing and continue the child to let it exit. */ 4085c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, 4086c8ea8731SJohn Baldwin sizeof(events)) == 0); 4087c8ea8731SJohn Baldwin events &= ~PTRACE_SYSCALL; 4088c8ea8731SJohn Baldwin ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, 4089c8ea8731SJohn Baldwin sizeof(events)) == 0); 409096a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0), 0); 4091c8ea8731SJohn Baldwin 4092c8ea8731SJohn Baldwin /* The last event should be for the child process's exit. */ 4093c8ea8731SJohn Baldwin wpid = waitpid(fpid, &status, 0); 4094c8ea8731SJohn Baldwin ATF_REQUIRE(WIFEXITED(status)); 409596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 1); 4096c8ea8731SJohn Baldwin 4097c8ea8731SJohn Baldwin wpid = wait(&status); 409896a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 409996a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4100c8ea8731SJohn Baldwin } 4101c8ea8731SJohn Baldwin 4102fd631bcdSMariusz Zaborski /* 4103fd631bcdSMariusz Zaborski * Verify that when the process is traced that it isn't reparent 4104fd631bcdSMariusz Zaborski * to the init process when we close all process descriptors. 4105fd631bcdSMariusz Zaborski */ 4106fd631bcdSMariusz Zaborski ATF_TC(ptrace__proc_reparent); 4107fd631bcdSMariusz Zaborski ATF_TC_HEAD(ptrace__proc_reparent, tc) 4108fd631bcdSMariusz Zaborski { 4109fd631bcdSMariusz Zaborski 4110fd631bcdSMariusz Zaborski atf_tc_set_md_var(tc, "timeout", "2"); 4111fd631bcdSMariusz Zaborski } 4112fd631bcdSMariusz Zaborski ATF_TC_BODY(ptrace__proc_reparent, tc) 4113fd631bcdSMariusz Zaborski { 4114fd631bcdSMariusz Zaborski pid_t traced, debuger, wpid; 4115fd631bcdSMariusz Zaborski int pd, status; 4116fd631bcdSMariusz Zaborski 4117fd631bcdSMariusz Zaborski traced = pdfork(&pd, 0); 4118fd631bcdSMariusz Zaborski ATF_REQUIRE(traced >= 0); 4119fd631bcdSMariusz Zaborski if (traced == 0) { 4120fd631bcdSMariusz Zaborski raise(SIGSTOP); 4121fd631bcdSMariusz Zaborski exit(0); 4122fd631bcdSMariusz Zaborski } 4123fd631bcdSMariusz Zaborski ATF_REQUIRE(pd >= 0); 4124fd631bcdSMariusz Zaborski 4125fd631bcdSMariusz Zaborski debuger = fork(); 4126fd631bcdSMariusz Zaborski ATF_REQUIRE(debuger >= 0); 4127fd631bcdSMariusz Zaborski if (debuger == 0) { 4128fd631bcdSMariusz Zaborski /* The traced process is reparented to debuger. */ 412996a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 4130fd631bcdSMariusz Zaborski wpid = waitpid(traced, &status, 0); 413196a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 4132fd631bcdSMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 413396a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 413496a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 413596a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_DETACH, traced, (caddr_t)1, 0), 0); 4136fd631bcdSMariusz Zaborski 4137fd631bcdSMariusz Zaborski /* We closed pd so we should not have any child. */ 4138fd631bcdSMariusz Zaborski wpid = wait(&status); 413996a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 414096a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4141fd631bcdSMariusz Zaborski 4142fd631bcdSMariusz Zaborski exit(0); 4143fd631bcdSMariusz Zaborski } 4144fd631bcdSMariusz Zaborski 414596a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 4146fd631bcdSMariusz Zaborski wpid = waitpid(debuger, &status, 0); 414796a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 414896a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 4149fd631bcdSMariusz Zaborski 4150fd631bcdSMariusz Zaborski /* Check if we still have any child. */ 4151fd631bcdSMariusz Zaborski wpid = wait(&status); 415296a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 415396a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 4154fd631bcdSMariusz Zaborski } 4155fd631bcdSMariusz Zaborski 41568e493611SMariusz Zaborski /* 41578e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are visible to 41588e493611SMariusz Zaborski * waitid(P_ALL). 41598e493611SMariusz Zaborski */ 41608e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_wait_child); 41618e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_wait_child, tc) 41628e493611SMariusz Zaborski { 41638e493611SMariusz Zaborski pid_t child, wpid; 41648e493611SMariusz Zaborski int pd, status; 41658e493611SMariusz Zaborski 41668e493611SMariusz Zaborski child = pdfork(&pd, 0); 41678e493611SMariusz Zaborski ATF_REQUIRE(child >= 0); 41688e493611SMariusz Zaborski 41698e493611SMariusz Zaborski if (child == 0) { 41708e493611SMariusz Zaborski trace_me(); 41718e493611SMariusz Zaborski (void)raise(SIGSTOP); 41728e493611SMariusz Zaborski exit(0); 41738e493611SMariusz Zaborski } 41748e493611SMariusz Zaborski 41758e493611SMariusz Zaborski wpid = waitpid(child, &status, 0); 417696a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 41778e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 417896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 41798e493611SMariusz Zaborski 41808e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 41818e493611SMariusz Zaborski 41828e493611SMariusz Zaborski wpid = wait(&status); 418396a9e50eSAlex Richardson REQUIRE_EQ(wpid, child); 41848e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 418596a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 41868e493611SMariusz Zaborski 41878e493611SMariusz Zaborski ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); 41888e493611SMariusz Zaborski 41898e493611SMariusz Zaborski /* 41908e493611SMariusz Zaborski * If process was created by pdfork, the return code have to 41918e493611SMariusz Zaborski * be collected through process descriptor. 41928e493611SMariusz Zaborski */ 41938e493611SMariusz Zaborski wpid = wait(&status); 419496a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 419596a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 41968e493611SMariusz Zaborski 41978e493611SMariusz Zaborski ATF_REQUIRE(close(pd) != -1); 41988e493611SMariusz Zaborski } 41998e493611SMariusz Zaborski 42008e493611SMariusz Zaborski /* 42018e493611SMariusz Zaborski * Ensure that traced processes created with pdfork(2) are not visible 42028e493611SMariusz Zaborski * after returning to parent - waitid(P_ALL). 42038e493611SMariusz Zaborski */ 42048e493611SMariusz Zaborski ATF_TC_WITHOUT_HEAD(ptrace__procdesc_reparent_wait_child); 42058e493611SMariusz Zaborski ATF_TC_BODY(ptrace__procdesc_reparent_wait_child, tc) 42068e493611SMariusz Zaborski { 42078e493611SMariusz Zaborski pid_t traced, debuger, wpid; 42088e493611SMariusz Zaborski int pd, status; 42098e493611SMariusz Zaborski 42108e493611SMariusz Zaborski traced = pdfork(&pd, 0); 42118e493611SMariusz Zaborski ATF_REQUIRE(traced >= 0); 42128e493611SMariusz Zaborski if (traced == 0) { 42138e493611SMariusz Zaborski raise(SIGSTOP); 42148e493611SMariusz Zaborski exit(0); 42158e493611SMariusz Zaborski } 42168e493611SMariusz Zaborski ATF_REQUIRE(pd >= 0); 42178e493611SMariusz Zaborski 421810321314SAlex Richardson /* Wait until the child process has stopped before fork()ing again. */ 421910321314SAlex Richardson REQUIRE_EQ(traced, waitpid(traced, &status, WSTOPPED)); 42208e493611SMariusz Zaborski debuger = fork(); 42218e493611SMariusz Zaborski ATF_REQUIRE(debuger >= 0); 42228e493611SMariusz Zaborski if (debuger == 0) { 42238e493611SMariusz Zaborski /* The traced process is reparented to debuger. */ 422496a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_ATTACH, traced, 0, 0), 0); 42258e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 422696a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42278e493611SMariusz Zaborski ATF_REQUIRE(WIFSTOPPED(status)); 422896a9e50eSAlex Richardson REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); 42298e493611SMariusz Zaborski 42308e493611SMariusz Zaborski /* Allow process to die. */ 423196a9e50eSAlex Richardson REQUIRE_EQ(ptrace(PT_CONTINUE, traced, (caddr_t)1, 0), 0); 42328e493611SMariusz Zaborski wpid = waitpid(traced, &status, 0); 423396a9e50eSAlex Richardson REQUIRE_EQ(wpid, traced); 42348e493611SMariusz Zaborski ATF_REQUIRE(WIFEXITED(status)); 423596a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 42368e493611SMariusz Zaborski 42378e493611SMariusz Zaborski /* Reparent back to the orginal process. */ 423896a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 42398e493611SMariusz Zaborski exit(0); 42408e493611SMariusz Zaborski } 42418e493611SMariusz Zaborski 42428e493611SMariusz Zaborski wpid = waitpid(debuger, &status, 0); 424396a9e50eSAlex Richardson REQUIRE_EQ(wpid, debuger); 424496a9e50eSAlex Richardson REQUIRE_EQ(WEXITSTATUS(status), 0); 42458e493611SMariusz Zaborski 42468e493611SMariusz Zaborski /* 42478e493611SMariusz Zaborski * We have a child but it has a process descriptori 42488e493611SMariusz Zaborski * so we should not be able to collect it process. 42498e493611SMariusz Zaborski */ 42508e493611SMariusz Zaborski wpid = wait(&status); 425196a9e50eSAlex Richardson REQUIRE_EQ(wpid, -1); 425296a9e50eSAlex Richardson REQUIRE_EQ(errno, ECHILD); 42538e493611SMariusz Zaborski 425496a9e50eSAlex Richardson REQUIRE_EQ(close(pd), 0); 42558e493611SMariusz Zaborski } 42568e493611SMariusz Zaborski 4257c209e3e2SJohn Baldwin ATF_TP_ADD_TCS(tp) 4258c209e3e2SJohn Baldwin { 4259c209e3e2SJohn Baldwin 4260c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); 4261c209e3e2SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); 426257c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); 426357c74f5bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); 4264128c9bc0SMark Johnston ATF_TP_ADD_TC(tp, ptrace__parent_exits_before_child); 426598685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); 426698685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); 426798685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); 426898685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); 426998685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 427098685dc8SJohn Baldwin ptrace__follow_fork_child_detached_unrelated_debugger); 427198685dc8SJohn Baldwin ATF_TP_ADD_TC(tp, 427298685dc8SJohn Baldwin ptrace__follow_fork_parent_detached_unrelated_debugger); 4273368b2b1cSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__getppid); 4274189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); 4275189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); 4276189ac973SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); 42775fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events); 42785fcfab6eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); 42793340c45bSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__siginfo); 42808d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable); 42818d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable); 42828d570f64SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__event_mask); 4283fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork); 4284fc4f075aSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__ptrace_vfork_follow); 4285403e331dSJohn Baldwin #ifdef HAVE_BREAKPOINT 428682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_breakpoint); 4287e2ebfbbfSEric Badger #endif 428882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_system_call); 428982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_threads); 429082a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_signal); 429182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_competing_stop); 429282a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_KILL_with_signal_full_sigqueue); 429382a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_system_call_entry); 429482a4538fSEric Badger ATF_TP_ADD_TC(tp, 429582a4538fSEric Badger ptrace__PT_CONTINUE_with_signal_system_call_entry_and_exit); 429682a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_full_sigqueue); 4297753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); 429882a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); 429982a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); 430082a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); 430182a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); 4302753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); 4303753e2922SBryan Drewery ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); 430482a4538fSEric Badger ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); 4305b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); 4306b38bd91fSEric Badger ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); 4307b4d33259SEric Badger ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); 4308d74da94cSMark Johnston ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); 430954cfb29eSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); 4310643ce7deSJohn Baldwin #ifdef HAVE_BREAKPOINT 4311643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo); 4312643ce7deSJohn Baldwin #endif 4313643ce7deSJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__step_siginfo); 4314403e331dSJohn Baldwin #if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK) 4315e012fe34SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_different_thread); 4316e012fe34SJohn Baldwin #endif 4317c5786670SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__PT_LWPINFO_stale_siginfo); 4318c8ea8731SJohn Baldwin ATF_TP_ADD_TC(tp, ptrace__syscall_args); 4319fd631bcdSMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__proc_reparent); 43208e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_wait_child); 43218e493611SMariusz Zaborski ATF_TP_ADD_TC(tp, ptrace__procdesc_reparent_wait_child); 4322c209e3e2SJohn Baldwin 4323c209e3e2SJohn Baldwin return (atf_no_error()); 4324c209e3e2SJohn Baldwin } 4325